From 81f410fae40f1874539c73e91456df8e516e315a Mon Sep 17 00:00:00 2001 From: clonker <1685266+clonker@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:13:00 +0100 Subject: [PATCH] SSACFG liveness: add conditional jump values to live set --- libyul/backends/evm/SSACFGLiveness.cpp | 22 +++++- .../standard_yul_cfg_json_export/output.json | 70 +++++++++++++------ .../strict_asm_yul_cfg_json_export/output | 15 ++-- test/cmdlineTests/yul_cfg_json_export/output | 70 +++++++++++++------ .../libyul/yulSSAControlFlowGraph/complex.yul | 14 ++-- .../yulSSAControlFlowGraph/complex2.yul | 14 ++-- .../yulSSAControlFlowGraph/nested_for.yul | 10 +-- .../nested_function.yul | 4 +- test/libyul/yulSSAControlFlowGraph/switch.yul | 4 +- 9 files changed, 146 insertions(+), 77 deletions(-) diff --git a/libyul/backends/evm/SSACFGLiveness.cpp b/libyul/backends/evm/SSACFGLiveness.cpp index 4537c8c5d8fc..6ecd559ca806 100644 --- a/libyul/backends/evm/SSACFGLiveness.cpp +++ b/libyul/backends/evm/SSACFGLiveness.cpp @@ -18,6 +18,8 @@ #include +#include + #include #include #include @@ -87,9 +89,23 @@ void SSACFGLiveness::runDagDfs() if (!m_topologicalSort.backEdge(blockId, _successor)) live += m_liveIns[_successor.value] - m_cfg.block(_successor).phis; }); - if (std::holds_alternative(block.exit)) - live += std::get(block.exit).returnValues - | ranges::views::filter(literalsFilter(m_cfg)); + util::GenericVisitor exitVisitor { + [](SSACFG::BasicBlock::MainExit const&) {}, + [&](SSACFG::BasicBlock::FunctionReturn const& _functionReturn) { + live += _functionReturn.returnValues | ranges::views::filter(literalsFilter(m_cfg)); + }, + [&](SSACFG::BasicBlock::JumpTable const& _jt) { + if (literalsFilter(m_cfg)(_jt.value)) + live.emplace(_jt.value); + }, + [](SSACFG::BasicBlock::Jump const&) {}, + [&](SSACFG::BasicBlock::ConditionalJump const& _conditionalJump) { + if (literalsFilter(m_cfg)(_conditionalJump.condition)) + live.emplace(_conditionalJump.condition); + }, + [](SSACFG::BasicBlock::Terminated const&) {} + }; + std::visit(exitVisitor, block.exit); // clean out unreachables live = live | ranges::views::filter([&](auto const& valueId) { return !std::holds_alternative(m_cfg.valueInfo(valueId)); }) | ranges::to; diff --git a/test/cmdlineTests/standard_yul_cfg_json_export/output.json b/test/cmdlineTests/standard_yul_cfg_json_export/output.json index fc47f4f7b937..bb13b3e91503 100644 --- a/test/cmdlineTests/standard_yul_cfg_json_export/output.json +++ b/test/cmdlineTests/standard_yul_cfg_json_export/output.json @@ -45,7 +45,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -188,7 +189,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -260,7 +262,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -303,7 +306,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -361,7 +365,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" @@ -492,7 +497,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -635,7 +641,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -707,7 +714,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -750,7 +758,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -808,7 +817,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" @@ -903,7 +913,8 @@ "out": [ "v0", "v18", - "v24" + "v24", + "v28" ] }, "type": "BuiltinCall" @@ -997,7 +1008,8 @@ "v24" ], "out": [ - "v41" + "v41", + "v42" ] }, "type": "BuiltinCall" @@ -1153,7 +1165,9 @@ "v41" ], "out": [ - "v46" + "v46", + "v59", + "v60" ] }, "type": "BuiltinCall" @@ -1224,10 +1238,12 @@ "instructions": [], "liveness": { "in": [ - "v46" + "v46", + "v59" ], "out": [ - "v46" + "v46", + "v59" ] } }, @@ -1372,7 +1388,8 @@ "v46" ], "out": [ - "v46" + "v46", + "v67" ] }, "type": "BuiltinCall" @@ -1480,7 +1497,8 @@ "out": [ "v46", "v71", - "v77" + "v77", + "v80" ] }, "type": "BuiltinCall" @@ -1570,7 +1588,8 @@ "v77" ], "out": [ - "v46" + "v46", + "v90" ] }, "type": "BuiltinCall" @@ -1718,7 +1737,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -1861,7 +1881,8 @@ "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -1933,7 +1954,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -1976,7 +1998,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -2034,7 +2057,8 @@ "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" diff --git a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output index ac154fc16246..a65c164d631d 100644 --- a/test/cmdlineTests/strict_asm_yul_cfg_json_export/output +++ b/test/cmdlineTests/strict_asm_yul_cfg_json_export/output @@ -45,7 +45,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -188,7 +189,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -260,7 +262,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -303,7 +306,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -361,7 +365,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" diff --git a/test/cmdlineTests/yul_cfg_json_export/output b/test/cmdlineTests/yul_cfg_json_export/output index 6848d7db9ddb..f6f2ec6d8f42 100644 --- a/test/cmdlineTests/yul_cfg_json_export/output +++ b/test/cmdlineTests/yul_cfg_json_export/output @@ -44,7 +44,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -187,7 +188,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -259,7 +261,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -302,7 +305,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -360,7 +364,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" @@ -492,7 +497,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -635,7 +641,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -707,7 +714,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -750,7 +758,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -808,7 +817,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" @@ -903,7 +913,8 @@ Yul Control Flow Graph: "out": [ "v0", "v18", - "v24" + "v24", + "v28" ] }, "type": "BuiltinCall" @@ -997,7 +1008,8 @@ Yul Control Flow Graph: "v24" ], "out": [ - "v41" + "v41", + "v42" ] }, "type": "BuiltinCall" @@ -1153,7 +1165,9 @@ Yul Control Flow Graph: "v41" ], "out": [ - "v46" + "v46", + "v59", + "v60" ] }, "type": "BuiltinCall" @@ -1224,10 +1238,12 @@ Yul Control Flow Graph: "instructions": [], "liveness": { "in": [ - "v46" + "v46", + "v59" ], "out": [ - "v46" + "v46", + "v59" ] } }, @@ -1372,7 +1388,8 @@ Yul Control Flow Graph: "v46" ], "out": [ - "v46" + "v46", + "v67" ] }, "type": "BuiltinCall" @@ -1480,7 +1497,8 @@ Yul Control Flow Graph: "out": [ "v46", "v71", - "v77" + "v77", + "v80" ] }, "type": "BuiltinCall" @@ -1570,7 +1588,8 @@ Yul Control Flow Graph: "v77" ], "out": [ - "v46" + "v46", + "v90" ] }, "type": "BuiltinCall" @@ -1718,7 +1737,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v2" ] }, "type": "BuiltinCall" @@ -1861,7 +1881,8 @@ Yul Control Flow Graph: "liveness": { "in": [], "out": [ - "v0" + "v0", + "v5" ] }, "type": "BuiltinCall" @@ -1933,7 +1954,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v11" ] }, "type": "BuiltinCall" @@ -1976,7 +1998,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v12" ] }, "type": "BuiltinCall" @@ -2034,7 +2057,8 @@ Yul Control Flow Graph: "v0" ], "out": [ - "v0" + "v0", + "v17" ] }, "type": "BuiltinCall" diff --git a/test/libyul/yulSSAControlFlowGraph/complex.yul b/test/libyul/yulSSAControlFlowGraph/complex.yul index 6fb0453c186b..3f7f329a48d5 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex.yul @@ -69,7 +69,7 @@ // Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ // Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ +// LiveOut: v0,v1,v5,v6\l\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ // )\l\ @@ -81,7 +81,7 @@ // Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ // Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ +// LiveOut: v0,v1,v5,v7,v8\l\nv7 := mload(v5)\l\ // v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; @@ -103,7 +103,7 @@ // Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ // Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ +// LiveOut: v0,v1,v5,v7,v13\l\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; // Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -117,7 +117,7 @@ // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ // Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ +// LiveOut: v0,v1,v5,v7,v20\l\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; // Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -132,7 +132,7 @@ // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ // Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ +// LiveOut: v0,v1,v5,v25\l\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; // Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -147,7 +147,7 @@ // Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ // Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ +// LiveOut: v0,v1,v5,v29\l\nv29 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; // Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -175,7 +175,7 @@ // Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ // Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ +// LiveOut: v0,v1,v43,v44\l\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; diff --git a/test/libyul/yulSSAControlFlowGraph/complex2.yul b/test/libyul/yulSSAControlFlowGraph/complex2.yul index c3ea8b94f8aa..6d801124cda3 100644 --- a/test/libyul/yulSSAControlFlowGraph/complex2.yul +++ b/test/libyul/yulSSAControlFlowGraph/complex2.yul @@ -85,7 +85,7 @@ // Block1_0Exit -> Block1_1 [style="solid"]; // Block1_1 [label="\ // Block 1; (1, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv5 := φ(\l\ +// LiveOut: v0,v1,v5,v6\l\nv5 := φ(\l\ // Block 0 => 42,\l\ // Block 21 => v43\l\ // )\l\ @@ -97,7 +97,7 @@ // Block1_1Exit:1 -> Block1_2 [style="solid"]; // Block1_2 [label="\ // Block 2; (2, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5,v7\l\nv7 := mload(v5)\l\ +// LiveOut: v0,v1,v5,v7,v8\l\nv7 := mload(v5)\l\ // v8 := eq(0, v7)\l\ // "]; // Block1_2 -> Block1_2Exit; @@ -119,7 +119,7 @@ // Block1_6Exit -> Block1_4 [style="solid"]; // Block1_7 [label="\ // Block 7; (5, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv13 := eq(1, v7)\l\ +// LiveOut: v0,v1,v5,v7,v13\l\nv13 := eq(1, v7)\l\ // "]; // Block1_7 -> Block1_7Exit; // Block1_7Exit [label="{ If v13 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -133,7 +133,7 @@ // Block1_9 -> Block1_9Exit; // Block1_10 [label="\ // Block 10; (7, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5,v7\l\nv20 := eq(2, v7)\l\ +// LiveOut: v0,v1,v5,v7,v20\l\nv20 := eq(2, v7)\l\ // "]; // Block1_10 -> Block1_10Exit; // Block1_10Exit [label="{ If v20 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -148,7 +148,7 @@ // Block1_12 -> Block1_12Exit; // Block1_13 [label="\ // Block 13; (9, max 17)\nLiveIn: v0,v1,v5,v7\l\ -// LiveOut: v0,v1,v5\l\nv25 := eq(3, v7)\l\ +// LiveOut: v0,v1,v5,v25\l\nv25 := eq(3, v7)\l\ // "]; // Block1_13 -> Block1_13Exit; // Block1_13Exit [label="{ If v25 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -163,7 +163,7 @@ // Block1_15Exit -> Block1_5 [style="solid"]; // Block1_16 [label="\ // Block 16; (15, max 17)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v5\l\nv29 := mload(v1)\l\ +// LiveOut: v0,v1,v5,v29\l\nv29 := mload(v1)\l\ // "]; // Block1_16 -> Block1_16Exit; // Block1_16Exit [label="{ If v29 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -191,7 +191,7 @@ // Block1_18Exit -> Block1_5 [style="solid"]; // Block1_3 [label="\ // Block 3; (12, max 14)\nLiveIn: v0,v1,v5\l\ -// LiveOut: v0,v1,v43\l\nv43 := add(1, v5)\l\ +// LiveOut: v0,v1,v43,v44\l\nv43 := add(1, v5)\l\ // v44 := calldataload(v43)\l\ // "]; // Block1_3 -> Block1_3Exit; diff --git a/test/libyul/yulSSAControlFlowGraph/nested_for.yul b/test/libyul/yulSSAControlFlowGraph/nested_for.yul index b088e3b55ed8..f816df462b91 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_for.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_for.yul @@ -33,7 +33,7 @@ // Block0_0Exit -> Block0_1 [style="solid"]; // Block0_1 [label="\ // Block 1; (1, max 24)\nLiveIn: v2\l\ -// LiveOut: v2\l\nv2 := φ(\l\ +// LiveOut: v2,v3\l\nv2 := φ(\l\ // Block 0 => 0,\l\ // Block 3 => v36\l\ // )\l\ @@ -56,7 +56,7 @@ // Block0_4 -> Block0_4Exit; // Block0_5 [label="\ // Block 5; (3, max 23)\nLiveIn: v2,v4\l\ -// LiveOut: v2,v4\l\nv4 := φ(\l\ +// LiveOut: v2,v4,v5\l\nv4 := φ(\l\ // Block 2 => 0,\l\ // Block 7 => v35\l\ // )\l\ @@ -80,7 +80,7 @@ // Block0_8Exit -> Block0_3 [style="solid"]; // Block0_9 [label="\ // Block 9; (5, max 21)\nLiveIn: v2,v4,v6\l\ -// LiveOut: v2,v4,v6\l\nv6 := φ(\l\ +// LiveOut: v2,v4,v6,v7\l\nv6 := φ(\l\ // Block 6 => 0,\l\ // Block 11 => v31\l\ // )\l\ @@ -132,7 +132,7 @@ // Block0_7Exit -> Block0_5 [style="dashed"]; // Block0_15 [label="\ // Block 15; (8, max 19)\nLiveIn: v2,v4,v6,v8\l\ -// LiveOut: v2,v4,v6,v8\l\nv8 := φ(\l\ +// LiveOut: v2,v4,v6,v8,v9\l\nv8 := φ(\l\ // Block 13 => 0,\l\ // Block 17 => v16\l\ // )\l\ @@ -171,7 +171,7 @@ // Block0_18Exit -> Block0_14 [style="solid"]; // Block0_21 [label="\ // Block 21; (14, max 19)\nLiveIn: v2,v4,v6,v19\l\ -// LiveOut: v2,v4,v6,v19\l\nv19 := φ(\l\ +// LiveOut: v2,v4,v6,v19,v20\l\nv19 := φ(\l\ // Block 19 => 0,\l\ // Block 23 => v26\l\ // )\l\ diff --git a/test/libyul/yulSSAControlFlowGraph/nested_function.yul b/test/libyul/yulSSAControlFlowGraph/nested_function.yul index acda15ce81a5..1263d4782db8 100644 --- a/test/libyul/yulSSAControlFlowGraph/nested_function.yul +++ b/test/libyul/yulSSAControlFlowGraph/nested_function.yul @@ -103,7 +103,7 @@ // FunctionEntry_cycle1_0 -> Block7_0; // Block7_0 [label="\ // Block 0; (0, max 2)\nLiveIn: \l\ -// LiveOut: \l\nv2 := mload(3)\l\ +// LiveOut: v2\l\nv2 := mload(3)\l\ // "]; // Block7_0 -> Block7_0Exit; // Block7_0Exit [label="{ If v2 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; @@ -130,7 +130,7 @@ // FunctionEntry_cycle2_0 -> Block8_0; // Block8_0 [label="\ // Block 0; (0, max 2)\nLiveIn: \l\ -// LiveOut: \l\nv2 := mload(4)\l\ +// LiveOut: v2\l\nv2 := mload(4)\l\ // "]; // Block8_0 -> Block8_0Exit; // Block8_0Exit [label="{ If v2 | { <0> Zero | <1> NonZero }}" shape=Mrecord]; diff --git a/test/libyul/yulSSAControlFlowGraph/switch.yul b/test/libyul/yulSSAControlFlowGraph/switch.yul index 10573b012298..91b3daeeeded 100644 --- a/test/libyul/yulSSAControlFlowGraph/switch.yul +++ b/test/libyul/yulSSAControlFlowGraph/switch.yul @@ -23,7 +23,7 @@ // Entry0 -> Block0_0; // Block0_0 [label="\ // Block 0; (0, max 5)\nLiveIn: \l\ -// LiveOut: v3\l\nv1 := calldataload(3)\l\ +// LiveOut: v3,v4\l\nv1 := calldataload(3)\l\ // v3 := sload(0)\l\ // v4 := eq(0, v3)\l\ // "]; @@ -40,7 +40,7 @@ // Block0_2Exit -> Block0_1 [style="solid"]; // Block0_3 [label="\ // Block 3; (3, max 5)\nLiveIn: v3\l\ -// LiveOut: \l\nv7 := eq(1, v3)\l\ +// LiveOut: v7\l\nv7 := eq(1, v3)\l\ // "]; // Block0_3 -> Block0_3Exit; // Block0_3Exit [label="{ If v7 | { <0> Zero | <1> NonZero }}" shape=Mrecord];