@_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();
; 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()
; 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*) {
; 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
; 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()
; 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
; 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*) {
}
; 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.
; 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*) {
; 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'
; 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*) {
; 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
; 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
; 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:
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.
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.