diff options
author | Heejin Ahn <aheejin@gmail.com> | 2019-03-26 17:15:55 +0000 |
---|---|---|
committer | Heejin Ahn <aheejin@gmail.com> | 2019-03-26 17:15:55 +0000 |
commit | 44a5a4b10704b336700a94403103faaba6fa9729 (patch) | |
tree | ffd5f9c885827cf0c815a4c75f1e684fe99f32c0 /llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll | |
parent | 5c4fad0c2333a1400e8d731346462fe8b84a8d02 (diff) | |
download | bcm5719-llvm-44a5a4b10704b336700a94403103faaba6fa9729.tar.gz bcm5719-llvm-44a5a4b10704b336700a94403103faaba6fa9729.zip |
[WebAssembly] Fix bugs in BLOCK/TRY placement
Summary:
Before we placed all TRY/END_TRY markers before placing BLOCK/END_BLOCK
markers. This couldn't handle this case:
```
bb0:
br bb2
bb1: // nearest common dominator of bb3 and bb4
br_if ... bb3
br bb4
bb2:
...
bb3:
call @foo // unwinds to ehpad
bb4:
call @bar // unwinds to ehpad
ehpad:
catch
...
```
When we placed TRY markers, we placed it in bb1 because it is the
nearest common dominator of bb3 and bb4. But because bb0 jumps to bb2,
when we placed block markers, we ended up with interleaved scopes like
```
block
try
end_block
catch
end_try
```
which was not correct.
This patch fixes the bug by placing BLOCK and TRY markers in one pass
while iterating BBs in a function. This also adds some more routines to
`placeTryMarkers`, because we now have to assume that there can be
previously placed BLOCK and END_BLOCK.
Reviewers: dschuff
Subscribers: sunfish, sbc100, jgravelle-google, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59739
llvm-svn: 357007
Diffstat (limited to 'llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll')
-rw-r--r-- | llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll index 5b06a0baa35..f0f49344cfc 100644 --- a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll +++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 -exception-model=wasm -mattr=+exception-handling | FileCheck %s +; RUN: llc < %s -O0 -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -verify-machineinstrs -exception-model=wasm -mattr=+exception-handling | FileCheck %s --check-prefix=NOOPT target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" @@ -70,7 +71,7 @@ rethrow: ; preds = %catch.fallthrough call void @llvm.wasm.rethrow.in.catch() [ "funclet"(token %1) ] unreachable -try.cont: ; preds = %entry, %catch, %catch2 +try.cont: ; preds = %catch, %catch2, %entry ret void } @@ -173,7 +174,7 @@ rethrow5: ; preds = %catch.start3 invoke void @llvm.wasm.rethrow.in.catch() [ "funclet"(token %9) ] to label %unreachable unwind label %ehcleanup9 -try.cont: ; preds = %catch, %invoke.cont8 +try.cont: ; preds = %invoke.cont8, %catch call void @__cxa_end_catch() [ "funclet"(token %1) ] catchret from %1 to label %try.cont11 @@ -181,7 +182,7 @@ rethrow: ; preds = %catch.start call void @llvm.wasm.rethrow.in.catch() [ "funclet"(token %1) ] unreachable -try.cont11: ; preds = %entry, %try.cont +try.cont11: ; preds = %try.cont, %entry ret void ehcleanup: ; preds = %catch6 @@ -286,6 +287,54 @@ terminate: ; preds = %ehcleanup unreachable } +; Tests if block and try markers are correctly placed. Even if two predecessors +; of the EH pad are bb2 and bb3 and their nearest common dominator is bb1, the +; TRY marker should be placed at bb0 because there's a branch from bb0 to bb2, +; and scopes cannot be interleaved. + +; NOOPT-LABEL: test3 +; NOOPT: try +; NOOPT: block +; NOOPT: block +; NOOPT: block +; NOOPT: end_block +; NOOPT: end_block +; NOOPT: call foo +; NOOPT: end_block +; NOOPT: call bar +; NOOPT: catch {{.*}} +; NOOPT: end_try +define void @test3() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { +bb0: + br i1 undef, label %bb1, label %bb2 + +bb1: ; preds = %bb0 + br i1 undef, label %bb3, label %bb4 + +bb2: ; preds = %bb0 + br label %try.cont + +bb3: ; preds = %bb1 + invoke void @foo() + to label %try.cont unwind label %catch.dispatch + +bb4: ; preds = %bb1 + invoke void @bar() + to label %try.cont unwind label %catch.dispatch + +catch.dispatch: ; preds = %bb4, %bb3 + %0 = catchswitch within none [label %catch.start] unwind to caller + +catch.start: ; preds = %catch.dispatch + %1 = catchpad within %0 [i8* null] + %2 = call i8* @llvm.wasm.get.exception(token %1) + %3 = call i32 @llvm.wasm.get.ehselector(token %1) + catchret from %1 to label %try.cont + +try.cont: ; preds = %catch.start, %bb4, %bb3, %bb2 + ret void +} + declare void @foo() declare void @bar() declare i32 @__gxx_wasm_personality_v0(...) |