• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -canon-freeze -S | FileCheck %s
3; A set of tests that have one phi node
4declare void @call(i32)
5declare i32 @get_step()
6
7define void @add(i32 %init, i32 %n) {
8; CHECK-LABEL: @add(
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]]
11; CHECK-NEXT:    br label [[LOOP:%.*]]
12; CHECK:       loop:
13; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
14; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
15; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
16; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
17; CHECK:       exit:
18; CHECK-NEXT:    ret void
19;
20entry:
21  br label %loop
22
23loop:
24  %i = phi i32 [ %init, %entry], [%i.next, %loop ]
25  %i.next = add i32 %i, 1
26  %i.next.fr = freeze i32 %i.next
27  %cond = icmp eq i32 %i.next.fr, %n
28  br i1 %cond, label %loop, label %exit
29
30exit:
31  ret void
32}
33
34define void @add_comm(i32 %init, i32 %n) {
35; CHECK-LABEL: @add_comm(
36; CHECK-NEXT:  entry:
37; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]]
38; CHECK-NEXT:    br label [[LOOP:%.*]]
39; CHECK:       loop:
40; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
41; CHECK-NEXT:    [[I_NEXT]] = add i32 1, [[I]]
42; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
43; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
44; CHECK:       exit:
45; CHECK-NEXT:    ret void
46;
47entry:
48  br label %loop
49
50loop:
51  %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
52  %i.next = add i32 1, %i
53  %i.next.fr = freeze i32 %i.next
54  %cond = icmp eq i32 %i.next.fr, %n
55  br i1 %cond, label %loop, label %exit
56
57exit:
58  ret void
59}
60
61define void @add_multiuses(i32 %init, i32 %n) {
62; CHECK-LABEL: @add_multiuses(
63; CHECK-NEXT:  entry:
64; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]]
65; CHECK-NEXT:    br label [[LOOP:%.*]]
66; CHECK:       loop:
67; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
68; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
69; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
70; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
71; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
72; CHECK:       exit:
73; CHECK-NEXT:    ret void
74;
75entry:
76  br label %loop
77
78loop:
79  %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
80  %i.next = add i32 %i, 1
81  %i.next.fr = freeze i32 %i.next
82  call void @call(i32 %i.next.fr)
83  %cond = icmp eq i32 %i.next.fr, %n
84  br i1 %cond, label %loop, label %exit
85
86exit:
87  ret void
88}
89
90define void @add_multiuses2(i32 %init, i32 %n) {
91; CHECK-LABEL: @add_multiuses2(
92; CHECK-NEXT:  entry:
93; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]]
94; CHECK-NEXT:    br label [[LOOP:%.*]]
95; CHECK:       loop:
96; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
97; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
98; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
99; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
100; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
101; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
102; CHECK:       exit:
103; CHECK-NEXT:    ret void
104;
105entry:
106  br label %loop
107
108loop:
109  %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
110  %i.next = add i32 %i, 1
111  %i.next.fr = freeze i32 %i.next
112  call void @call(i32 %i.next.fr)
113  %i.next.fr2 = freeze i32 %i.next
114  call void @call(i32 %i.next.fr2)
115  %cond = icmp eq i32 %i.next.fr, %n
116  br i1 %cond, label %loop, label %exit
117
118exit:
119  ret void
120}
121
122define void @add_flags(i32 %init, i32 %n) {
123; CHECK-LABEL: @add_flags(
124; CHECK-NEXT:  entry:
125; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]]
126; CHECK-NEXT:    br label [[LOOP:%.*]]
127; CHECK:       loop:
128; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
129; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
130; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
131; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
132; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
133; CHECK:       exit:
134; CHECK-NEXT:    ret void
135;
136entry:
137  br label %loop
138
139loop:
140  %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
141  %i.next = add nuw nsw i32 %i, 1
142  %i.next.fr = freeze i32 %i.next
143  call void @call(i32 %i.next.fr)
144  %cond = icmp eq i32 %i.next.fr, %n
145  br i1 %cond, label %loop, label %exit
146
147exit:
148  ret void
149}
150
151define void @add_ind(i32 %init, i32 %n) {
152; CHECK-LABEL: @add_ind(
153; CHECK-NEXT:  entry:
154; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]]
155; CHECK-NEXT:    br label [[LOOP:%.*]]
156; CHECK:       loop:
157; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
158; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
159; CHECK-NEXT:    [[I_FR_NEXT:%.*]] = add nuw nsw i32 [[I]], 1
160; CHECK-NEXT:    call void @call(i32 [[I_FR_NEXT]])
161; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_FR_NEXT]], [[N:%.*]]
162; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
163; CHECK:       exit:
164; CHECK-NEXT:    ret void
165;
166entry:
167  br label %loop
168
169loop:
170  %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
171  %i.next = add nuw nsw i32 %i, 1
172  %i.fr = freeze i32 %i
173  %i.fr.next = add nuw nsw i32 %i.fr, 1
174  call void @call(i32 %i.fr.next)
175  %cond = icmp eq i32 %i.fr.next, %n
176  br i1 %cond, label %loop, label %exit
177
178exit:
179  ret void
180}
181
182; Negative test
183define void @add_ind_frozen(i32 %init, i32 %n) {
184; CHECK-LABEL: @add_ind_frozen(
185; CHECK-NEXT:  entry:
186; CHECK-NEXT:    br label [[LOOP:%.*]]
187; CHECK:       loop:
188; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ]
189; CHECK-NEXT:    [[I_FR:%.*]] = freeze i32 [[I]]
190; CHECK-NEXT:    [[I_NEXT_FR]] = add nuw nsw i32 [[I_FR]], 1
191; CHECK-NEXT:    call void @call(i32 [[I_NEXT_FR]])
192; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT_FR]], [[N:%.*]]
193; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
194; CHECK:       exit:
195; CHECK-NEXT:    ret void
196;
197entry:
198  br label %loop
199
200loop:
201  %i = phi i32 [%init, %entry], [%i.next.fr, %loop]
202  %i.fr = freeze i32 %i
203  %i.next.fr = add nuw nsw i32 %i.fr, 1
204  call void @call(i32 %i.next.fr)
205  %cond = icmp eq i32 %i.next.fr, %n
206  br i1 %cond, label %loop, label %exit
207
208exit:
209  ret void
210}
211
212define void @add_flags_not_compared(i32 %init, i32 %n) {
213; CHECK-LABEL: @add_flags_not_compared(
214; CHECK-NEXT:  entry:
215; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]]
216; CHECK-NEXT:    br label [[LOOP:%.*]]
217; CHECK:       loop:
218; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
219; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
220; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
221; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
222; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
223; CHECK:       exit:
224; CHECK-NEXT:    ret void
225;
226entry:
227  br label %loop
228
229loop:
230  %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
231  %i.next = add nuw nsw i32 %i, 1
232  %i.next.fr = freeze i32 %i.next
233  call void @call(i32 %i.next.fr)
234  %cond = icmp eq i32 %i.next, %n
235  br i1 %cond, label %loop, label %exit
236
237exit:
238  ret void
239}
240
241; Negative test
242define void @add_flags_not_compared_stepinst(i32 %init, i32 %n) {
243; CHECK-LABEL: @add_flags_not_compared_stepinst(
244; CHECK-NEXT:  entry:
245; CHECK-NEXT:    br label [[LOOP:%.*]]
246; CHECK:       loop:
247; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ]
248; CHECK-NEXT:    [[I_NEXT:%.*]] = add nuw nsw i32 [[I]], 1
249; CHECK-NEXT:    [[I_NEXT_FR]] = freeze i32 [[I_NEXT]]
250; CHECK-NEXT:    call void @call(i32 [[I_NEXT_FR]])
251; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
252; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
253; CHECK:       exit:
254; CHECK-NEXT:    ret void
255;
256entry:
257  br label %loop
258
259loop:
260  %i = phi i32 [ %init, %entry ], [ %i.next.fr, %loop ]
261  %i.next = add nuw nsw i32 %i, 1
262  %i.next.fr = freeze i32 %i.next
263  call void @call(i32 %i.next.fr)
264  %cond = icmp eq i32 %i.next, %n
265  br i1 %cond, label %loop, label %exit
266
267exit:
268  ret void
269}
270
271; Negative test
272; If pushing freeze through icmp is needed, this should be enabled.
273; There is no correctness issue in pushing freeze into icmp here, just it's
274; being conservative right now.
275define void @add_flags_stepinst_frozen(i32 %init, i32 %n) {
276; CHECK-LABEL: @add_flags_stepinst_frozen(
277; CHECK-NEXT:  entry:
278; CHECK-NEXT:    br label [[LOOP:%.*]]
279; CHECK:       loop:
280; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
281; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1
282; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
283; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
284; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]
285; CHECK-NEXT:    br i1 [[COND_FR]], label [[LOOP]], label [[EXIT:%.*]]
286; CHECK:       exit:
287; CHECK-NEXT:    ret void
288;
289entry:
290  br label %loop
291
292loop:
293  %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
294  %i.next = add nuw nsw i32 %i, 1
295  call void @call(i32 %i.next)
296  %cond = icmp eq i32 %i.next, %n
297  %cond.fr = freeze i1 %cond
298  br i1 %cond.fr, label %loop, label %exit
299
300exit:
301  ret void
302}
303
304define void @sub(i32 %init, i32 %n) {
305; CHECK-LABEL: @sub(
306; CHECK-NEXT:  entry:
307; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]]
308; CHECK-NEXT:    br label [[LOOP:%.*]]
309; CHECK:       loop:
310; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
311; CHECK-NEXT:    [[I_NEXT]] = sub i32 [[I]], 1
312; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
313; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
314; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
315; CHECK:       exit:
316; CHECK-NEXT:    ret void
317;
318entry:
319  br label %loop
320
321loop:
322  %i = phi i32 [%init, %entry], [%i.next, %loop]
323  %i.next = sub nuw nsw i32 %i, 1
324  %i.next.fr = freeze i32 %i.next
325  call void @call(i32 %i.next.fr)
326  %cond = icmp eq i32 %i.next.fr, %n
327  br i1 %cond, label %loop, label %exit
328
329exit:
330  ret void
331}
332
333define void @init_const(i32 %n) {
334; CHECK-LABEL: @init_const(
335; CHECK-NEXT:  entry:
336; CHECK-NEXT:    br label [[LOOP:%.*]]
337; CHECK:       loop:
338; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
339; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
340; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
341; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
342; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
343; CHECK:       exit:
344; CHECK-NEXT:    ret void
345;
346entry:
347  br label %loop
348
349loop:
350  %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
351  %i.next = add nuw nsw i32 %i, 1
352  %i.next.fr = freeze i32 %i.next
353  call void @call(i32 %i.next.fr)
354  %cond = icmp eq i32 %i.next.fr, %n
355  br i1 %cond, label %loop, label %exit
356
357exit:
358  ret void
359}
360
361define void @step_init_arg(i32 %init, i32 %n, i32 %step) {
362; CHECK-LABEL: @step_init_arg(
363; CHECK-NEXT:  entry:
364; CHECK-NEXT:    [[STEP_FROZEN:%.*]] = freeze i32 [[STEP:%.*]]
365; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]]
366; CHECK-NEXT:    br label [[LOOP:%.*]]
367; CHECK:       loop:
368; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
369; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], [[STEP_FROZEN]]
370; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
371; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
372; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
373; CHECK:       exit:
374; CHECK-NEXT:    ret void
375;
376entry:
377  br label %loop
378
379loop:
380  %i = phi i32 [%init, %entry], [%i.next, %loop]
381  %i.next = add nuw nsw i32 %i, %step
382  %i.next.fr = freeze i32 %i.next
383  call void @call(i32 %i.next.fr)
384  %cond = icmp eq i32 %i.next.fr, %n
385  br i1 %cond, label %loop, label %exit
386
387exit:
388  ret void
389}
390
391define void @step_init_arg_multiuses(i32 %init, i32 %n, i32 %step) {
392; CHECK-LABEL: @step_init_arg_multiuses(
393; CHECK-NEXT:  entry:
394; CHECK-NEXT:    [[STEP_FROZEN:%.*]] = freeze i32 [[STEP:%.*]]
395; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]]
396; CHECK-NEXT:    br label [[LOOP:%.*]]
397; CHECK:       loop:
398; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
399; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], [[STEP_FROZEN]]
400; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
401; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
402; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
403; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
404; CHECK:       exit:
405; CHECK-NEXT:    ret void
406;
407entry:
408  br label %loop
409
410loop:
411  %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
412  %i.next = add nsw nuw i32 %i, %step
413  %i.next.fr1 = freeze i32 %i.next
414  call void @call(i32 %i.next.fr1)
415  %i.next.fr2 = freeze i32 %i.next
416  call void @call(i32 %i.next.fr2)
417  %cond = icmp eq i32 %i.next, %n
418  br i1 %cond, label %loop, label %exit
419
420exit:
421  ret void
422}
423
424define void @step_init_arg_multiuses2(i32 %init, i32 %n, i32 %step) {
425; CHECK-LABEL: @step_init_arg_multiuses2(
426; CHECK-NEXT:  entry:
427; CHECK-NEXT:    [[STEP_FROZEN:%.*]] = freeze i32 [[STEP:%.*]]
428; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]]
429; CHECK-NEXT:    br label [[LOOP:%.*]]
430; CHECK:       loop:
431; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
432; CHECK-NEXT:    call void @call(i32 [[I]])
433; CHECK-NEXT:    call void @call(i32 [[I]])
434; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], [[STEP_FROZEN]]
435; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
436; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
437; CHECK:       exit:
438; CHECK-NEXT:    ret void
439;
440entry:
441  br label %loop
442
443loop:
444  %i = phi i32 [ %init, %entry ], [ %i.next, %loop ]
445  %i.fr1 = freeze i32 %i
446  call void @call(i32 %i.fr1)
447  %i.fr2 = freeze i32 %i
448  call void @call(i32 %i.fr2)
449  %i.next = add nsw nuw i32 %i, %step
450  %cond = icmp eq i32 %i.next, %n
451  br i1 %cond, label %loop, label %exit
452
453exit:
454  ret void
455}
456
457define void @step_init_inst(i32 %n) {
458; CHECK-LABEL: @step_init_inst(
459; CHECK-NEXT:  entry:
460; CHECK-NEXT:    [[STEP:%.*]] = call i32 @get_step()
461; CHECK-NEXT:    [[INIT:%.*]] = call i32 @get_step()
462; CHECK-NEXT:    [[STEP_FROZEN:%.*]] = freeze i32 [[STEP]]
463; CHECK-NEXT:    [[INIT_FROZEN:%.*]] = freeze i32 [[INIT]]
464; CHECK-NEXT:    br label [[LOOP:%.*]]
465; CHECK:       loop:
466; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
467; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], [[STEP_FROZEN]]
468; CHECK-NEXT:    call void @call(i32 [[I_NEXT]])
469; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]]
470; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
471; CHECK:       exit:
472; CHECK-NEXT:    ret void
473;
474entry:
475  %step = call i32 @get_step()
476  %init = call i32 @get_step()
477  br label %loop
478
479loop:
480  %i = phi i32 [%init, %entry], [%i.next, %loop]
481  %i.next = add nuw nsw i32 %i, %step
482  %i.next.fr = freeze i32 %i.next
483  call void @call(i32 %i.next.fr)
484  %cond = icmp eq i32 %i.next.fr, %n
485  br i1 %cond, label %loop, label %exit
486
487exit:
488  ret void
489}
490
491; Negative test
492define void @step_inst(i32 %init, i32 %n) {
493; CHECK-LABEL: @step_inst(
494; CHECK-NEXT:  entry:
495; CHECK-NEXT:    br label [[LOOP:%.*]]
496; CHECK:       loop:
497; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
498; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], [[I]]
499; CHECK-NEXT:    [[I_NEXT_FR:%.*]] = freeze i32 [[I_NEXT]]
500; CHECK-NEXT:    call void @call(i32 [[I_NEXT_FR]])
501; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[I_NEXT_FR]], [[N:%.*]]
502; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
503; CHECK:       exit:
504; CHECK-NEXT:    ret void
505;
506entry:
507  br label %loop
508
509loop:
510  %i = phi i32 [%init, %entry], [%i.next, %loop]
511  %i.next = add nuw nsw i32 %i, %i
512  %i.next.fr = freeze i32 %i.next
513  call void @call(i32 %i.next.fr)
514  %cond = icmp eq i32 %i.next.fr, %n
515  br i1 %cond, label %loop, label %exit
516
517exit:
518  ret void
519}
520
521; Negative test
522define void @gep(i8* %init, i8* %end) {
523; CHECK-LABEL: @gep(
524; CHECK-NEXT:  entry:
525; CHECK-NEXT:    br label [[LOOP:%.*]]
526; CHECK:       loop:
527; CHECK-NEXT:    [[I:%.*]] = phi i8* [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
528; CHECK-NEXT:    [[I_NEXT]] = getelementptr inbounds i8, i8* [[I]], i64 1
529; CHECK-NEXT:    [[I_NEXT_FR:%.*]] = freeze i8* [[I_NEXT]]
530; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8* [[I_NEXT_FR]], [[END:%.*]]
531; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
532; CHECK:       exit:
533; CHECK-NEXT:    ret void
534;
535entry:
536  br label %loop
537
538loop:
539  %i = phi i8* [ %init, %entry], [%i.next, %loop ]
540  %i.next = getelementptr inbounds i8, i8* %i, i64 1
541  %i.next.fr = freeze i8* %i.next
542  %cond = icmp eq i8* %i.next.fr, %end
543  br i1 %cond, label %loop, label %exit
544
545exit:
546  ret void
547}
548