Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / invoke.ll
blob3bc9dd24771779bf78a727a733e71f3e817798ef
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
3 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
5 declare i32 @__gxx_personality_v0(...)
6 declare void @__cxa_call_unexpected(ptr)
7 declare void @purefn() nounwind readnone willreturn
8 declare i32 @readonly() nounwind readonly
9 declare i32 @readonly_willreturn() nounwind readonly willreturn
10 declare i32 @nounwind_fn() nounwind
11 declare i32 @fn()
14 define ptr @f1() nounwind uwtable ssp personality ptr @__gxx_personality_v0 {
15 ; CHECK-LABEL: @f1(
16 ; CHECK-NEXT:  entry:
17 ; CHECK-NEXT:    unreachable
19 entry:
20   %call = invoke noalias ptr undef()
21   to label %invoke.cont unwind label %lpad
23 invoke.cont:
24   ret ptr %call
26 lpad:
27   %0 = landingpad { ptr, i32 }
28   filter [0 x ptr] zeroinitializer
29   %1 = extractvalue { ptr, i32 } %0, 0
30   tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind
31   unreachable
34 define ptr @f2() nounwind uwtable ssp personality ptr @__gxx_personality_v0 {
35 ; CHECK-LABEL: @f2(
36 ; CHECK-NEXT:  entry:
37 ; CHECK-NEXT:    unreachable
39 entry:
40   %call = invoke noalias ptr null()
41   to label %invoke.cont unwind label %lpad
43 invoke.cont:
44   ret ptr %call
46 lpad:
47   %0 = landingpad { ptr, i32 }
48   filter [0 x ptr] zeroinitializer
49   %1 = extractvalue { ptr, i32 } %0, 0
50   tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind
51   unreachable
54 define ptr @f2_no_null_opt() nounwind uwtable ssp #0 personality ptr @__gxx_personality_v0 {
55 ; CHECK-LABEL: @f2_no_null_opt(
56 ; CHECK-NEXT:  entry:
57 ; CHECK-NEXT:    [[CALL:%.*]] = invoke noalias ptr null()
58 ; CHECK-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
59 ; CHECK:       invoke.cont:
60 ; CHECK-NEXT:    ret ptr [[CALL]]
61 ; CHECK:       lpad:
62 ; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }
63 ; CHECK-NEXT:            filter [0 x ptr] zeroinitializer
64 ; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0
65 ; CHECK-NEXT:    tail call void @__cxa_call_unexpected(ptr [[TMP1]]) #[[ATTR7:[0-9]+]]
66 ; CHECK-NEXT:    unreachable
68 entry:
69   %call = invoke noalias ptr null()
70   to label %invoke.cont unwind label %lpad
72 invoke.cont:
73   ret ptr %call
75 lpad:
76   %0 = landingpad { ptr, i32 }
77   filter [0 x ptr] zeroinitializer
78   %1 = extractvalue { ptr, i32 } %0, 0
79   tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind
80   unreachable
83 define i32 @invoke_readonly_may_not_return() nounwind personality ptr @__gxx_personality_v0 {
84 ; CHECK-LABEL: @invoke_readonly_may_not_return(
85 ; CHECK-NEXT:  entry:
86 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @readonly()
87 ; CHECK-NEXT:    ret i32 3
89 entry:
90   %call = invoke i32 @readonly()
91   to label %invoke.cont unwind label %lpad
93 invoke.cont:
94   ret i32 3
96 lpad:
97   %0 = landingpad { ptr, i32 }
98   filter [0 x ptr] zeroinitializer
99   %1 = extractvalue { ptr, i32 } %0, 0
100   tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind
101   unreachable
104 define i32 @invoke_readonly_willreturn() nounwind personality ptr @__gxx_personality_v0 {
105 ; CHECK-LABEL: @invoke_readonly_willreturn(
106 ; CHECK-NEXT:  entry:
107 ; CHECK-NEXT:    ret i32 3
109 entry:
110   %call = invoke i32 @readonly_willreturn()
111   to label %invoke.cont unwind label %lpad
113 invoke.cont:
114   ret i32 3
116 lpad:
117   %0 = landingpad { ptr, i32 }
118   filter [0 x ptr] zeroinitializer
119   %1 = extractvalue { ptr, i32 } %0, 0
120   tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind
121   unreachable
124 define i32 @invoke_readonly_willreturn_with_used_retval() nounwind personality ptr @__gxx_personality_v0 {
125 ; CHECK-LABEL: @invoke_readonly_willreturn_with_used_retval(
126 ; CHECK-NEXT:  entry:
127 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @readonly_willreturn()
128 ; CHECK-NEXT:    ret i32 [[CALL]]
130 entry:
131   %call = invoke i32 @readonly_willreturn()
132   to label %invoke.cont unwind label %lpad
134 invoke.cont:
135   ret i32 %call
137 lpad:
138   %0 = landingpad { ptr, i32 }
139   filter [0 x ptr] zeroinitializer
140   %1 = extractvalue { ptr, i32 } %0, 0
141   tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind
142   unreachable
145 define i32 @f5(i1 %cond, ptr %a, ptr %b) personality ptr @__gxx_personality_v0 {
146 ; CHECK-LABEL: @f5(
147 ; CHECK-NEXT:  entry:
148 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[X:%.*]], label [[Y:%.*]]
149 ; CHECK:       x:
150 ; CHECK-NEXT:    [[CALL:%.*]] = invoke i32 @fn()
151 ; CHECK-NEXT:            to label [[CONT:%.*]] unwind label [[LPAD:%.*]]
152 ; CHECK:       y:
153 ; CHECK-NEXT:    [[CALL2:%.*]] = call i32 @nounwind_fn()
154 ; CHECK-NEXT:    br label [[CONT]]
155 ; CHECK:       cont:
156 ; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[CALL]], [[X]] ], [ [[CALL2]], [[Y]] ]
157 ; CHECK-NEXT:    ret i32 [[PHI]]
158 ; CHECK:       lpad:
159 ; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }
160 ; CHECK-NEXT:            filter [0 x ptr] zeroinitializer
161 ; CHECK-NEXT:    tail call void @__cxa_call_unexpected(ptr [[A:%.*]]) #[[ATTR7]]
162 ; CHECK-NEXT:    unreachable
164 entry:
165   br i1 %cond, label %x, label %y
168   %call = invoke i32 @fn()
169   to label %cont unwind label %lpad
172   %call2 = invoke i32 @nounwind_fn()
173   to label %cont unwind label %lpad
175 cont:
176   %phi = phi i32 [%call, %x], [%call2, %y]
177   ret i32 %phi
179 lpad:
180   %phi2 = phi ptr [%a, %x], [%b, %y]
181   %0 = landingpad { ptr, i32 }
182   filter [0 x ptr] zeroinitializer
183   tail call void @__cxa_call_unexpected(ptr %phi2) noreturn nounwind
184   unreachable
187 define void @f6() personality ptr @__gxx_personality_v0 {
188 ; CHECK-LABEL: @f6(
189 ; CHECK-NEXT:  entry:
190 ; CHECK-NEXT:    [[FOO:%.*]] = invoke i32 @fn()
191 ; CHECK-NEXT:            to label [[COMMON_RET:%.*]] unwind label [[LPAD:%.*]]
192 ; CHECK:       common.ret:
193 ; CHECK-NEXT:    ret void
194 ; CHECK:       lpad:
195 ; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }
196 ; CHECK-NEXT:            cleanup
197 ; CHECK-NEXT:    br label [[COMMON_RET]]
199 entry:
200   invoke void @purefn()
201   to label %invoke.cont1 unwind label %lpad
203 invoke.cont1:
204   %foo = invoke i32 @fn()
205   to label %invoke.cont2 unwind label %lpad
207 invoke.cont2:
208   ret void
210 lpad:
211   %tmp = phi ptr [ null, %invoke.cont1 ], [ null, %entry ]
212   landingpad { ptr, i32 }
213   cleanup
214   ret void
217 define void @invoke_of_noreturn() personality ptr @__gxx_personality_v0 {
218 ; CHECK-LABEL: @invoke_of_noreturn(
219 ; CHECK-NEXT:  entry:
220 ; CHECK-NEXT:    invoke void @simple_throw()
221 ; CHECK-NEXT:            to label [[INVOKE_CONT_UNREACHABLE:%.*]] unwind label [[LPAD:%.*]]
222 ; CHECK:       invoke.cont.unreachable:
223 ; CHECK-NEXT:    unreachable
224 ; CHECK:       lpad:
225 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
226 ; CHECK-NEXT:            cleanup
227 ; CHECK-NEXT:    call void @sideeffect(i32 1)
228 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
230 entry:
231   invoke void @simple_throw() to label %invoke.cont unwind label %lpad
233 invoke.cont:
234   call void @sideeffect(i32 0)
235   ret void
237 lpad:
238   %eh = landingpad { ptr, i32 } cleanup
239   call void @sideeffect(i32 1)
240   resume { ptr, i32 } %eh
243 define void @invoke_of_noreturn_with_shared_normal_destination(i1 %c) personality ptr @__gxx_personality_v0 {
244 ; CHECK-LABEL: @invoke_of_noreturn_with_shared_normal_destination(
245 ; CHECK-NEXT:  entry:
246 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[INVOKE:%.*]], label [[INVOKE_CONT:%.*]]
247 ; CHECK:       invoke:
248 ; CHECK-NEXT:    invoke void @simple_throw()
249 ; CHECK-NEXT:            to label [[INVOKE_CONT_UNREACHABLE:%.*]] unwind label [[LPAD:%.*]]
250 ; CHECK:       invoke.cont.unreachable:
251 ; CHECK-NEXT:    unreachable
252 ; CHECK:       invoke.cont:
253 ; CHECK-NEXT:    call void @sideeffect(i32 -1)
254 ; CHECK-NEXT:    ret void
255 ; CHECK:       lpad:
256 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
257 ; CHECK-NEXT:            cleanup
258 ; CHECK-NEXT:    call void @sideeffect(i32 1)
259 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
261 entry:
262   br i1 %c, label %invoke, label %invoke.cont
264 invoke:
265   invoke void @simple_throw() to label %invoke.cont unwind label %lpad
267 invoke.cont:
268   %r = phi i32 [ 0, %invoke ], [ -1, %entry ]
269   call void @sideeffect(i32 %r)
270   ret void
272 lpad:
273   %eh = landingpad { ptr, i32 } cleanup
274   call void @sideeffect(i32 1)
275   resume { ptr, i32 } %eh
278 define void @invoke_of_nounwind() personality ptr @__gxx_personality_v0 {
279 ; CHECK-LABEL: @invoke_of_nounwind(
280 ; CHECK-NEXT:  entry:
281 ; CHECK-NEXT:    call void @simple_return()
282 ; CHECK-NEXT:    call void @sideeffect(i32 0)
283 ; CHECK-NEXT:    ret void
285 entry:
286   invoke void @simple_return() to label %invoke.cont unwind label %lpad
288 invoke.cont:
289   call void @sideeffect(i32 0)
290   ret void
292 lpad:
293   %eh = landingpad { ptr, i32 } cleanup
294   call void @sideeffect(i32 1)
295   resume { ptr, i32 } %eh
298 declare void @simple_throw() noreturn
299 declare void @simple_return() nounwind
300 declare void @sideeffect(i32 )
302 attributes #0 = { null_pointer_is_valid }