xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll (revision 07b9d231ff9baa6473b0dd588a3ce5330d3e4871)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
2; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
3
4declare void @Personality()
5declare void @f()
6
7define void @test1() personality ptr @Personality {
8; CHECK-LABEL: @test1(
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    call void @f() #[[ATTR0:[0-9]+]]
11; CHECK-NEXT:    ret void
12;
13entry:
14  invoke void @f()
15  to label %exit unwind label %unreachable.unwind
16exit:
17  ret void
18unreachable.unwind:
19  cleanuppad within none []
20  unreachable
21}
22
23define void @test2() personality ptr @Personality {
24; CHECK-LABEL: @test2(
25; CHECK-NEXT:  entry:
26; CHECK-NEXT:    invoke void @f()
27; CHECK-NEXT:            to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]]
28; CHECK:       catch.pad:
29; CHECK-NEXT:    [[CS1:%.*]] = catchswitch within none [label %catch.body] unwind to caller
30; CHECK:       catch.body:
31; CHECK-NEXT:    [[CATCH:%.*]] = catchpad within [[CS1]] []
32; CHECK-NEXT:    call void @f()
33; CHECK-NEXT:    catchret from [[CATCH]] to label [[UNREACHABLE:%.*]]
34; CHECK:       exit:
35; CHECK-NEXT:    ret void
36; CHECK:       unreachable:
37; CHECK-NEXT:    unreachable
38;
39entry:
40  invoke void @f()
41  to label %exit unwind label %catch.pad
42catch.pad:
43  %cs1 = catchswitch within none [label %catch.body] unwind label %unreachable.unwind
44catch.body:
45  %catch = catchpad within %cs1 []
46  call void @f()
47  catchret from %catch to label %unreachable
48exit:
49  ret void
50unreachable.unwind:
51  cleanuppad within none []
52  unreachable
53unreachable:
54  unreachable
55}
56
57define void @test3() personality ptr @Personality {
58; CHECK-LABEL: @test3(
59; CHECK-NEXT:  entry:
60; CHECK-NEXT:    invoke void @f()
61; CHECK-NEXT:            to label [[EXIT:%.*]] unwind label [[CLEANUP_PAD:%.*]]
62; CHECK:       cleanup.pad:
63; CHECK-NEXT:    [[CLEANUP:%.*]] = cleanuppad within none []
64; CHECK-NEXT:    call void @f() #[[ATTR0]]
65; CHECK-NEXT:    unreachable
66; CHECK:       exit:
67; CHECK-NEXT:    ret void
68;
69entry:
70  invoke void @f()
71  to label %exit unwind label %cleanup.pad
72cleanup.pad:
73  %cleanup = cleanuppad within none []
74  invoke void @f()
75  to label %cleanup.ret unwind label %unreachable.unwind
76cleanup.ret:
77  ; This cleanupret should be rewritten to unreachable,
78  ; and merged into the pred block.
79  cleanupret from %cleanup unwind label %unreachable.unwind
80exit:
81  ret void
82unreachable.unwind:
83  cleanuppad within none []
84  unreachable
85}
86
87define void @test5() personality ptr @Personality {
88; CHECK-LABEL: @test5(
89; CHECK-NEXT:  entry:
90; CHECK-NEXT:    invoke void @f()
91; CHECK-NEXT:            to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]]
92; CHECK:       catch.pad:
93; CHECK-NEXT:    [[CS1:%.*]] = catchswitch within none [label %catch.body] unwind to caller
94; CHECK:       catch.body:
95; CHECK-NEXT:    [[CATCH:%.*]] = catchpad within [[CS1]] []
96; CHECK-NEXT:    catchret from [[CATCH]] to label [[EXIT]]
97; CHECK:       exit:
98; CHECK-NEXT:    unreachable
99;
100entry:
101  invoke void @f()
102  to label %exit unwind label %catch.pad
103
104catch.pad:
105  %cs1 = catchswitch within none [label %catch.body] unwind to caller
106
107catch.body:
108  %catch = catchpad within %cs1 []
109  catchret from %catch to label %exit
110
111exit:
112  unreachable
113}
114
115define void @test6() personality ptr @Personality {
116; CHECK-LABEL: @test6(
117; CHECK-NEXT:  entry:
118; CHECK-NEXT:    invoke void @f()
119; CHECK-NEXT:            to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]]
120; CHECK:       catch.pad:
121; CHECK-NEXT:    [[CS1:%.*]] = catchswitch within none [label %catch.body] unwind to caller
122; CHECK:       catch.body:
123; CHECK-NEXT:    [[CATCH:%.*]] = catchpad within [[CS1]] [ptr null, i32 0, ptr null]
124; CHECK-NEXT:    catchret from [[CATCH]] to label [[EXIT]]
125; CHECK:       exit:
126; CHECK-NEXT:    ret void
127;
128entry:
129  invoke void @f()
130  to label %exit unwind label %catch.pad
131
132catch.pad:
133  %cs1 = catchswitch within none [label %catch.body, label %catch.body] unwind to caller
134
135catch.body:
136  %catch = catchpad within %cs1 [ptr null, i32 0, ptr null]
137  catchret from %catch to label %exit
138
139exit:
140  ret void
141}
142
143define void @test7() personality ptr @Personality {
144; CHECK-LABEL: @test7(
145; CHECK-NEXT:  entry:
146; CHECK-NEXT:    invoke void @f()
147; CHECK-NEXT:            to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]]
148; CHECK:       catch.pad:
149; CHECK-NEXT:    [[CS1:%.*]] = catchswitch within none [label %catch.body] unwind to caller
150; CHECK:       catch.body:
151; CHECK-NEXT:    [[CATCH:%.*]] = catchpad within [[CS1]] [ptr null, i32 0, ptr null]
152; CHECK-NEXT:    catchret from [[CATCH]] to label [[EXIT]]
153; CHECK:       exit:
154; CHECK-NEXT:    ret void
155;
156entry:
157  invoke void @f()
158  to label %exit unwind label %catch.pad
159
160catch.pad:
161  %cs1 = catchswitch within none [label %catch.body, label %catch.body2] unwind to caller
162
163catch.body:
164  %catch = catchpad within %cs1 [ptr null, i32 0, ptr null]
165  catchret from %catch to label %exit
166
167catch.body2:
168  %catch2 = catchpad within %cs1 [ptr null, i32 0, ptr null]
169  catchret from %catch2 to label %exit
170
171exit:
172  ret void
173}
174
175define void @test8() personality ptr @Personality {
176; CHECK-LABEL: @test8(
177; CHECK-NEXT:  entry:
178; CHECK-NEXT:    invoke void @f()
179; CHECK-NEXT:            to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]]
180; CHECK:       catch.pad:
181; CHECK-NEXT:    [[CS1:%.*]] = catchswitch within none [label %catch.body] unwind to caller
182; CHECK:       catch.body:
183; CHECK-NEXT:    [[CATCH:%.*]] = catchpad within [[CS1]] [ptr null, i32 0, ptr null]
184; CHECK-NEXT:    catchret from [[CATCH]] to label [[EXIT]]
185; CHECK:       exit:
186; CHECK-NEXT:    ret void
187;
188entry:
189  invoke void @f()
190  to label %exit unwind label %catch.pad
191
192catch.pad:
193  %cs1 = catchswitch within none [label %catch.body, label %catch.body2] unwind to caller
194
195catch.body2:
196  %catch2 = catchpad within %cs1 [ptr null, i32 0, ptr null]
197  catchret from %catch2 to label %exit
198
199catch.body:
200  %catch = catchpad within %cs1 [ptr null, i32 0, ptr null]
201  catchret from %catch to label %exit
202
203exit:
204  ret void
205}
206
207define void @test9() personality ptr @Personality {
208; CHECK-LABEL: @test9(
209; CHECK-NEXT:  entry:
210; CHECK-NEXT:    invoke void @f()
211; CHECK-NEXT:            to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]]
212; CHECK:       catch.pad:
213; CHECK-NEXT:    [[CS1:%.*]] = catchswitch within none [label [[CATCH_BODY:%.*]], label %catch.body2] unwind to caller
214; CHECK:       catch.body:
215; CHECK-NEXT:    [[CATCH:%.*]] = catchpad within [[CS1]] [ptr null, i32 0, ptr null]
216; CHECK-NEXT:    catchret from [[CATCH]] to label [[EXIT]]
217; CHECK:       catch.body2:
218; CHECK-NEXT:    [[CATCH2:%.*]] = catchpad within [[CS1]] [ptr null, i32 64, ptr null]
219; CHECK-NEXT:    catchret from [[CATCH2]] to label [[EXIT]]
220; CHECK:       exit:
221; CHECK-NEXT:    ret void
222;
223entry:
224  invoke void @f()
225  to label %exit unwind label %catch.pad
226
227catch.pad:
228  %cs1 = catchswitch within none [label %catch.body, label %catch.body2] unwind to caller
229
230catch.body:
231  %catch = catchpad within %cs1 [ptr null, i32 0, ptr null]
232  catchret from %catch to label %exit
233
234catch.body2:
235  %catch2 = catchpad within %cs1 [ptr null, i32 64, ptr null]
236  catchret from %catch2 to label %exit
237
238exit:
239  ret void
240}
241;.
242; CHECK: attributes #[[ATTR0]] = { nounwind }
243;.
244