summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2019-03-26 17:15:55 +0000
committerHeejin Ahn <aheejin@gmail.com>2019-03-26 17:15:55 +0000
commit44a5a4b10704b336700a94403103faaba6fa9729 (patch)
treeffd5f9c885827cf0c815a4c75f1e684fe99f32c0 /llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll
parent5c4fad0c2333a1400e8d731346462fe8b84a8d02 (diff)
downloadbcm5719-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.ll55
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(...)
OpenPOWER on IntegriCloud