1# RUN: llc -mtriple=wasm32-unknown-unknown -exception-model=wasm -mattr=+exception-handling -run-pass wasm-late-eh-prepare -run-pass wasm-cfg-stackify %s -o - | FileCheck %s
2
3--- |
4  target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5  target triple = "wasm32-unknown-unknown"
6
7  declare i32 @__gxx_wasm_personality_v0(...)
8  declare void @foo()
9  define void @eh_label_test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
10    ret void
11  }
12  define void @unreachable_ehpad_test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
13    ret void
14  }
15  define void @rethrow_arg_test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
16    ret void
17  }
18...
19
20---
21# This tests 'try' and 'catch' instructions are correctly placed with respect to
22# EH_LABEL instructions.
23# CHECK-LABEL: name: eh_label_test
24name: eh_label_test
25liveins:
26  - { reg: '$arguments' }
27body: |
28  bb.0:
29    ; TRY should be before EH_LABEL wrappers of throwing calls
30    ; CHECK:      bb.0
31    ; CHECK:      TRY
32    ; CHECK-NEXT: EH_LABEL
33    ; CHECK-NEXT: CALL @foo
34    ; CHECK-NEXT: EH_LABEL
35    successors: %bb.1, %bb.2
36    EH_LABEL <mcsymbol .Ltmp0>
37    CALL @foo, implicit-def dead $arguments, implicit $sp32, implicit $sp64
38    EH_LABEL <mcsymbol .Ltmp1>
39    BR %bb.2, implicit-def dead $arguments
40
41  bb.1 (landing-pad):
42  ; predecessors: %bb.0
43    successors: %bb.2
44    ; CATCH_ALL should be after an EH_LABEL at the beginning of an EH pad
45    ; CHECK:      bb.1
46    ; CHECK:      EH_LABEL
47    ; CHECK-NEXT: CATCH_ALL
48    EH_LABEL <mcsymbol .Ltmp2>
49    CATCHRET %bb.2, %bb.1, implicit-def dead $arguments
50
51  bb.2:
52  ; predecessors: %bb.0, %bb.1
53    RETURN implicit-def dead $arguments
54...
55
56---
57# Unreachable EH pads should be removed by LateEHPrepare.
58# CHECK-LABEL: name: unreachable_ehpad_test
59name: unreachable_ehpad_test
60liveins:
61  - { reg: '$arguments' }
62body: |
63  ; CHECK: bb.0
64  bb.0:
65    successors: %bb.2
66    BR %bb.2, implicit-def dead $arguments
67
68  ; This EH pad is unreachable, so it should be removed by LateEHPrepare
69  ; CHECK-NOT: bb.1 (landing-pad)
70  bb.1 (landing-pad):
71    successors: %bb.2
72    EH_LABEL <mcsymbol .Ltmp2>
73    CATCHRET %bb.2, %bb.1, implicit-def dead $arguments
74
75  ; CHECK: bb.2
76  bb.2:
77  ; predecessors: %bb.0, %bb.1
78    RETURN implicit-def dead $arguments
79...
80
81---
82# CHECK-LABEL: name: rethrow_arg_test
83name: rethrow_arg_test
84liveins:
85  - { reg: '$arguments' }
86body: |
87  bb.0:
88    successors: %bb.1, %bb.4
89    ; CHECK: bb.0
90    ; CHECK: TRY
91    EH_LABEL <mcsymbol .Ltmp0>
92    CALL @foo, implicit-def dead $arguments, implicit $sp32, implicit $sp64
93    EH_LABEL <mcsymbol .Ltmp1>
94    BR %bb.4, implicit-def dead $arguments
95
96  bb.1 (landing-pad):
97  ; predecessors: %bb.0
98    successors: %bb.2
99    ; CHECK: bb.1
100    ; CHECK: CATCH
101    ; CHECK: TRY
102    ; This RETHROW rethrows the exception caught by this BB's CATCH, but after
103    ; CFGStackify a TRY is placed between the CATCH and this RETHROW, so after
104    ; CFGStackify its immediate argument should become not 0, but 1.
105    ; CHECK: RETHROW 1
106    EH_LABEL <mcsymbol .Ltmp2>
107    %0:i32 = CATCH &__cpp_exception, implicit-def dead $arguments
108    RETHROW 0, implicit-def dead $arguments
109
110  bb.2 (landing-pad):
111  ; predecessors: %bb.1
112    successors: %bb.3
113    ; CHECK: bb.2
114    ; CHECK: CATCH
115    ; CHECK: RETHROW 0
116    EH_LABEL <mcsymbol .Ltmp5>
117    %1:i32 = CATCH &__cpp_exception, implicit-def dead $arguments
118    RETHROW 0, implicit-def dead $arguments
119    CATCHRET %bb.3, %bb.2, implicit-def dead $arguments
120
121  bb.3:
122  ; predecessors: %bb.2
123    successors: %bb.4
124    CATCHRET %bb.4, %bb.1, implicit-def dead $arguments
125
126  bb.4:
127  ; predecessors: %bb.0, %bb.3
128    ; CHECK: bb.4
129    ; CHECK: END_TRY
130    ; CHECK: END_TRY
131    RETURN implicit-def dead $arguments
132
133