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, i32* %a.addr, align 4
170 store i32 %b, i32* %b.addr, align 4
173 %0 = load i32, i32* %a.addr, align 4
174 %1 = load i32, i32* %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, i32* %i, align 4
183 %2 = load i32, i32* %i, align 4
184 %cmp2 = icmp slt i32 %2, 10
185 br i1 %cmp2, label %for.body3, label %for.end4
189 %3 = load i32, i32* %i, align 4
190 %inc = add nsw i32 %3, 1
191 store i32 %inc, i32* %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]], i32* [[A_ADDR]], align 4
211 ; CHECK-NEXT: store i32 [[B]], i32* [[B_ADDR]], align 4
212 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
214 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
215 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[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, i32* [[I]], align 4
222 ; CHECK-NEXT: br label [[FOR_COND1:%.*]]
224 ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[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, i32* [[I]], align 4
231 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
232 ; CHECK-NEXT: store i32 [[INC]], i32* [[I]], align 4
233 ; CHECK-NEXT: br label [[FOR_COND1]]
235 ; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[A_ADDR_I]] to i8*
236 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]])
237 ; CHECK-NEXT: [[TMP5:%.*]] = bitcast i32* [[B_ADDR_I]] to i8*
238 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]])
239 ; CHECK-NEXT: [[TMP6:%.*]] = bitcast i32* [[I_I]] to i8*
240 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]])
241 ; CHECK-NEXT: store i32 0, i32* [[A_ADDR_I]], align 4
242 ; CHECK-NEXT: store i32 5, i32* [[B_ADDR_I]], align 4
243 ; CHECK-NEXT: br label [[FOR_COND_I:%.*]]
245 ; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[A_ADDR_I]], align 4
246 ; CHECK-NEXT: [[TMP8:%.*]] = load i32, i32* [[B_ADDR_I]], align 4
247 ; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[TMP7]], [[TMP8]]
248 ; CHECK-NEXT: br i1 [[CMP_I]], label [[FOR_BODY_I:%.*]], label [[FOR_END_I:%.*]]
250 ; CHECK-NEXT: br label [[FOR_COND_I]], !llvm.loop [[LOOP2:![0-9]+]]
252 ; CHECK-NEXT: store i32 0, i32* [[I_I]], align 4
253 ; CHECK-NEXT: br label [[FOR_COND1_I:%.*]]
254 ; CHECK: for.cond1.i:
255 ; CHECK-NEXT: [[TMP9:%.*]] = load i32, i32* [[I_I]], align 4
256 ; CHECK-NEXT: [[CMP2_I:%.*]] = icmp slt i32 [[TMP9]], 10
257 ; CHECK-NEXT: br i1 [[CMP2_I]], label [[FOR_BODY3_I:%.*]], label [[FOR_END4_I:%.*]]
258 ; CHECK: for.body3.i:
259 ; CHECK-NEXT: [[TMP10:%.*]] = load i32, i32* [[I_I]], align 4
260 ; CHECK-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP10]], 1
261 ; CHECK-NEXT: store i32 [[INC_I]], i32* [[I_I]], align 4
262 ; CHECK-NEXT: br label [[FOR_COND1_I]], !llvm.loop [[LOOP3:![0-9]+]]
264 ; CHECK-NEXT: br label [[WHILE_BODY_I:%.*]]
265 ; CHECK: while.body.i:
266 ; CHECK-NEXT: br label [[WHILE_BODY_I]]
267 ; CHECK: callee_multiple.exit:
268 ; CHECK-NEXT: ret void
271 %a.addr = alloca i32, align 4
272 %b.addr = alloca i32, align 4
273 %i = alloca i32, align 4
274 store i32 %a, i32* %a.addr, align 4
275 store i32 %b, i32* %b.addr, align 4
278 %0 = load i32, i32* %a.addr, align 4
279 %1 = load i32, i32* %b.addr, align 4
280 %cmp = icmp slt i32 %0, %1
281 br i1 %cmp, label %for.body, label %for.end
285 store i32 0, i32* %i, align 4
288 %2 = load i32, i32* %i, align 4
289 %cmp2 = icmp slt i32 %2, 10
290 br i1 %cmp2, label %for.body3, label %for.end4
294 %3 = load i32, i32* %i, align 4
295 %inc = add nsw i32 %3, 1
296 store i32 %inc, i32* %i, align 4
299 call void @callee_multiple(i32 0, i32 5)
303 define void @callee_nested(i32 %a, i32 %b) #0 {
305 %a.addr = alloca i32, align 4
306 %b.addr = alloca i32, align 4
307 %i = alloca i32, align 4
308 store i32 %a, i32* %a.addr, align 4
309 store i32 %b, i32* %b.addr, align 4
312 %0 = load i32, i32* %a.addr, align 4
313 %1 = load i32, i32* %b.addr, align 4
314 %cmp = icmp slt i32 %0, %1
315 br i1 %cmp, label %for.body, label %for.end
317 br label %for.cond, !llvm.loop !0
319 store i32 0, i32* %i, align 4
322 %2 = load i32, i32* %i, align 4
323 %cmp2 = icmp slt i32 %2, 10
324 br i1 %cmp2, label %for.body3, label %for.end8
328 %3 = load i32, i32* %b.addr, align 4
329 %4 = load i32, i32* %a.addr, align 4
330 %cmp5 = icmp slt i32 %3, %4
331 br i1 %cmp5, label %for.body6, label %for.end7
333 br label %for.cond4, !llvm.loop !2
337 %5 = load i32, i32* %i, align 4
338 %inc = add nsw i32 %5, 1
339 store i32 %inc, i32* %i, align 4
340 br label %for.cond1, !llvm.loop !3
347 define void @caller_nested(i32 %a, i32 %b) #1 {
348 ; CHECK: Function Attrs: noinline
349 ; CHECK-LABEL: define {{[^@]+}}@caller_nested
350 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]] {
352 ; CHECK-NEXT: [[A_ADDR_I:%.*]] = alloca i32, align 4
353 ; CHECK-NEXT: [[B_ADDR_I:%.*]] = alloca i32, align 4
354 ; CHECK-NEXT: [[I_I:%.*]] = alloca i32, align 4
355 ; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
356 ; CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
357 ; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
358 ; CHECK-NEXT: [[I9:%.*]] = alloca i32, align 4
359 ; CHECK-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4
360 ; CHECK-NEXT: store i32 [[B]], i32* [[B_ADDR]], align 4
361 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
363 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
364 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[B_ADDR]], align 4
365 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
366 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END8:%.*]]
368 ; CHECK-NEXT: store i32 0, i32* [[I]], align 4
369 ; CHECK-NEXT: br label [[FOR_COND1:%.*]]
371 ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
372 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[TMP2]], 10
373 ; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_BODY3:%.*]], label [[FOR_END7:%.*]]
375 ; CHECK-NEXT: br label [[FOR_COND4:%.*]]
377 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[B_ADDR]], align 4
378 ; CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[A_ADDR]], align 4
379 ; CHECK-NEXT: [[CMP5:%.*]] = icmp slt i32 [[TMP3]], [[TMP4]]
380 ; CHECK-NEXT: br i1 [[CMP5]], label [[FOR_BODY6:%.*]], label [[FOR_END:%.*]]
382 ; CHECK-NEXT: br label [[FOR_COND4]]
384 ; CHECK-NEXT: br label [[FOR_INC:%.*]]
386 ; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[I]], align 4
387 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP5]], 1
388 ; CHECK-NEXT: store i32 [[INC]], i32* [[I]], align 4
389 ; CHECK-NEXT: br label [[FOR_COND1]]
391 ; CHECK-NEXT: br label [[FOR_COND]]
393 ; CHECK-NEXT: store i32 0, i32* [[I9]], align 4
394 ; CHECK-NEXT: br label [[FOR_COND10:%.*]]
396 ; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[I9]], align 4
397 ; CHECK-NEXT: [[CMP11:%.*]] = icmp slt i32 [[TMP6]], 10
398 ; CHECK-NEXT: br i1 [[CMP11]], label [[FOR_BODY12:%.*]], label [[FOR_END15:%.*]]
400 ; CHECK-NEXT: br label [[FOR_INC13:%.*]]
402 ; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[I9]], align 4
403 ; CHECK-NEXT: [[INC14:%.*]] = add nsw i32 [[TMP7]], 1
404 ; CHECK-NEXT: store i32 [[INC14]], i32* [[I9]], align 4
405 ; CHECK-NEXT: br label [[FOR_COND10]]
407 ; CHECK-NEXT: [[TMP8:%.*]] = bitcast i32* [[A_ADDR_I]] to i8*
408 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]])
409 ; CHECK-NEXT: [[TMP9:%.*]] = bitcast i32* [[B_ADDR_I]] to i8*
410 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP9]])
411 ; CHECK-NEXT: [[TMP10:%.*]] = bitcast i32* [[I_I]] to i8*
412 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP10]])
413 ; CHECK-NEXT: store i32 0, i32* [[A_ADDR_I]], align 4
414 ; CHECK-NEXT: store i32 5, i32* [[B_ADDR_I]], align 4
415 ; CHECK-NEXT: br label [[FOR_COND_I:%.*]]
417 ; CHECK-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR_I]], align 4
418 ; CHECK-NEXT: [[TMP12:%.*]] = load i32, i32* [[B_ADDR_I]], align 4
419 ; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[TMP11]], [[TMP12]]
420 ; CHECK-NEXT: br i1 [[CMP_I]], label [[FOR_BODY_I:%.*]], label [[FOR_END_I:%.*]]
422 ; CHECK-NEXT: br label [[FOR_COND_I]], !llvm.loop [[LOOP0]]
424 ; CHECK-NEXT: store i32 0, i32* [[I_I]], align 4
425 ; CHECK-NEXT: br label [[FOR_COND1_I:%.*]]
426 ; CHECK: for.cond1.i:
427 ; CHECK-NEXT: [[TMP13:%.*]] = load i32, i32* [[I_I]], align 4
428 ; CHECK-NEXT: [[CMP2_I:%.*]] = icmp slt i32 [[TMP13]], 10
429 ; CHECK-NEXT: br i1 [[CMP2_I]], label [[FOR_BODY3_I:%.*]], label [[FOR_END8_I:%.*]]
430 ; CHECK: for.body3.i:
431 ; CHECK-NEXT: br label [[FOR_COND4_I:%.*]]
432 ; CHECK: for.cond4.i:
433 ; CHECK-NEXT: [[TMP14:%.*]] = load i32, i32* [[B_ADDR_I]], align 4
434 ; CHECK-NEXT: [[TMP15:%.*]] = load i32, i32* [[A_ADDR_I]], align 4
435 ; CHECK-NEXT: [[CMP5_I:%.*]] = icmp slt i32 [[TMP14]], [[TMP15]]
436 ; CHECK-NEXT: br i1 [[CMP5_I]], label [[FOR_BODY6_I:%.*]], label [[FOR_END7_I:%.*]]
437 ; CHECK: for.body6.i:
438 ; CHECK-NEXT: br label [[FOR_COND4_I]], !llvm.loop [[LOOP2:![0-9]+]]
440 ; CHECK-NEXT: [[TMP16:%.*]] = load i32, i32* [[I_I]], align 4
441 ; CHECK-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP16]], 1
442 ; CHECK-NEXT: store i32 [[INC_I]], i32* [[I_I]], align 4
443 ; CHECK-NEXT: br label [[FOR_COND1_I]], !llvm.loop [[LOOP4:![0-9]+]]
445 ; CHECK-NEXT: br label [[WHILE_BODY_I:%.*]]
446 ; CHECK: while.body.i:
447 ; CHECK-NEXT: br label [[WHILE_BODY_I]]
448 ; CHECK: callee_nested.exit:
449 ; CHECK-NEXT: ret void
452 %a.addr = alloca i32, align 4
453 %b.addr = alloca i32, align 4
454 %i = alloca i32, align 4
455 %i9 = alloca i32, align 4
456 store i32 %a, i32* %a.addr, align 4
457 store i32 %b, i32* %b.addr, align 4
460 %0 = load i32, i32* %a.addr, align 4
461 %1 = load i32, i32* %b.addr, align 4
462 %cmp = icmp slt i32 %0, %1
463 br i1 %cmp, label %for.body, label %for.end8
465 store i32 0, i32* %i, align 4
468 %2 = load i32, i32* %i, align 4
469 %cmp2 = icmp slt i32 %2, 10
470 br i1 %cmp2, label %for.body3, label %for.end7
474 %3 = load i32, i32* %b.addr, align 4
475 %4 = load i32, i32* %a.addr, align 4
476 %cmp5 = icmp slt i32 %3, %4
477 br i1 %cmp5, label %for.body6, label %for.end
483 %5 = load i32, i32* %i, align 4
484 %inc = add nsw i32 %5, 1
485 store i32 %inc, i32* %i, align 4
490 store i32 0, i32* %i9, align 4
493 %6 = load i32, i32* %i9, align 4
494 %cmp11 = icmp slt i32 %6, 10
495 br i1 %cmp11, label %for.body12, label %for.end15
499 %7 = load i32, i32* %i9, align 4
500 %inc14 = add nsw i32 %7, 1
501 store i32 %inc14, i32* %i9, align 4
504 call void @callee_nested(i32 0, i32 5)
508 ; CHECK: attributes [[ATTR0]] = { mustprogress }
509 ; CHECK: attributes [[ATTR1]] = { noinline }
511 ; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[GEN1:!.*]]}
512 ; CHECK: [[GEN1]] = !{!"llvm.loop.mustprogress"}
513 ; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[GEN1:!.*]]}
514 ; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[GEN1:!.*]]}
515 ; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[GEN1:!.*]]}
517 attributes #0 = { mustprogress }
518 attributes #1 = { noinline }
519 attributes #2 = { noinline mustprogress }
521 !0 = distinct !{!0, !1}
522 !1 = !{!"llvm.loop.mustprogress"}
523 !2 = distinct !{!2, !1}
524 !3 = distinct !{!3, !1}
525 !4 = distinct !{!4, !1}
526 !5 = distinct !{!5, !1}
527 !6 = distinct !{!6, !1}
528 !7 = distinct !{!7, !1}