diff options
author | Alon Zakai <azakai@google.com> | 2023-07-26 13:35:18 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-26 13:35:18 -0700 |
commit | 2f879c0c3089e54472860a23a27985ac687d375d (patch) | |
tree | 8e63776f5b186eb2b53247eaf9e4e8ff1f3c402f /test | |
parent | 3ed34d275709acddb0e4ce7c4fa9ef7c6bb22f92 (diff) | |
download | binaryen-2f879c0c3089e54472860a23a27985ac687d375d.tar.gz binaryen-2f879c0c3089e54472860a23a27985ac687d375d.tar.bz2 binaryen-2f879c0c3089e54472860a23a27985ac687d375d.zip |
End the current basic block on a Call (#5823)
Before this PR, if a call had no paths to a catch in the same function then we skipped
creating a new basic block right after it. As a result, we could have a call in the middle
of a basic block. If EH is enabled that means we might transfer control flow out of
the function from the middle of a block. But it is better to have the property that
any transfer of control flow - to another basic block, or outside of the function - can
only happen at the end of a basic block.
This causes some overhead, but a subsequent PR (#5838) will remove that as a
followup, and this PR adds a little code to pass the module and check if EH is enabled,
and avoid the overhead if not, which at least avoids regressing the non-EH case
until that followup lands.
Diffstat (limited to 'test')
-rw-r--r-- | test/gtest/cfg.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/test/gtest/cfg.cpp b/test/gtest/cfg.cpp index 03e333965..7bf18ebdb 100644 --- a/test/gtest/cfg.cpp +++ b/test/gtest/cfg.cpp @@ -87,6 +87,51 @@ TEST_F(CFGTest, Print) { EXPECT_EQ(ss.str(), cfgText); } +TEST_F(CFGTest, CallBlock) { + // Verify that a call instruction ends the current basic block. Even if the + // call has no control flow edges inside the function (no catches it can + // reach), we still end a basic block with the call, so that we preserve the + // property of basic blocks ending in possibly-control-flow-transferring + // instructions. + auto moduleText = R"wasm( + (module + (func $foo + (drop + (i32.const 0) + ) + (call $bar) + (drop + (i32.const 1) + ) + ) + (func $bar) + ) + )wasm"; + + auto cfgText = R"cfg(;; preds: [], succs: [1] +0: + 0: i32.const 0 + 1: drop + 2: call $bar + +;; preds: [0], succs: [] +1: + 3: i32.const 1 + 4: drop + 5: block +)cfg"; + + Module wasm; + parseWast(wasm, moduleText); + + CFG cfg = CFG::fromFunction(wasm.getFunction("foo")); + + std::stringstream ss; + cfg.print(ss); + + EXPECT_EQ(ss.str(), cfgText); +} + TEST_F(CFGTest, LinearLiveness) { auto moduleText = R"wasm( (module |