diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll --- a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll +++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh.ll @@ -12,6 +12,9 @@ @_ZTIi = external constant i8* @_ZTId = external constant i8* +%class.Object = type { i8 } +%class.MyClass = type { i32 } + ; Simple test case with two catch clauses ; ; void foo(); @@ -28,19 +31,19 @@ ; CHECK: call foo ; CHECK: catch ; CHECK: block -; CHECK: br_if 0, {{.*}} # 0: down to label2 +; CHECK: br_if 0, {{.*}} # 0: down to label[[L0:[0-9]+]] ; CHECK: call $drop=, __cxa_begin_catch ; CHECK: call __cxa_end_catch -; CHECK: br 1 # 1: down to label0 -; CHECK: end_block # label2: +; CHECK: br 1 # 1: down to label[[L1:[0-9]+]] +; CHECK: end_block # label[[L0]]: ; CHECK: block -; CHECK: br_if 0, {{.*}} # 0: down to label3 +; CHECK: br_if 0, {{.*}} # 0: down to label[[L2:[0-9]+]] ; CHECK: call $drop=, __cxa_begin_catch ; CHECK: call __cxa_end_catch -; CHECK: br 1 # 1: down to label0 -; CHECK: end_block # label3: +; CHECK: br 1 # 1: down to label[[L1]] +; CHECK: end_block # label[[L2]]: ; CHECK: rethrow {{.*}} # to caller -; CHECK: end_try # label0: +; CHECK: end_try # label[[L1]]: define void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { entry: invoke void @foo() @@ -99,35 +102,35 @@ ; CHECK: catch ; CHECK: block ; CHECK: block -; CHECK: br_if 0, {{.*}} # 0: down to label7 +; CHECK: br_if 0, {{.*}} # 0: down to label[[L0:[0-9]+]] ; CHECK: call $drop=, __cxa_begin_catch ; CHECK: try ; CHECK: call foo -; CHECK: br 2 # 2: down to label6 +; CHECK: br 2 # 2: down to label[[L1:[0-9]+]] ; CHECK: catch ; CHECK: try ; CHECK: block -; CHECK: br_if 0, {{.*}} # 0: down to label11 +; CHECK: br_if 0, {{.*}} # 0: down to label[[L2:[0-9]+]] ; CHECK: call $drop=, __cxa_begin_catch ; CHECK: try ; CHECK: call foo -; CHECK: br 2 # 2: down to label9 +; CHECK: br 2 # 2: down to label[[L3:[0-9]+]] ; CHECK: catch ; CHECK: call __cxa_end_catch -; CHECK: rethrow {{.*}} # down to catch3 +; CHECK: rethrow {{.*}} # down to catch[[C0:[0-9]+]] ; CHECK: end_try -; CHECK: end_block # label11: -; CHECK: rethrow {{.*}} # down to catch3 -; CHECK: catch {{.*}} # catch3: +; CHECK: end_block # label[[L2]]: +; CHECK: rethrow {{.*}} # down to catch[[C0]] +; CHECK: catch {{.*}} # catch[[C0]]: ; CHECK: call __cxa_end_catch ; CHECK: rethrow {{.*}} # to caller -; CHECK: end_try # label9: +; CHECK: end_try # label[[L3]]: ; CHECK: call __cxa_end_catch -; CHECK: br 2 # 2: down to label6 +; CHECK: br 2 # 2: down to label[[L1]] ; CHECK: end_try -; CHECK: end_block # label7: +; CHECK: end_block # label[[L0]]: ; CHECK: rethrow {{.*}} # to caller -; CHECK: end_block # label6: +; CHECK: end_block # label[[L1]]: ; CHECK: call __cxa_end_catch ; CHECK: end_try define void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { @@ -219,13 +222,13 @@ ; CHECK: call foo ; CHECK: catch ; CHECK: call $drop=, __cxa_begin_catch -; CHECK: loop # label15: +; CHECK: loop # label[[L0:[0-9]+]]: ; CHECK: block ; CHECK: block -; CHECK: br_if 0, {{.*}} # 0: down to label17 +; CHECK: br_if 0, {{.*}} # 0: down to label[[L1:[0-9]+]] ; CHECK: try ; CHECK: call foo -; CHECK: br 2 # 2: down to label16 +; CHECK: br 2 # 2: down to label[[L2:[0-9]+]] ; CHECK: catch ; CHECK: try ; CHECK: call __cxa_end_catch @@ -235,13 +238,13 @@ ; CHECK: end_try ; CHECK: rethrow {{.*}} # to caller ; CHECK: end_try -; CHECK: end_block # label17: +; CHECK: end_block # label[[L1]]: ; CHECK: call __cxa_end_catch -; CHECK: br 2 # 2: down to label13 -; CHECK: end_block # label16: -; CHECK: br 0 # 0: up to label15 +; CHECK: br 2 # 2: down to label[[L3:[0-9]+]] +; CHECK: end_block # label[[L2]]: +; CHECK: br 0 # 0: up to label[[L0]] ; CHECK: end_loop -; CHECK: end_try # label13: +; CHECK: end_try # label[[L3]]: define void @test2() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { entry: invoke void @foo() @@ -377,10 +380,10 @@ ; destination mismatches. And we use -wasm-disable-ehpad-sort to create maximum ; number of mismatches in several tests below. -; 'call bar''s original unwind destination was 'catch14', but after control flow -; linearization, its unwind destination incorrectly becomes 'catch15'. We fix -; this by wrapping the call with a nested try/catch/end_try and branching to the -; right destination (label32). +; 'call bar''s original unwind destination was 'C1', but after control flow +; linearization, its unwind destination incorrectly becomes 'C0'. We fix this by +; wrapping the call with a nested try/catch/end_try and branching to the right +; destination (L0). ; NOSORT-LABEL: test5 ; NOSORT: block @@ -391,16 +394,16 @@ ; NOSORT: try ; NOSORT: call bar ; NOSORT: catch $drop= -; NOSORT: br 2 # 2: down to label32 +; NOSORT: br 2 # 2: down to label[[L0:[0-9]+]] ; NOSORT: end_try ; --- Nested try/catch/end_try ends -; NOSORT: br 2 # 2: down to label31 -; NOSORT: catch $drop= # catch15: -; NOSORT: br 2 # 2: down to label31 +; NOSORT: br 2 # 2: down to label[[L1:[0-9]+]] +; NOSORT: catch $drop= # catch[[C0:[0-9]+]]: +; NOSORT: br 2 # 2: down to label[[L1]] ; NOSORT: end_try -; NOSORT: catch $drop= # catch14: -; NOSORT: end_try # label32: -; NOSORT: end_block # label31: +; NOSORT: catch $drop= # catch[[C1:[0-9]+]]: +; NOSORT: end_try # label[[L0]]: +; NOSORT: end_block # label[[L1]]: ; NOSORT: return define void @test5() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { @@ -435,10 +438,9 @@ } ; Two 'call bar''s original unwind destination was the caller, but after control -; flow linearization, their unwind destination incorrectly becomes 'catch17'. We -; fix this by wrapping the call with a nested try/catch/end_try and branching to -; the right destination (label4), from which we rethrow the exception to the -; caller. +; flow linearization, their unwind destination incorrectly becomes 'C0'. We fix +; this by wrapping the call with a nested try/catch/end_try and branching to the +; right destination (L0), from which we rethrow the exception to the caller. ; And the return value of 'baz' should NOT be stackified because the BB is split ; during fixing unwind mismatches. @@ -452,13 +454,13 @@ ; NOSORT: call ${{[0-9]+}}=, baz ; NOSORT-NOT: call $push{{.*}}=, baz ; NOSORT: catch $[[REG:[0-9]+]]= -; NOSORT: br 1 # 1: down to label35 +; NOSORT: br 1 # 1: down to label[[L0:[0-9]+]] ; NOSORT: end_try ; --- Nested try/catch/end_try ends ; NOSORT: return -; NOSORT: catch $drop= # catch17: +; NOSORT: catch $drop= # catch[[C0:[0-9]+]]: ; NOSORT: return -; NOSORT: end_try # label35: +; NOSORT: end_try # label[[L0]]: ; NOSORT: rethrow $[[REG]] # to caller define void @test6() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { @@ -487,9 +489,9 @@ ; Similar situation as @test6. Here 'call @qux''s original unwind destination ; was the caller, but after control flow linearization, their unwind destination -; incorrectly becomes another catch within the function. We fix this by wrapping -; the call with a nested try/catch/end_try and branching to the right -; destination, from which we rethrow the exception to the caller. +; incorrectly becomes 'C0' within the function. We fix this by wrapping the call +; with a nested try/catch/end_try and branching to the right destination, from +; which we rethrow the exception to the caller. ; Because 'call @qux' pops an argument pushed by 'i32.const 5' from stack, the ; nested 'try' should be placed before `i32.const 5', not between 'i32.const 5' @@ -503,13 +505,13 @@ ; NOSORT-NEXT: i32.const $push{{[0-9]+}}=, 5 ; NOSORT-NEXT: call ${{[0-9]+}}=, qux ; NOSORT: catch $[[REG:[0-9]+]]= -; NOSORT: br 1 # 1: down to label37 +; NOSORT: br 1 # 1: down to label[[L0:[0-9]+]] ; NOSORT: end_try ; --- Nested try/catch/end_try ends ; NOSORT: return -; NOSORT: catch $drop= # catch19: +; NOSORT: catch $drop= # catch[[C0:[0-9]+]]: ; NOSORT: return -; NOSORT: end_try # label37: +; NOSORT: end_try # label[[L0]]: ; NOSORT: rethrow $[[REG]] # to caller define i32 @test7() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { @@ -578,12 +580,12 @@ ; i32 signature. But because we add a rethrow instruction at the end of the ; appendix block, now the LOOP marker does not have a signature (= has a void ; signature). Here the two calls two 'bar' are supposed to throw up to the -; caller, but incorrectly unwind to 'catch19' after linearizing the CFG. +; caller, but incorrectly unwind to 'C0' after linearizing the CFG. ; NOSORT-LABEL: test9 ; NOSORT: block ; NOSORT-NOT: loop i32 -; NOSORT: loop # label42: +; NOSORT: loop # label[[L0:[0-9]+]]: ; NOSORT: try ; NOSORT: call foo ; --- Nested try/catch/end_try starts @@ -591,13 +593,13 @@ ; NOSORT: call bar ; NOSORT: call bar ; NOSORT: catch $[[REG:[0-9]+]]= -; NOSORT: br 1 # 1: down to label43 +; NOSORT: br 1 # 1: down to label[[L1:[0-9]+]] ; NOSORT: end_try ; --- Nested try/catch/end_try ends ; NOSORT: return {{.*}} -; NOSORT: catch $drop= # catch23: -; NOSORT: br 1 # 1: up to label42 -; NOSORT: end_try # label43: +; NOSORT: catch $drop= # catch[[C0:[0-9]+]]: +; NOSORT: br 1 # 1: up to label[[L0]] +; NOSORT: end_try # label[[L1]]: ; NOSORT: end_loop ; NOSORT: end_block ; NOSORT: rethrow $[[REG]] # to caller @@ -646,38 +648,38 @@ ; NOSORT: try ; NOSORT: call bar ; NOSORT: catch $[[REG0:[0-9]+]]= -; NOSORT: br 2 # 2: down to label47 +; NOSORT: br 2 # 2: down to label[[L0:[0-9]+]] ; NOSORT: end_try ; --- Nested try/catch/end_try ends -; NOSORT: br 2 # 2: down to label46 +; NOSORT: br 2 # 2: down to label[[L1:[0-9]+]] ; NOSORT: catch {{.*}} ; NOSORT: block i32 -; NOSORT: br_on_exn 0, {{.*}} # 0: down to label50 +; NOSORT: br_on_exn 0, {{.*}} # 0: down to label[[L2:[0-9]+]] ; --- Nested try/catch/end_try starts ; NOSORT: try -; NOSORT: rethrow {{.*}} # down to catch28 -; NOSORT: catch $[[REG1:[0-9]+]]= # catch28: -; NOSORT: br 5 # 5: down to label45 +; NOSORT: rethrow {{.*}} # down to catch[[C0:[0-9]+]] +; NOSORT: catch $[[REG1:[0-9]+]]= # catch[[C0]]: +; NOSORT: br 5 # 5: down to label[[L3:[0-9]+]] ; NOSORT: end_try ; --- Nested try/catch/end_try ends -; NOSORT: end_block # label50: +; NOSORT: end_block # label[[L2]]: ; NOSORT: call $drop=, __cxa_begin_catch ; --- Nested try/catch/end_try starts ; NOSORT: try ; NOSORT: call __cxa_end_catch ; NOSORT: catch $[[REG1]]= -; NOSORT: br 4 # 4: down to label45 +; NOSORT: br 4 # 4: down to label[[L3]] ; NOSORT: end_try ; --- Nested try/catch/end_try ends -; NOSORT: br 2 # 2: down to label46 +; NOSORT: br 2 # 2: down to label[[L1]] ; NOSORT: end_try ; NOSORT: catch $[[REG0]]= -; NOSORT: end_try # label47: +; NOSORT: end_try # label[[L0]]: ; NOSORT: call $drop=, __cxa_begin_catch ; NOSORT: call __cxa_end_catch -; NOSORT: end_block # label46: +; NOSORT: end_block # label[[L1]]: ; NOSORT: return -; NOSORT: end_block # label45: +; NOSORT: end_block # label[[L3]]: ; NOSORT: rethrow $[[REG1]] # to caller define void @test10() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { bb0: @@ -757,8 +759,6 @@ ret void } -%class.Object = type { i8 } - ; Intrinsics like memcpy, memmove, and memset don't throw and are lowered into ; calls to external symbols (not global addresses) in instruction selection, ; which will be eventually lowered to library function calls. @@ -820,8 +820,6 @@ unreachable } -%class.MyClass = type { i32 } - ; This crashed on debug mode (= when NDEBUG is not defined) when the logic for ; computing the innermost region was not correct, in which a loop region ; contains an exception region. This should pass CFGSort without crashing.