1# RUN: llc -mtriple=wasm32-unknown-unknown -exception-model=wasm -mattr=+exception-handling -run-pass wasm-cfg-stackify %s -o - | FileCheck %s
2
3--- |
4  target triple = "wasm32-unknown-unknown"
5
6  declare i32 @__gxx_wasm_personality_v0(...)
7  declare void @foo()
8  define void @rethrow_arg_test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
9    ret void
10  }
11  define i32 @fix_end_function_test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
12    ret i32 0
13  }
14...
15
16---
17# CHECK-LABEL: name: rethrow_arg_test
18name: rethrow_arg_test
19liveins:
20  - { reg: '$arguments' }
21body: |
22  bb.0:
23    successors: %bb.1, %bb.3
24    ; CHECK: bb.0:
25    ; CHECK: TRY
26    EH_LABEL <mcsymbol .Ltmp0>
27    CALL @foo, implicit-def dead $arguments, implicit $sp32, implicit $sp64
28    EH_LABEL <mcsymbol .Ltmp1>
29    BR %bb.3, implicit-def dead $arguments
30
31  bb.1 (landing-pad):
32    successors: %bb.2
33    ; CHECK: bb.1 (landing-pad):
34    ; CHECK: CATCH
35    ; CHECK: TRY
36    ; This RETHROW rethrows the exception caught by this BB's CATCH, but after
37    ; CFGStackify a TRY is placed between the CATCH and this RETHROW, so after
38    ; CFGStackify its immediate argument should become not 0, but 1.
39    ; CHECK: RETHROW 1
40    EH_LABEL <mcsymbol .Ltmp2>
41    %0:i32 = CATCH &__cpp_exception, implicit-def dead $arguments
42    RETHROW 0, implicit-def dead $arguments
43
44  bb.2 (landing-pad):
45    ; CHECK: bb.2 (landing-pad):
46    ; CHECK: CATCH
47    ; CHECK: RETHROW 0
48    EH_LABEL <mcsymbol .Ltmp3>
49    %1:i32 = CATCH &__cpp_exception, implicit-def dead $arguments
50    RETHROW 0, implicit-def dead $arguments
51
52  bb.3:
53    ; CHECK: bb.3:
54    ; CHECK: END_TRY
55    ; CHECK: END_TRY
56    RETURN implicit-def dead $arguments
57...
58
59---
60# This function has i32 return type and the end of the function is unreachable,
61# so CFGStackify's fixEndsAtEndOfFunction() propagates the return type while
62# they encounter 'end' or 'delegate'. This is a regression test for a bug that
63# we only handled 'end' but not 'delegate'.
64# CHECK-LABEL: name: fix_end_function_test
65name: fix_end_function_test
66liveins:
67  - { reg: '$arguments' }
68machineFunctionInfo:
69  params:          [  ]
70  results:         [ i32 ]
71  wasmEHFuncInfo:
72    3:               4
73body: |
74  ; CHECK: TRY 127
75  ; CHECK:   TRY 127
76  ; CHECK:     CALL @foo
77  ; CHECK:     TRY 64
78  ; CHECK:       CALL @foo
79  ; CHECK:     DELEGATE
80  ; CHECK:     RETURN
81  ; CHECK:   CATCH
82  ;; This TRY should have the return type i32 (127)
83  ; CHECK:     TRY 127
84  ; CHECK:       RETHROW
85  ; CHECK:     DELEGATE
86  ; CHECK:   END_TRY
87  ; CHECK: CATCH
88  ; CHECK:   RETHROW
89  ; CHECK: END_TRY
90  bb.0:
91    successors: %bb.1, %bb.3
92    EH_LABEL <mcsymbol .Ltmp0>
93    CALL @foo, implicit-def dead $arguments, implicit $sp32, implicit $sp64
94    EH_LABEL <mcsymbol .Ltmp1>
95
96  bb.1:
97    successors: %bb.2, %bb.4
98    EH_LABEL <mcsymbol .Ltmp2>
99    CALL @foo, implicit-def dead $arguments, implicit $sp32, implicit $sp64
100    EH_LABEL <mcsymbol .Ltmp3>
101
102  bb.2:
103    %0:i32 = CONST_I32 3, implicit-def dead $arguments
104    RETURN %0:i32, implicit-def dead $arguments
105
106  bb.3 (landing-pad):
107    EH_LABEL <mcsymbol .Ltmp4>
108    %0:i32 = CATCH &__cpp_exception, implicit-def dead $arguments
109    RETHROW 0, implicit-def dead $arguments
110
111  bb.4 (landing-pad):
112    EH_LABEL <mcsymbol .Ltmp5>
113    %1:i32 = CATCH &__cpp_exception, implicit-def dead $arguments
114    RETHROW 0, implicit-def dead $arguments
115...
116