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(
13 ; CHECK-NEXT: [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 4
14 ; CHECK-NEXT: br label [[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]]
22 ; CHECK-NEXT: tail call void @f()
23 ; CHECK-NEXT: br label [[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
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
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
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(
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:%.*]]
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]]
69 ; CHECK-NEXT: tail call void @f()
70 ; CHECK-NEXT: br label [[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
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
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
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(
108 ; CHECK-NEXT: [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 4
109 ; CHECK-NEXT: br label [[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]]
116 ; CHECK-NEXT: tail call void @f()
117 ; CHECK-NEXT: br label [[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
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
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
150 define void @test_dead_on_unwind(ptr noalias dead_on_unwind %a, i1 zeroext %y) uwtable {
151 ; CHECK-LABEL: @test_dead_on_unwind(
153 ; CHECK-NEXT: [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 4
154 ; CHECK-NEXT: br label [[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]]
161 ; CHECK-NEXT: tail call void @f()
162 ; CHECK-NEXT: br label [[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
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
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
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(
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:%.*]]
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
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
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
234 ;; Same as test3, but with unordered atomics
235 define void @test3b(i1 zeroext %y) uwtable {
236 ; CHECK-LABEL: @test3b(
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:%.*]]
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
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
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
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
277 define void @loop_within_tryblock() personality ptr @__gxx_personality_v0 {
278 ; CHECK-LABEL: @loop_within_tryblock(
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:%.*]]
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:%.*]]
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]]
296 ; CHECK-NEXT: [[INC]] = add nsw i32 [[I_0]], 1
297 ; CHECK-NEXT: br label [[FOR_COND]]
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:%.*]]
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:%.*]]
316 ; CHECK-NEXT: ret void
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]]
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]]
327 %a = alloca i32, align 4
328 store i32 0, ptr %a, align 4
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
337 %0 = load i32, ptr %a, align 4
338 %add = add nsw i32 %0, 1
339 store i32 %add, ptr %a, align 4
341 to label %invoke.cont unwind label %lpad
347 %inc = add nsw i32 %i.0, 1
351 %1 = landingpad { ptr, i32 }
353 %2 = extractvalue { ptr, i32 } %1, 0
354 %3 = extractvalue { ptr, i32 } %1, 1
355 br label %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
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
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(
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:%.*]]
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:%.*]]
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]]
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:%.*]]
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:%.*]]
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:%.*]]
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]]
420 ; CHECK-NEXT: ret void
423 %call = call ptr @malloc(i64 4)
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
435 to label %invoke.cont unwind label %lpad
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
449 %1 = landingpad { ptr, i32 }
451 %2 = extractvalue { ptr, i32 } %1, 0
452 %3 = extractvalue { ptr, i32 } %1, 1
456 %4 = call ptr @__cxa_begin_catch(ptr %2) #4
457 call void @free(ptr %call)
458 call void @__cxa_end_catch()
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(
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:%.*]]
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:%.*]]
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]]
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:%.*]]
489 ; CHECK-NEXT: br label [[FUN_RET:%.*]]
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:%.*]]
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]]
502 ; CHECK-NEXT: ret void
505 %call = call ptr @malloc(i64 4)
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
516 invoke void @boo_readnone()
517 to label %invoke.cont unwind label %lpad
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
532 %1 = landingpad { ptr, i32 }
534 %2 = extractvalue { ptr, i32 } %1, 0
535 %3 = extractvalue { ptr, i32 } %1, 1
539 %4 = call ptr @__cxa_begin_catch(ptr %2) #4
540 call void @free(ptr %call)
541 call void @__cxa_end_catch()
548 ; Function Attrs: nounwind
549 declare noalias ptr @malloc(i64)
551 ; Function Attrs: nounwind
552 declare void @free(ptr nocapture)
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