xref: /llvm-project/llvm/test/Transforms/Inline/inlined-mustprogress-loop-metadata.ll (revision 151602c7a9935558ca671b35359989b261045db0)
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
3
4define void @callee(i32 %a, i32 %b) #0 {
5entry:
6  br label %for.cond
7for.cond:
8  %cmp = icmp slt i32 %a, %b
9  br i1 %cmp, label %for.body, label %for.end
10for.body:
11  br label %for.cond, !llvm.loop !0
12for.end:
13  br label %while.body
14while.body:
15  br label %while.body
16}
17
18define 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:#.*]] {
22; CHECK-NEXT:  entry:
23; CHECK-NEXT:    br label [[FOR_COND:%.*]]
24; CHECK:       for.cond:
25; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
26; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
27; CHECK:       for.body:
28; CHECK-NEXT:    br label [[FOR_COND]]
29; CHECK:       for.end:
30; CHECK-NEXT:    br label [[FOR_COND_I:%.*]]
31; CHECK:       for.cond.i:
32  ; CHECK-NEXT:    br label [[FOR_COND_I]], !llvm.loop [[LOOP0:![0-9]+]]
33; CHECK:       callee.exit:
34; CHECK-NEXT:    ret void
35;
36entry:
37  br label %for.cond
38for.cond:
39  %cmp = icmp slt i32 %a, %b
40  br i1 %cmp, label %for.body, label %for.end
41for.body:
42  br label %for.cond
43for.end:
44  call void @callee(i32 0, i32 5)
45  ret void
46}
47
48define void @callee_no_metadata(i32 %a, i32 %b) {
49entry:
50  br label %for.cond
51for.cond:
52  %cmp = icmp slt i32 %a, %b
53  br i1 %cmp, label %for.body, label %for.end
54for.body:
55  br label %for.cond
56for.end:
57  br label %while.body
58while.body:
59  br label %while.body
60}
61
62define void @caller_no_metadata(i32 %a, i32 %b) {
63; CHECK-LABEL: define {{[^@]+}}@caller_no_metadata
64; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
65; CHECK-NEXT:  entry:
66; CHECK-NEXT:    br label [[FOR_COND:%.*]]
67; CHECK:       for.cond:
68; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
69; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
70; CHECK:       for.body:
71; CHECK-NEXT:    br label [[FOR_COND]]
72; CHECK:       for.end:
73; CHECK-NEXT:    br label [[FOR_COND_I:%.*]]
74; CHECK:       for.cond.i:
75; CHECK-NEXT:    br label [[FOR_COND_I]]
76; CHECK:       callee_no_metadata.exit:
77; CHECK-NEXT:    ret void
78;
79entry:
80  br label %for.cond
81for.cond:
82  %cmp = icmp slt i32 %a, %b
83  br i1 %cmp, label %for.body, label %for.end
84for.body:
85  br label %for.cond
86for.end:
87  call void @callee_no_metadata(i32 0, i32 5)
88  ret void
89}
90
91define void @callee_mustprogress(i32 %a, i32 %b) #0 {
92entry:
93  br label %for.cond
94for.cond:
95  %cmp = icmp slt i32 %a, %b
96  br i1 %cmp, label %for.body, label %for.end
97for.body:
98  br label %for.cond
99for.end:
100  br label %while.body
101while.body:
102  br label %while.body
103}
104
105define 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]+]] {
109; CHECK-NEXT:  entry:
110; CHECK-NEXT:    br label [[FOR_COND:%.*]]
111; CHECK:       for.cond:
112; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
113; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
114; CHECK:       for.body:
115; CHECK-NEXT:    br label [[FOR_COND]]
116; CHECK:       for.end:
117; CHECK-NEXT:    br label [[FOR_COND_I:%.*]]
118; CHECK:       for.cond.i:
119; CHECK-NEXT:    br label [[FOR_COND_I]]
120; CHECK:       callee_mustprogress.exit:
121; CHECK-NEXT:    ret void
122;
123entry:
124  br label %for.cond
125for.cond:
126  %cmp = icmp slt i32 %a, %b
127  br i1 %cmp, label %for.body, label %for.end
128for.body:
129  br label %for.cond
130for.end:
131  call void @callee_mustprogress(i32 0, i32 5)
132  ret void
133}
134
135define 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:%.*]]) {
138; CHECK-NEXT:  entry:
139; CHECK-NEXT:    br label [[FOR_COND:%.*]]
140; CHECK:       for.cond:
141; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
142; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
143; CHECK:       for.body:
144; CHECK-NEXT:    br label [[FOR_COND]]
145; CHECK:       for.end:
146; CHECK-NEXT:    br label [[FOR_COND_I:%.*]]
147; CHECK:       for.cond.i:
148; CHECK-NEXT:    br label [[FOR_COND_I]]
149; CHECK:       callee_no_metadata.exit:
150; CHECK-NEXT:    ret void
151;
152entry:
153  br label %for.cond
154for.cond:
155  %cmp = icmp slt i32 %a, %b
156  br i1 %cmp, label %for.body, label %for.end
157for.body:
158  br label %for.cond
159for.end:
160  call void @callee_no_metadata(i32 0, i32 5)
161  ret void
162}
163
164define void @callee_multiple(i32 %a, i32 %b) #0 {
165entry:
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
171  br label %for.cond
172for.cond:
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
177for.body:
178  br label %for.cond, !llvm.loop !2
179for.end:
180  store i32 0, ptr %i, align 4
181  br label %for.cond1
182for.cond1:
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
186for.body3:
187  br label %for.inc
188for.inc:
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
193for.end4:
194  br label %while.body
195while.body:
196  br label %while.body
197}
198
199define 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]] {
203; CHECK-NEXT:  entry:
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:%.*]]
213; CHECK:       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:%.*]]
218; CHECK:       for.body:
219; CHECK-NEXT:    br label [[FOR_COND]]
220; CHECK:       for.end:
221; CHECK-NEXT:    store i32 0, ptr [[I]], align 4
222; CHECK-NEXT:    br label [[FOR_COND1:%.*]]
223; CHECK:       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:%.*]]
227; CHECK:       for.body3:
228; CHECK-NEXT:    br label [[FOR_INC:%.*]]
229; CHECK:       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]]
234; CHECK:       for.end4:
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:%.*]]
241; CHECK:       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:%.*]]
246; CHECK:       for.body.i:
247  ; CHECK-NEXT:    br label [[FOR_COND_I]], !llvm.loop [[LOOP2:![0-9]+]]
248; CHECK:       for.end.i:
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]+]]
260; CHECK:       for.end4.i:
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
266;
267entry:
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
273  br label %for.cond
274for.cond:
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
279for.body:
280  br label %for.cond
281for.end:
282  store i32 0, ptr %i, align 4
283  br label %for.cond1
284for.cond1:
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
288for.body3:
289  br label %for.inc
290for.inc:
291  %3 = load i32, ptr %i, align 4
292  %inc = add nsw i32 %3, 1
293  store i32 %inc, ptr %i, align 4
294  br label %for.cond1
295for.end4:
296  call void @callee_multiple(i32 0, i32 5)
297  ret void
298}
299
300define void @callee_nested(i32 %a, i32 %b) #0 {
301entry:
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
307  br label %for.cond
308for.cond:
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
313for.body:
314  br label %for.cond, !llvm.loop !0
315for.end:
316  store i32 0, ptr %i, align 4
317  br label %for.cond1
318for.cond1:
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
322for.body3:
323  br label %for.cond4
324for.cond4:
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
329for.body6:
330  br label %for.cond4, !llvm.loop !2
331for.end7:
332  br label %for.inc
333for.inc:
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
338for.end8:
339  br label %while.body
340while.body:
341  br label %while.body
342}
343
344define 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]] {
348; CHECK-NEXT:  entry:
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:%.*]]
359; CHECK:       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:%.*]]
364; CHECK:       for.body:
365; CHECK-NEXT:    store i32 0, ptr [[I]], align 4
366; CHECK-NEXT:    br label [[FOR_COND1:%.*]]
367; CHECK:       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:%.*]]
371; CHECK:       for.body3:
372; CHECK-NEXT:    br label [[FOR_COND4:%.*]]
373; CHECK:       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:%.*]]
378; CHECK:       for.body6:
379; CHECK-NEXT:    br label [[FOR_COND4]]
380; CHECK:       for.end:
381; CHECK-NEXT:    br label [[FOR_INC:%.*]]
382; CHECK:       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]]
387; CHECK:       for.end7:
388; CHECK-NEXT:    br label [[FOR_COND]]
389; CHECK:       for.end8:
390; CHECK-NEXT:    store i32 0, ptr [[I9]], align 4
391; CHECK-NEXT:    br label [[FOR_COND10:%.*]]
392; CHECK:       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:%.*]]
396; CHECK:       for.body12:
397; CHECK-NEXT:    br label [[FOR_INC13:%.*]]
398; CHECK:       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]]
403; CHECK:       for.end15:
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:%.*]]
410; CHECK:       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:%.*]]
415; CHECK:       for.body.i:
416; CHECK-NEXT:    br label [[FOR_COND_I]], !llvm.loop [[LOOP0]]
417; CHECK:       for.end.i:
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]+]]
433; CHECK:       for.end7.i:
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]+]]
438; CHECK:       for.end8.i:
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
444;
445entry:
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
452  br label %for.cond
453for.cond:
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
458for.body:
459  store i32 0, ptr %i, align 4
460  br label %for.cond1
461for.cond1:
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
465for.body3:
466  br label %for.cond4
467for.cond4:
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
472for.body6:
473  br label %for.cond4
474for.end:
475  br label %for.inc
476for.inc:
477  %5 = load i32, ptr %i, align 4
478  %inc = add nsw i32 %5, 1
479  store i32 %inc, ptr %i, align 4
480  br label %for.cond1
481for.end7:
482  br label %for.cond
483for.end8:
484  store i32 0, ptr %i9, align 4
485  br label %for.cond10
486for.cond10:
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
490for.body12:
491  br label %for.inc13
492for.inc13:
493  %7 = load i32, ptr %i9, align 4
494  %inc14 = add nsw i32 %7, 1
495  store i32 %inc14, ptr %i9, align 4
496  br label %for.cond10
497for.end15:
498  call void @callee_nested(i32 0, i32 5)
499  ret void
500}
501
502; CHECK: attributes [[ATTR0]] = { mustprogress }
503; CHECK: attributes [[ATTR1]] = { noinline }
504
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:!.*]]}
510
511attributes #0 = { mustprogress }
512attributes #1 = { noinline }
513attributes #2 = { noinline mustprogress }
514
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}
523