xref: /llvm-project/llvm/test/Transforms/LICM/scalar-promote-unwind.ll (revision 10edb4991c12738e60843d55cd9edbf6d702d9eb)
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
4
5target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6target triple = "x86_64-unknown-linux-gnu"
7
8; Make sure we don't hoist the store out of the loop; %a would
9; have the wrong value if f() unwinds
10define 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
30;
31entry:
32  br label %for.body
33
34for.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
40
41
42if.then:
43  tail call void @f()
44  br label %for.inc
45
46for.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
50
51for.cond.cleanup:
52  ret void
53}
54
55; We can hoist the store out of the loop here; if f() unwinds,
56; the lifetime of %a ends.
57define 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
79;
80entry:
81  %a = alloca i32
82  br label %for.body
83
84for.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
90
91if.then:
92  tail call void @f()
93  br label %for.inc
94
95for.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
99
100for.cond.cleanup:
101  ret void
102}
103
104; byval memory cannot be accessed on unwind either.
105define 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
126;
127entry:
128  br label %for.body
129
130for.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
136
137if.then:
138  tail call void @f()
139  br label %for.inc
140
141for.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
145
146for.cond.cleanup:
147  ret void
148}
149
150define 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
171;
172entry:
173  br label %for.body
174
175for.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
181
182if.then:
183  tail call void @f()
184  br label %for.inc
185
186for.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
190
191for.cond.cleanup:
192  ret void
193}
194
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.
197define 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
215;
216entry:
217  %a = alloca i32
218  br label %for.body
219
220for.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
229
230for.cond.cleanup:
231  ret void
232}
233
234;; Same as test3, but with unordered atomics
235define 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
253;
254entry:
255  %a = alloca i32
256  br label %for.body
257
258for.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
267
268for.cond.cleanup:
269  ret void
270}
271
272@_ZTIi = external constant ptr
273
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
277define 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]]
325;
326entry:
327  %a = alloca i32, align 4
328  store i32 0, ptr %a, align 4
329  br label %for.cond
330
331for.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
335
336for.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
342
343invoke.cont:
344  br label %for.inc
345
346for.inc:
347  %inc = add nsw i32 %i.0, 1
348  br label %for.cond
349
350lpad:
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
356
357catch.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
361
362catch:
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
367
368try.cont:
369  ret void
370
371for.end:
372  br label %try.cont
373
374eh.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
378}
379
380
381; The malloc'ed memory is not capture and therefore promoted.
382define 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
421;
422entry:
423  %call = call ptr @malloc(i64 4)
424  br label %for.body
425
426for.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
432
433for.call:
434  invoke void @boo()
435  to label %invoke.cont unwind label %lpad
436
437invoke.cont:
438  br label %for.latch
439
440for.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
444
445for.end:
446  br label %fun.ret
447
448lpad:
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
454
455catch:
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
460
461fun.ret:
462  ret void
463}
464
465; The malloc'ed memory can be captured and therefore only loads can be promoted.
466define 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
503;
504entry:
505  %call = call ptr @malloc(i64 4)
506  br label %for.body
507
508for.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
514
515for.call:
516  invoke void @boo_readnone()
517  to label %invoke.cont unwind label %lpad
518
519invoke.cont:
520  br label %for.latch
521
522for.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
527
528for.end:
529  br label %fun.ret
530
531lpad:
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
537
538catch:
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
543
544fun.ret:
545  ret void
546}
547
548; Function Attrs: nounwind
549declare noalias ptr @malloc(i64)
550
551; Function Attrs: nounwind
552declare void @free(ptr nocapture)
553
554declare void @boo()
555
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.
559declare void @boo_readnone() readnone
560
561declare i32 @__gxx_personality_v0(...)
562
563declare ptr @__cxa_begin_catch(ptr)
564
565declare void @__cxa_end_catch()
566
567declare i32 @llvm.eh.typeid.for.p0(ptr)
568
569declare void @f() uwtable
570