1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --force-update
2 ; RUN: opt < %s -S -passes="inline" | FileCheck %s
4 define void @callee(i32 %a, i32 %b) #0 {
8 %cmp = icmp slt i32 %a, %b
9 br i1 %cmp, label %for.body, label %for.end
11 br label %for.cond, !llvm.loop !0
18 define void @caller(i32 %a, i32 %b) #1 {
19 ; CHECK: Function Attrs: noinline
20 ; CHECK-LABEL: define {{[^@]+}}@caller
21 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1:#.*]] {
23 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
25 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
26 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
28 ; CHECK-NEXT: br label [[FOR_COND]]
30 ; CHECK-NEXT: br label [[FOR_COND_I:%.*]]
32 ; CHECK-NEXT: br label [[FOR_COND_I]], !llvm.loop [[LOOP0:![0-9]+]]
34 ; CHECK-NEXT: ret void
39 %cmp = icmp slt i32 %a, %b
40 br i1 %cmp, label %for.body, label %for.end
44 call void @callee(i32 0, i32 5)
48 define void @callee_no_metadata(i32 %a, i32 %b) {
52 %cmp = icmp slt i32 %a, %b
53 br i1 %cmp, label %for.body, label %for.end
62 define void @caller_no_metadata(i32 %a, i32 %b) {
63 ; CHECK-LABEL: define {{[^@]+}}@caller_no_metadata
64 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
66 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
68 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
69 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
71 ; CHECK-NEXT: br label [[FOR_COND]]
73 ; CHECK-NEXT: br label [[FOR_COND_I:%.*]]
75 ; CHECK-NEXT: br label [[FOR_COND_I]]
76 ; CHECK: callee_no_metadata.exit:
77 ; CHECK-NEXT: ret void
82 %cmp = icmp slt i32 %a, %b
83 br i1 %cmp, label %for.body, label %for.end
87 call void @callee_no_metadata(i32 0, i32 5)
91 define void @callee_mustprogress(i32 %a, i32 %b) #0 {
95 %cmp = icmp slt i32 %a, %b
96 br i1 %cmp, label %for.body, label %for.end
105 define void @caller_mustprogress(i32 %a, i32 %b) #0 {
106 ; CHECK: Function Attrs: mustprogress
107 ; CHECK-LABEL: define {{[^@]+}}@caller_mustprogress
108 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR0:#[0-9]+]] {
110 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
112 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
113 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
115 ; CHECK-NEXT: br label [[FOR_COND]]
117 ; CHECK-NEXT: br label [[FOR_COND_I:%.*]]
119 ; CHECK-NEXT: br label [[FOR_COND_I]]
120 ; CHECK: callee_mustprogress.exit:
121 ; CHECK-NEXT: ret void
126 %cmp = icmp slt i32 %a, %b
127 br i1 %cmp, label %for.body, label %for.end
131 call void @callee_mustprogress(i32 0, i32 5)
135 define void @caller_mustprogress_callee_no_metadata(i32 %a, i32 %b) #0 {
136 ; CHECK-LABEL: define {{[^@]+}}@caller_mustprogress_callee_no_metadata
137 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
139 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
141 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
142 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
144 ; CHECK-NEXT: br label [[FOR_COND]]
146 ; CHECK-NEXT: br label [[FOR_COND_I:%.*]]
148 ; CHECK-NEXT: br label [[FOR_COND_I]]
149 ; CHECK: callee_no_metadata.exit:
150 ; CHECK-NEXT: ret void
155 %cmp = icmp slt i32 %a, %b
156 br i1 %cmp, label %for.body, label %for.end
160 call void @callee_no_metadata(i32 0, i32 5)
164 define void @callee_multiple(i32 %a, i32 %b) #0 {
166 %a.addr = alloca i32, align 4
167 %b.addr = alloca i32, align 4
168 %i = alloca i32, align 4
169 store i32 %a, ptr %a.addr, align 4
170 store i32 %b, ptr %b.addr, align 4
173 %0 = load i32, ptr %a.addr, align 4
174 %1 = load i32, ptr %b.addr, align 4
175 %cmp = icmp slt i32 %0, %1
176 br i1 %cmp, label %for.body, label %for.end
178 br label %for.cond, !llvm.loop !2
180 store i32 0, ptr %i, align 4
183 %2 = load i32, ptr %i, align 4
184 %cmp2 = icmp slt i32 %2, 10
185 br i1 %cmp2, label %for.body3, label %for.end4
189 %3 = load i32, ptr %i, align 4
190 %inc = add nsw i32 %3, 1
191 store i32 %inc, ptr %i, align 4
192 br label %for.cond1, !llvm.loop !4
199 define void @caller_multiple(i32 %a, i32 %b) #1 {
200 ; CHECK: Function Attrs: noinline
201 ; CHECK-LABEL: define {{[^@]+}}@caller_multiple
202 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] {
204 ; CHECK-NEXT: [[A_ADDR_I:%.*]] = alloca i32, align 4
205 ; CHECK-NEXT: [[B_ADDR_I:%.*]] = alloca i32, align 4
206 ; CHECK-NEXT: [[I_I:%.*]] = alloca i32, align 4
207 ; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
208 ; CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
209 ; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
210 ; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
211 ; CHECK-NEXT: store i32 [[B]], ptr [[B_ADDR]], align 4
212 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
214 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
215 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
216 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
217 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
219 ; CHECK-NEXT: br label [[FOR_COND]]
221 ; CHECK-NEXT: store i32 0, ptr [[I]], align 4
222 ; CHECK-NEXT: br label [[FOR_COND1:%.*]]
224 ; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[I]], align 4
225 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[TMP2]], 10
226 ; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_BODY3:%.*]], label [[FOR_END4:%.*]]
228 ; CHECK-NEXT: br label [[FOR_INC:%.*]]
230 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[I]], align 4
231 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
232 ; CHECK-NEXT: store i32 [[INC]], ptr [[I]], align 4
233 ; CHECK-NEXT: br label [[FOR_COND1]]
235 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[A_ADDR_I]])
236 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[B_ADDR_I]])
237 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I_I]])
238 ; CHECK-NEXT: store i32 0, ptr [[A_ADDR_I]], align 4
239 ; CHECK-NEXT: store i32 5, ptr [[B_ADDR_I]], align 4
240 ; CHECK-NEXT: br label [[FOR_COND_I:%.*]]
242 ; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
243 ; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
244 ; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[TMP7]], [[TMP8]]
245 ; CHECK-NEXT: br i1 [[CMP_I]], label [[FOR_BODY_I:%.*]], label [[FOR_END_I:%.*]]
247 ; CHECK-NEXT: br label [[FOR_COND_I]], !llvm.loop [[LOOP2:![0-9]+]]
249 ; CHECK-NEXT: store i32 0, ptr [[I_I]], align 4
250 ; CHECK-NEXT: br label [[FOR_COND1_I:%.*]]
251 ; CHECK: for.cond1.i:
252 ; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[I_I]], align 4
253 ; CHECK-NEXT: [[CMP2_I:%.*]] = icmp slt i32 [[TMP9]], 10
254 ; CHECK-NEXT: br i1 [[CMP2_I]], label [[FOR_BODY3_I:%.*]], label [[FOR_END4_I:%.*]]
255 ; CHECK: for.body3.i:
256 ; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[I_I]], align 4
257 ; CHECK-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP10]], 1
258 ; CHECK-NEXT: store i32 [[INC_I]], ptr [[I_I]], align 4
259 ; CHECK-NEXT: br label [[FOR_COND1_I]], !llvm.loop [[LOOP3:![0-9]+]]
261 ; CHECK-NEXT: br label [[WHILE_BODY_I:%.*]]
262 ; CHECK: while.body.i:
263 ; CHECK-NEXT: br label [[WHILE_BODY_I]]
264 ; CHECK: callee_multiple.exit:
265 ; CHECK-NEXT: ret void
268 %a.addr = alloca i32, align 4
269 %b.addr = alloca i32, align 4
270 %i = alloca i32, align 4
271 store i32 %a, ptr %a.addr, align 4
272 store i32 %b, ptr %b.addr, align 4
275 %0 = load i32, ptr %a.addr, align 4
276 %1 = load i32, ptr %b.addr, align 4
277 %cmp = icmp slt i32 %0, %1
278 br i1 %cmp, label %for.body, label %for.end
282 store i32 0, ptr %i, align 4
285 %2 = load i32, ptr %i, align 4
286 %cmp2 = icmp slt i32 %2, 10
287 br i1 %cmp2, label %for.body3, label %for.end4
291 %3 = load i32, ptr %i, align 4
292 %inc = add nsw i32 %3, 1
293 store i32 %inc, ptr %i, align 4
296 call void @callee_multiple(i32 0, i32 5)
300 define void @callee_nested(i32 %a, i32 %b) #0 {
302 %a.addr = alloca i32, align 4
303 %b.addr = alloca i32, align 4
304 %i = alloca i32, align 4
305 store i32 %a, ptr %a.addr, align 4
306 store i32 %b, ptr %b.addr, align 4
309 %0 = load i32, ptr %a.addr, align 4
310 %1 = load i32, ptr %b.addr, align 4
311 %cmp = icmp slt i32 %0, %1
312 br i1 %cmp, label %for.body, label %for.end
314 br label %for.cond, !llvm.loop !0
316 store i32 0, ptr %i, align 4
319 %2 = load i32, ptr %i, align 4
320 %cmp2 = icmp slt i32 %2, 10
321 br i1 %cmp2, label %for.body3, label %for.end8
325 %3 = load i32, ptr %b.addr, align 4
326 %4 = load i32, ptr %a.addr, align 4
327 %cmp5 = icmp slt i32 %3, %4
328 br i1 %cmp5, label %for.body6, label %for.end7
330 br label %for.cond4, !llvm.loop !2
334 %5 = load i32, ptr %i, align 4
335 %inc = add nsw i32 %5, 1
336 store i32 %inc, ptr %i, align 4
337 br label %for.cond1, !llvm.loop !3
344 define void @caller_nested(i32 %a, i32 %b) #1 {
345 ; CHECK: Function Attrs: noinline
346 ; CHECK-LABEL: define {{[^@]+}}@caller_nested
347 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] {
349 ; CHECK-NEXT: [[A_ADDR_I:%.*]] = alloca i32, align 4
350 ; CHECK-NEXT: [[B_ADDR_I:%.*]] = alloca i32, align 4
351 ; CHECK-NEXT: [[I_I:%.*]] = alloca i32, align 4
352 ; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
353 ; CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
354 ; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
355 ; CHECK-NEXT: [[I9:%.*]] = alloca i32, align 4
356 ; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
357 ; CHECK-NEXT: store i32 [[B]], ptr [[B_ADDR]], align 4
358 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
360 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
361 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
362 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
363 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END8:%.*]]
365 ; CHECK-NEXT: store i32 0, ptr [[I]], align 4
366 ; CHECK-NEXT: br label [[FOR_COND1:%.*]]
368 ; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[I]], align 4
369 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[TMP2]], 10
370 ; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_BODY3:%.*]], label [[FOR_END7:%.*]]
372 ; CHECK-NEXT: br label [[FOR_COND4:%.*]]
374 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[B_ADDR]], align 4
375 ; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[A_ADDR]], align 4
376 ; CHECK-NEXT: [[CMP5:%.*]] = icmp slt i32 [[TMP3]], [[TMP4]]
377 ; CHECK-NEXT: br i1 [[CMP5]], label [[FOR_BODY6:%.*]], label [[FOR_END:%.*]]
379 ; CHECK-NEXT: br label [[FOR_COND4]]
381 ; CHECK-NEXT: br label [[FOR_INC:%.*]]
383 ; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[I]], align 4
384 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP5]], 1
385 ; CHECK-NEXT: store i32 [[INC]], ptr [[I]], align 4
386 ; CHECK-NEXT: br label [[FOR_COND1]]
388 ; CHECK-NEXT: br label [[FOR_COND]]
390 ; CHECK-NEXT: store i32 0, ptr [[I9]], align 4
391 ; CHECK-NEXT: br label [[FOR_COND10:%.*]]
393 ; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[I9]], align 4
394 ; CHECK-NEXT: [[CMP11:%.*]] = icmp slt i32 [[TMP6]], 10
395 ; CHECK-NEXT: br i1 [[CMP11]], label [[FOR_BODY12:%.*]], label [[FOR_END15:%.*]]
397 ; CHECK-NEXT: br label [[FOR_INC13:%.*]]
399 ; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[I9]], align 4
400 ; CHECK-NEXT: [[INC14:%.*]] = add nsw i32 [[TMP7]], 1
401 ; CHECK-NEXT: store i32 [[INC14]], ptr [[I9]], align 4
402 ; CHECK-NEXT: br label [[FOR_COND10]]
404 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[A_ADDR_I]])
405 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[B_ADDR_I]])
406 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[I_I]])
407 ; CHECK-NEXT: store i32 0, ptr [[A_ADDR_I]], align 4
408 ; CHECK-NEXT: store i32 5, ptr [[B_ADDR_I]], align 4
409 ; CHECK-NEXT: br label [[FOR_COND_I:%.*]]
411 ; CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
412 ; CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
413 ; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[TMP11]], [[TMP12]]
414 ; CHECK-NEXT: br i1 [[CMP_I]], label [[FOR_BODY_I:%.*]], label [[FOR_END_I:%.*]]
416 ; CHECK-NEXT: br label [[FOR_COND_I]], !llvm.loop [[LOOP0]]
418 ; CHECK-NEXT: store i32 0, ptr [[I_I]], align 4
419 ; CHECK-NEXT: br label [[FOR_COND1_I:%.*]]
420 ; CHECK: for.cond1.i:
421 ; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[I_I]], align 4
422 ; CHECK-NEXT: [[CMP2_I:%.*]] = icmp slt i32 [[TMP13]], 10
423 ; CHECK-NEXT: br i1 [[CMP2_I]], label [[FOR_BODY3_I:%.*]], label [[FOR_END8_I:%.*]]
424 ; CHECK: for.body3.i:
425 ; CHECK-NEXT: br label [[FOR_COND4_I:%.*]]
426 ; CHECK: for.cond4.i:
427 ; CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
428 ; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
429 ; CHECK-NEXT: [[CMP5_I:%.*]] = icmp slt i32 [[TMP14]], [[TMP15]]
430 ; CHECK-NEXT: br i1 [[CMP5_I]], label [[FOR_BODY6_I:%.*]], label [[FOR_END7_I:%.*]]
431 ; CHECK: for.body6.i:
432 ; CHECK-NEXT: br label [[FOR_COND4_I]], !llvm.loop [[LOOP2:![0-9]+]]
434 ; CHECK-NEXT: [[TMP16:%.*]] = load i32, ptr [[I_I]], align 4
435 ; CHECK-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP16]], 1
436 ; CHECK-NEXT: store i32 [[INC_I]], ptr [[I_I]], align 4
437 ; CHECK-NEXT: br label [[FOR_COND1_I]], !llvm.loop [[LOOP4:![0-9]+]]
439 ; CHECK-NEXT: br label [[WHILE_BODY_I:%.*]]
440 ; CHECK: while.body.i:
441 ; CHECK-NEXT: br label [[WHILE_BODY_I]]
442 ; CHECK: callee_nested.exit:
443 ; CHECK-NEXT: ret void
446 %a.addr = alloca i32, align 4
447 %b.addr = alloca i32, align 4
448 %i = alloca i32, align 4
449 %i9 = alloca i32, align 4
450 store i32 %a, ptr %a.addr, align 4
451 store i32 %b, ptr %b.addr, align 4
454 %0 = load i32, ptr %a.addr, align 4
455 %1 = load i32, ptr %b.addr, align 4
456 %cmp = icmp slt i32 %0, %1
457 br i1 %cmp, label %for.body, label %for.end8
459 store i32 0, ptr %i, align 4
462 %2 = load i32, ptr %i, align 4
463 %cmp2 = icmp slt i32 %2, 10
464 br i1 %cmp2, label %for.body3, label %for.end7
468 %3 = load i32, ptr %b.addr, align 4
469 %4 = load i32, ptr %a.addr, align 4
470 %cmp5 = icmp slt i32 %3, %4
471 br i1 %cmp5, label %for.body6, label %for.end
477 %5 = load i32, ptr %i, align 4
478 %inc = add nsw i32 %5, 1
479 store i32 %inc, ptr %i, align 4
484 store i32 0, ptr %i9, align 4
487 %6 = load i32, ptr %i9, align 4
488 %cmp11 = icmp slt i32 %6, 10
489 br i1 %cmp11, label %for.body12, label %for.end15
493 %7 = load i32, ptr %i9, align 4
494 %inc14 = add nsw i32 %7, 1
495 store i32 %inc14, ptr %i9, align 4
498 call void @callee_nested(i32 0, i32 5)
502 ; CHECK: attributes [[ATTR0]] = { mustprogress }
503 ; CHECK: attributes [[ATTR1]] = { noinline }
505 ; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[GEN1:!.*]]}
506 ; CHECK: [[GEN1]] = !{!"llvm.loop.mustprogress"}
507 ; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[GEN1:!.*]]}
508 ; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[GEN1:!.*]]}
509 ; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[GEN1:!.*]]}
511 attributes #0 = { mustprogress }
512 attributes #1 = { noinline }
513 attributes #2 = { noinline mustprogress }
515 !0 = distinct !{!0, !1}
516 !1 = !{!"llvm.loop.mustprogress"}
517 !2 = distinct !{!2, !1}
518 !3 = distinct !{!3, !1}
519 !4 = distinct !{!4, !1}
520 !5 = distinct !{!5, !1}
521 !6 = distinct !{!6, !1}
522 !7 = distinct !{!7, !1}