[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / LICM / scalar-promote-unwind.ll
blobf7829c4d6e4d9742db0dd7930a25923aadc01825
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=licm -S | FileCheck %s
3 ; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<target-ir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
5 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6 target triple = "x86_64-unknown-linux-gnu"
8 ; Make sure we don't hoist the store out of the loop; %a would
9 ; have the wrong value if f() unwinds
10 define void @test1(ptr nocapture noalias %a, i1 zeroext %y) uwtable {
11 ; CHECK-LABEL: @test1(
12 ; CHECK-NEXT:  entry:
13 ; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 4
14 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
15 ; CHECK:       for.body:
16 ; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ]
17 ; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ]
18 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1
19 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[A]], align 4
20 ; CHECK-NEXT:    br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]]
21 ; CHECK:       if.then:
22 ; CHECK-NEXT:    tail call void @f()
23 ; CHECK-NEXT:    br label [[FOR_INC]]
24 ; CHECK:       for.inc:
25 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 1
26 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000
27 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
28 ; CHECK:       for.cond.cleanup:
29 ; CHECK-NEXT:    ret void
31 entry:
32   br label %for.body
34 for.body:
35   %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
36   %0 = load i32, ptr %a, align 4
37   %add = add nsw i32 %0, 1
38   store i32 %add, ptr %a, align 4
39   br i1 %y, label %if.then, label %for.inc
42 if.then:
43   tail call void @f()
44   br label %for.inc
46 for.inc:
47   %inc = add nuw nsw i32 %i.03, 1
48   %exitcond = icmp eq i32 %inc, 10000
49   br i1 %exitcond, label %for.cond.cleanup, label %for.body
51 for.cond.cleanup:
52   ret void
55 ; We can hoist the store out of the loop here; if f() unwinds,
56 ; the lifetime of %a ends.
57 define void @test_alloca(i1 zeroext %y) uwtable {
58 ; CHECK-LABEL: @test_alloca(
59 ; CHECK-NEXT:  entry:
60 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
61 ; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A]], align 4
62 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
63 ; CHECK:       for.body:
64 ; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ]
65 ; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ]
66 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1
67 ; CHECK-NEXT:    br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]]
68 ; CHECK:       if.then:
69 ; CHECK-NEXT:    tail call void @f()
70 ; CHECK-NEXT:    br label [[FOR_INC]]
71 ; CHECK:       for.inc:
72 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 1
73 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000
74 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
75 ; CHECK:       for.cond.cleanup:
76 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INC]] ]
77 ; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A]], align 4
78 ; CHECK-NEXT:    ret void
80 entry:
81   %a = alloca i32
82   br label %for.body
84 for.body:
85   %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
86   %0 = load i32, ptr %a, align 4
87   %add = add nsw i32 %0, 1
88   store i32 %add, ptr %a, align 4
89   br i1 %y, label %if.then, label %for.inc
91 if.then:
92   tail call void @f()
93   br label %for.inc
95 for.inc:
96   %inc = add nuw nsw i32 %i.03, 1
97   %exitcond = icmp eq i32 %inc, 10000
98   br i1 %exitcond, label %for.cond.cleanup, label %for.body
100 for.cond.cleanup:
101   ret void
104 ; byval memory cannot be accessed on unwind either.
105 define void @test_byval(ptr byval(i32) %a, i1 zeroext %y) uwtable {
106 ; CHECK-LABEL: @test_byval(
107 ; CHECK-NEXT:  entry:
108 ; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 4
109 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
110 ; CHECK:       for.body:
111 ; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ]
112 ; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ]
113 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1
114 ; CHECK-NEXT:    br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]]
115 ; CHECK:       if.then:
116 ; CHECK-NEXT:    tail call void @f()
117 ; CHECK-NEXT:    br label [[FOR_INC]]
118 ; CHECK:       for.inc:
119 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 1
120 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000
121 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
122 ; CHECK:       for.cond.cleanup:
123 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INC]] ]
124 ; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A]], align 4
125 ; CHECK-NEXT:    ret void
127 entry:
128   br label %for.body
130 for.body:
131   %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
132   %0 = load i32, ptr %a, align 4
133   %add = add nsw i32 %0, 1
134   store i32 %add, ptr %a, align 4
135   br i1 %y, label %if.then, label %for.inc
137 if.then:
138   tail call void @f()
139   br label %for.inc
141 for.inc:
142   %inc = add nuw nsw i32 %i.03, 1
143   %exitcond = icmp eq i32 %inc, 10000
144   br i1 %exitcond, label %for.cond.cleanup, label %for.body
146 for.cond.cleanup:
147   ret void
150 define void @test_dead_on_unwind(ptr noalias dead_on_unwind %a, i1 zeroext %y) uwtable {
151 ; CHECK-LABEL: @test_dead_on_unwind(
152 ; CHECK-NEXT:  entry:
153 ; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 4
154 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
155 ; CHECK:       for.body:
156 ; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ]
157 ; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ]
158 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1
159 ; CHECK-NEXT:    br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]]
160 ; CHECK:       if.then:
161 ; CHECK-NEXT:    tail call void @f()
162 ; CHECK-NEXT:    br label [[FOR_INC]]
163 ; CHECK:       for.inc:
164 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 1
165 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000
166 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
167 ; CHECK:       for.cond.cleanup:
168 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INC]] ]
169 ; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A]], align 4
170 ; CHECK-NEXT:    ret void
172 entry:
173   br label %for.body
175 for.body:
176   %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
177   %0 = load i32, ptr %a, align 4
178   %add = add nsw i32 %0, 1
179   store i32 %add, ptr %a, align 4
180   br i1 %y, label %if.then, label %for.inc
182 if.then:
183   tail call void @f()
184   br label %for.inc
186 for.inc:
187   %inc = add nuw nsw i32 %i.03, 1
188   %exitcond = icmp eq i32 %inc, 10000
189   br i1 %exitcond, label %for.cond.cleanup, label %for.body
191 for.cond.cleanup:
192   ret void
195 ;; We can promote if the load can be proven safe to speculate, and the
196 ;; store safe to sink, even if the the store *isn't* must execute.
197 define void @test3(i1 zeroext %y) uwtable {
198 ; CHECK-LABEL: @test3(
199 ; CHECK-NEXT:  entry:
200 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
201 ; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A]], align 4
202 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
203 ; CHECK:       for.body:
204 ; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
205 ; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
206 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1
207 ; CHECK-NEXT:    tail call void @f()
208 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 1
209 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000
210 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
211 ; CHECK:       for.cond.cleanup:
212 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
213 ; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A]], align 4
214 ; CHECK-NEXT:    ret void
216 entry:
217   %a = alloca i32
218   br label %for.body
220 for.body:
221   %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
222   %0 = load i32, ptr %a, align 4
223   %add = add nsw i32 %0, 1
224   tail call void @f()
225   store i32 %add, ptr %a, align 4
226   %inc = add nuw nsw i32 %i.03, 1
227   %exitcond = icmp eq i32 %inc, 10000
228   br i1 %exitcond, label %for.cond.cleanup, label %for.body
230 for.cond.cleanup:
231   ret void
234 ;; Same as test3, but with unordered atomics
235 define void @test3b(i1 zeroext %y) uwtable {
236 ; CHECK-LABEL: @test3b(
237 ; CHECK-NEXT:  entry:
238 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
239 ; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load atomic i32, ptr [[A]] unordered, align 4
240 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
241 ; CHECK:       for.body:
242 ; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
243 ; CHECK-NEXT:    [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
244 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1
245 ; CHECK-NEXT:    tail call void @f()
246 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_03]], 1
247 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000
248 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
249 ; CHECK:       for.cond.cleanup:
250 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
251 ; CHECK-NEXT:    store atomic i32 [[ADD_LCSSA]], ptr [[A]] unordered, align 4
252 ; CHECK-NEXT:    ret void
254 entry:
255   %a = alloca i32
256   br label %for.body
258 for.body:
259   %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
260   %0 = load atomic i32, ptr %a unordered, align 4
261   %add = add nsw i32 %0, 1
262   tail call void @f()
263   store atomic i32 %add, ptr %a unordered, align 4
264   %inc = add nuw nsw i32 %i.03, 1
265   %exitcond = icmp eq i32 %inc, 10000
266   br i1 %exitcond, label %for.cond.cleanup, label %for.body
268 for.cond.cleanup:
269   ret void
272 @_ZTIi = external constant ptr
274 ; In this test, the loop is within a try block. There is an explicit unwind edge out of the loop.
275 ; Make sure this edge is treated as a loop exit, and that the loads and stores are promoted as
276 ; expected
277 define void @loop_within_tryblock() personality ptr @__gxx_personality_v0 {
278 ; CHECK-LABEL: @loop_within_tryblock(
279 ; CHECK-NEXT:  entry:
280 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
281 ; CHECK-NEXT:    store i32 0, ptr [[A]], align 4
282 ; CHECK-NEXT:    [[A_PROMOTED:%.*]] = load i32, ptr [[A]], align 4
283 ; CHECK-NEXT:    br label [[FOR_COND:%.*]]
284 ; CHECK:       for.cond:
285 ; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ]
286 ; CHECK-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ]
287 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_0]], 1024
288 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
289 ; CHECK:       for.body:
290 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1
291 ; CHECK-NEXT:    invoke void @boo()
292 ; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
293 ; CHECK:       invoke.cont:
294 ; CHECK-NEXT:    br label [[FOR_INC]]
295 ; CHECK:       for.inc:
296 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_0]], 1
297 ; CHECK-NEXT:    br label [[FOR_COND]]
298 ; CHECK:       lpad:
299 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ]
300 ; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }
301 ; CHECK-NEXT:    catch ptr @_ZTIi
302 ; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A]], align 4
303 ; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0
304 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1
305 ; CHECK-NEXT:    br label [[CATCH_DISPATCH:%.*]]
306 ; CHECK:       catch.dispatch:
307 ; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
308 ; CHECK-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]
309 ; CHECK-NEXT:    br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
310 ; CHECK:       catch:
311 ; CHECK-NEXT:    [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[TMP1]])
312 ; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
313 ; CHECK-NEXT:    call void @__cxa_end_catch()
314 ; CHECK-NEXT:    br label [[TRY_CONT:%.*]]
315 ; CHECK:       try.cont:
316 ; CHECK-NEXT:    ret void
317 ; CHECK:       for.end:
318 ; CHECK-NEXT:    [[ADD1_LCSSA:%.*]] = phi i32 [ [[ADD1]], [[FOR_COND]] ]
319 ; CHECK-NEXT:    store i32 [[ADD1_LCSSA]], ptr [[A]], align 4
320 ; CHECK-NEXT:    br label [[TRY_CONT]]
321 ; CHECK:       eh.resume:
322 ; CHECK-NEXT:    [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } undef, ptr [[TMP1]], 0
323 ; CHECK-NEXT:    [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[TMP2]], 1
324 ; CHECK-NEXT:    resume { ptr, i32 } [[LPAD_VAL3]]
326 entry:
327   %a = alloca i32, align 4
328   store i32 0, ptr %a, align 4
329   br label %for.cond
331 for.cond:
332   %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
333   %cmp = icmp slt i32 %i.0, 1024
334   br i1 %cmp, label %for.body, label %for.end
336 for.body:
337   %0 = load i32, ptr %a, align 4
338   %add = add nsw i32 %0, 1
339   store i32 %add, ptr %a, align 4
340   invoke void @boo()
341   to label %invoke.cont unwind label %lpad
343 invoke.cont:
344   br label %for.inc
346 for.inc:
347   %inc = add nsw i32 %i.0, 1
348   br label %for.cond
350 lpad:
351   %1 = landingpad { ptr, i32 }
352   catch ptr @_ZTIi
353   %2 = extractvalue { ptr, i32 } %1, 0
354   %3 = extractvalue { ptr, i32 } %1, 1
355   br label %catch.dispatch
357 catch.dispatch:
358   %4 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #3
359   %matches = icmp eq i32 %3, %4
360   br i1 %matches, label %catch, label %eh.resume
362 catch:
363   %5 = call ptr @__cxa_begin_catch(ptr %2) #3
364   %6 = load i32, ptr %5, align 4
365   call void @__cxa_end_catch() #3
366   br label %try.cont
368 try.cont:
369   ret void
371 for.end:
372   br label %try.cont
374 eh.resume:
375   %lpad.val = insertvalue { ptr, i32 } undef, ptr %2, 0
376   %lpad.val3 = insertvalue { ptr, i32 } %lpad.val, i32 %3, 1
377   resume { ptr, i32 } %lpad.val3
381 ; The malloc'ed memory is not capture and therefore promoted.
382 define void @malloc_no_capture() #0 personality ptr @__gxx_personality_v0 {
383 ; CHECK-LABEL: @malloc_no_capture(
384 ; CHECK-NEXT:  entry:
385 ; CHECK-NEXT:    [[CALL:%.*]] = call ptr @malloc(i64 4)
386 ; CHECK-NEXT:    [[CALL_PROMOTED:%.*]] = load i32, ptr [[CALL]], align 4
387 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
388 ; CHECK:       for.body:
389 ; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[CALL_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_LATCH:%.*]] ]
390 ; CHECK-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_LATCH]] ]
391 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1
392 ; CHECK-NEXT:    br label [[FOR_CALL:%.*]]
393 ; CHECK:       for.call:
394 ; CHECK-NEXT:    invoke void @boo()
395 ; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
396 ; CHECK:       invoke.cont:
397 ; CHECK-NEXT:    br label [[FOR_LATCH]]
398 ; CHECK:       for.latch:
399 ; CHECK-NEXT:    [[INC]] = add i32 [[I_0]], 1
400 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_0]], 1024
401 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
402 ; CHECK:       for.end:
403 ; CHECK-NEXT:    [[ADD_LCSSA2:%.*]] = phi i32 [ [[ADD]], [[FOR_LATCH]] ]
404 ; CHECK-NEXT:    store i32 [[ADD_LCSSA2]], ptr [[CALL]], align 4
405 ; CHECK-NEXT:    br label [[FUN_RET:%.*]]
406 ; CHECK:       lpad:
407 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_CALL]] ]
408 ; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }
409 ; CHECK-NEXT:    catch ptr null
410 ; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[CALL]], align 4
411 ; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0
412 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1
413 ; CHECK-NEXT:    br label [[CATCH:%.*]]
414 ; CHECK:       catch:
415 ; CHECK-NEXT:    [[TMP3:%.*]] = call ptr @__cxa_begin_catch(ptr [[TMP1]])
416 ; CHECK-NEXT:    call void @free(ptr [[CALL]])
417 ; CHECK-NEXT:    call void @__cxa_end_catch()
418 ; CHECK-NEXT:    br label [[FUN_RET]]
419 ; CHECK:       fun.ret:
420 ; CHECK-NEXT:    ret void
422 entry:
423   %call = call ptr @malloc(i64 4)
424   br label %for.body
426 for.body:
427   %i.0 = phi i32 [ 0, %entry  ], [ %inc, %for.latch ]
428   %0 = load i32, ptr %call, align 4
429   %add = add nsw i32 %0, 1
430   store i32 %add, ptr %call, align 4
431   br label %for.call
433 for.call:
434   invoke void @boo()
435   to label %invoke.cont unwind label %lpad
437 invoke.cont:
438   br label %for.latch
440 for.latch:
441   %inc = add i32 %i.0, 1
442   %cmp = icmp slt i32 %i.0, 1024
443   br i1 %cmp, label %for.body, label %for.end
445 for.end:
446   br label %fun.ret
448 lpad:
449   %1 = landingpad { ptr, i32 }
450   catch ptr null
451   %2 = extractvalue { ptr, i32 } %1, 0
452   %3 = extractvalue { ptr, i32 } %1, 1
453   br label %catch
455 catch:
456   %4 = call ptr @__cxa_begin_catch(ptr %2) #4
457   call void @free(ptr %call)
458   call void @__cxa_end_catch()
459   br label %fun.ret
461 fun.ret:
462   ret void
465 ; The malloc'ed memory can be captured and therefore only loads can be promoted.
466 define void @malloc_capture(ptr noalias %A) personality ptr @__gxx_personality_v0 {
467 ; CHECK-LABEL: @malloc_capture(
468 ; CHECK-NEXT:  entry:
469 ; CHECK-NEXT:    [[CALL:%.*]] = call ptr @malloc(i64 4)
470 ; CHECK-NEXT:    [[CALL_PROMOTED:%.*]] = load i32, ptr [[CALL]], align 4
471 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
472 ; CHECK:       for.body:
473 ; CHECK-NEXT:    [[ADD1:%.*]] = phi i32 [ [[CALL_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_LATCH:%.*]] ]
474 ; CHECK-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_LATCH]] ]
475 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[ADD1]], 1
476 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[CALL]], align 4
477 ; CHECK-NEXT:    br label [[FOR_CALL:%.*]]
478 ; CHECK:       for.call:
479 ; CHECK-NEXT:    invoke void @boo_readnone()
480 ; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
481 ; CHECK:       invoke.cont:
482 ; CHECK-NEXT:    br label [[FOR_LATCH]]
483 ; CHECK:       for.latch:
484 ; CHECK-NEXT:    store ptr [[CALL]], ptr [[A:%.*]], align 8
485 ; CHECK-NEXT:    [[INC]] = add i32 [[I_0]], 1
486 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_0]], 1024
487 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
488 ; CHECK:       for.end:
489 ; CHECK-NEXT:    br label [[FUN_RET:%.*]]
490 ; CHECK:       lpad:
491 ; CHECK-NEXT:    [[TMP0:%.*]] = landingpad { ptr, i32 }
492 ; CHECK-NEXT:    catch ptr null
493 ; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0
494 ; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1
495 ; CHECK-NEXT:    br label [[CATCH:%.*]]
496 ; CHECK:       catch:
497 ; CHECK-NEXT:    [[TMP3:%.*]] = call ptr @__cxa_begin_catch(ptr [[TMP1]])
498 ; CHECK-NEXT:    call void @free(ptr [[CALL]])
499 ; CHECK-NEXT:    call void @__cxa_end_catch()
500 ; CHECK-NEXT:    br label [[FUN_RET]]
501 ; CHECK:       fun.ret:
502 ; CHECK-NEXT:    ret void
504 entry:
505   %call = call ptr @malloc(i64 4)
506   br label %for.body
508 for.body:
509   %i.0 = phi i32 [ 0, %entry  ], [ %inc, %for.latch ]
510   %0 = load i32, ptr %call, align 4
511   %add = add nsw i32 %0, 1
512   store i32 %add, ptr %call, align 4
513   br label %for.call
515 for.call:
516   invoke void @boo_readnone()
517   to label %invoke.cont unwind label %lpad
519 invoke.cont:
520   br label %for.latch
522 for.latch:
523   store ptr %call, ptr %A
524   %inc = add i32 %i.0, 1
525   %cmp = icmp slt i32 %i.0, 1024
526   br i1 %cmp, label %for.body, label %for.end
528 for.end:
529   br label %fun.ret
531 lpad:
532   %1 = landingpad { ptr, i32 }
533   catch ptr null
534   %2 = extractvalue { ptr, i32 } %1, 0
535   %3 = extractvalue { ptr, i32 } %1, 1
536   br label %catch
538 catch:
539   %4 = call ptr @__cxa_begin_catch(ptr %2) #4
540   call void @free(ptr %call)
541   call void @__cxa_end_catch()
542   br label %fun.ret
544 fun.ret:
545   ret void
548 ; Function Attrs: nounwind
549 declare noalias ptr @malloc(i64)
551 ; Function Attrs: nounwind
552 declare void @free(ptr nocapture)
554 declare void @boo()
556 ; This is an artifical example, readnone functions by definition cannot unwind
557 ; exceptions by calling the C++ exception throwing methods
558 ; This function should only be used to test malloc_capture.
559 declare void @boo_readnone() readnone
561 declare i32 @__gxx_personality_v0(...)
563 declare ptr @__cxa_begin_catch(ptr)
565 declare void @__cxa_end_catch()
567 declare i32 @llvm.eh.typeid.for.p0(ptr)
569 declare void @f() uwtable