1 ; RUN: opt -S -indvars %s | FileCheck %s
2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3 target triple = "x86_64-unknown-linux-gnu"
5 define void @test1(i64 %start) {
11 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
12 %indvars.iv.next = add nsw i64 %indvars.iv, 1
13 ; CHECK: %cmp1 = icmp slt i64 %start, -1
14 %cmp1 = icmp slt i64 %indvars.iv, -1
15 br i1 %cmp1, label %for.end, label %loop
17 for.end: ; preds = %if.end, %entry
21 define void @test2(i64 %start) {
27 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
28 %indvars.iv.next = add nsw i64 %indvars.iv, 1
29 ; CHECK: %cmp1 = icmp sle i64 %start, -1
30 %cmp1 = icmp sle i64 %indvars.iv, -1
31 br i1 %cmp1, label %for.end, label %loop
33 for.end: ; preds = %if.end, %entry
37 ; As long as the test dominates the backedge, we're good
38 define void @test3(i64 %start) {
44 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
45 %indvars.iv.next = add nsw i64 %indvars.iv, 1
46 %cmp = icmp eq i64 %indvars.iv.next, 25
47 br i1 %cmp, label %backedge, label %for.end
50 ; prevent flattening, needed to make sure we're testing what we intend
52 ; CHECK: %cmp1 = icmp slt i64 %start, -1
53 %cmp1 = icmp slt i64 %indvars.iv, -1
54 br i1 %cmp1, label %for.end, label %loop
56 for.end: ; preds = %if.end, %entry
60 define void @test4(i64 %start) {
66 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
67 %indvars.iv.next = add nsw i64 %indvars.iv, 1
68 %cmp = icmp eq i64 %indvars.iv.next, 25
69 br i1 %cmp, label %backedge, label %for.end
72 ; prevent flattening, needed to make sure we're testing what we intend
74 ; CHECK: %cmp1 = icmp sgt i64 %start, -1
75 %cmp1 = icmp sgt i64 %indvars.iv, -1
76 br i1 %cmp1, label %loop, label %for.end
78 for.end: ; preds = %if.end, %entry
82 define void @test5(i64 %start) {
88 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
89 %indvars.iv.next = add nuw i64 %indvars.iv, 1
90 %cmp = icmp eq i64 %indvars.iv.next, 25
91 br i1 %cmp, label %backedge, label %for.end
94 ; prevent flattening, needed to make sure we're testing what we intend
96 ; CHECK: %cmp1 = icmp ugt i64 %start, 100
97 %cmp1 = icmp ugt i64 %indvars.iv, 100
98 br i1 %cmp1, label %loop, label %for.end
100 for.end: ; preds = %if.end, %entry
104 define void @test6(i64 %start) {
105 ; CHECK-LABEL: @test6
110 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
111 %indvars.iv.next = add nuw i64 %indvars.iv, 1
112 %cmp = icmp eq i64 %indvars.iv.next, 25
113 br i1 %cmp, label %backedge, label %for.end
116 ; prevent flattening, needed to make sure we're testing what we intend
118 ; CHECK: %cmp1 = icmp ult i64 %start, 100
119 %cmp1 = icmp ult i64 %indvars.iv, 100
120 br i1 %cmp1, label %for.end, label %loop
122 for.end: ; preds = %if.end, %entry
126 define void @test7(i64 %start, i64* %inc_ptr) {
127 ; CHECK-LABEL: @test7
129 %inc = load i64, i64* %inc_ptr, !range !0
130 %ok = icmp sge i64 %inc, 0
131 br i1 %ok, label %loop, label %for.end
134 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
135 %indvars.iv.next = add nsw i64 %indvars.iv, %inc
136 ; CHECK: %cmp1 = icmp slt i64 %start, -1
137 %cmp1 = icmp slt i64 %indvars.iv, -1
138 br i1 %cmp1, label %for.end, label %loop
140 for.end: ; preds = %if.end, %entry
144 ; Negative test - we can't show that the internal branch executes, so we can't
145 ; fold the test to a loop invariant one.
146 define void @test1_neg(i64 %start) {
147 ; CHECK-LABEL: @test1_neg
152 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
153 %indvars.iv.next = add nsw i64 %indvars.iv, 1
154 %cmp = icmp eq i64 %indvars.iv.next, 25
155 br i1 %cmp, label %backedge, label %skip
157 ; prevent flattening, needed to make sure we're testing what we intend
159 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
160 %cmp1 = icmp slt i64 %indvars.iv, -1
161 br i1 %cmp1, label %for.end, label %backedge
163 ; prevent flattening, needed to make sure we're testing what we intend
167 for.end: ; preds = %if.end, %entry
171 ; Slightly subtle version of @test4 where the icmp dominates the backedge,
172 ; but the exit branch doesn't.
173 define void @test2_neg(i64 %start) {
174 ; CHECK-LABEL: @test2_neg
179 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
180 %indvars.iv.next = add nsw i64 %indvars.iv, 1
181 %cmp = icmp eq i64 %indvars.iv.next, 25
182 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
183 %cmp1 = icmp slt i64 %indvars.iv, -1
184 br i1 %cmp, label %backedge, label %skip
186 ; prevent flattening, needed to make sure we're testing what we intend
188 br i1 %cmp1, label %for.end, label %backedge
190 ; prevent flattening, needed to make sure we're testing what we intend
194 for.end: ; preds = %if.end, %entry
198 ; The branch has to exit the loop if the condition is true
199 define void @test3_neg(i64 %start) {
200 ; CHECK-LABEL: @test3_neg
205 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
206 %indvars.iv.next = add nsw i64 %indvars.iv, 1
207 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
208 %cmp1 = icmp slt i64 %indvars.iv, -1
209 br i1 %cmp1, label %loop, label %for.end
211 for.end: ; preds = %if.end, %entry
215 define void @test4_neg(i64 %start) {
216 ; CHECK-LABEL: @test4_neg
221 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
222 %indvars.iv.next = add nsw i64 %indvars.iv, 1
223 %cmp = icmp eq i64 %indvars.iv.next, 25
224 br i1 %cmp, label %backedge, label %for.end
227 ; prevent flattening, needed to make sure we're testing what we intend
229 ; CHECK: %cmp1 = icmp sgt i64 %indvars.iv, -1
230 %cmp1 = icmp sgt i64 %indvars.iv, -1
232 ; %cmp1 can be made loop invariant only if the branch below goes to
233 ; %the header when %cmp1 is true.
234 br i1 %cmp1, label %for.end, label %loop
236 for.end: ; preds = %if.end, %entry
240 define void @test5_neg(i64 %start, i64 %inc) {
241 ; CHECK-LABEL: @test5_neg
246 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
247 %indvars.iv.next = add nsw i64 %indvars.iv, %inc
248 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
249 %cmp1 = icmp slt i64 %indvars.iv, -1
250 br i1 %cmp1, label %for.end, label %loop
252 for.end: ; preds = %if.end, %entry
256 define void @test8(i64 %start, i64* %inc_ptr) {
257 ; CHECK-LABEL: @test8
259 %inc = load i64, i64* %inc_ptr, !range !1
260 %ok = icmp sge i64 %inc, 0
261 br i1 %ok, label %loop, label %for.end
264 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
265 %indvars.iv.next = add nsw i64 %indvars.iv, %inc
266 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
267 %cmp1 = icmp slt i64 %indvars.iv, -1
268 br i1 %cmp1, label %for.end, label %loop
270 for.end: ; preds = %if.end, %entry
274 ; check to handle loops without preheaders, but invariant operands
275 ; (we handle this today by inserting a preheader)
276 define void @test9(i1 %cnd, i64 %start) {
277 ; CHECK-LABEL: @test9
278 ; CHECK-LABEL: loop.preheader:
280 br i1 %cnd, label %entry1, label %entry2
286 %indvars.iv = phi i64 [ %start, %entry1 ],[ %start, %entry2 ], [ %indvars.iv.next, %loop ]
287 %indvars.iv.next = add nsw i64 %indvars.iv, 1
288 ; CHECK: %cmp1 = icmp slt i64 %start, -1
289 %cmp1 = icmp slt i64 %indvars.iv, -1
290 br i1 %cmp1, label %for.end, label %loop
292 for.end: ; preds = %if.end, %entry
296 declare void @use(i1 %x)
298 ; check that we handle conditions with loop invariant operands which
299 ; *aren't* in the header - this is a very rare and fragile case where
300 ; we have a "loop" which is known to run exactly one iteration but
301 ; haven't yet simplified the uses of the IV
302 define void @test10() {
303 ; CHECK-LABEL: @test10
308 %phi1 = phi i32 [ %phi2, %latch ], [ 0, %entry ]
309 %dec = add i32 %phi1, -1
310 br i1 false, label %left, label %right
319 %phi2 = phi i32 [ %phi1, %left ], [ %dec, %right ]
320 ; CHECK: %cmp = icmp slt i32 -1, undef
321 %cmp = icmp slt i32 %phi2, undef
322 br i1 true, label %exit, label %loop
325 call void @use(i1 %cmp)
329 ; check that we can figure out that iv.next > 1 from the facts that iv >= 0 and
331 define void @test11(i64* %inc_ptr) {
332 ; CHECK-LABEL: @test11
334 %inc = load i64, i64* %inc_ptr, !range !0
335 %ne.cond = icmp ne i64 %inc, 0
336 br i1 %ne.cond, label %loop, label %exit
339 %iv = phi i64 [ %inc, %entry ], [ %iv.next, %backedge ]
340 %iv.next = add i64 %iv, 1
341 %brcond = icmp sgt i64 %iv.next, 1
342 ; CHECK: br i1 true, label %if.true, label %if.false
343 br i1 %brcond, label %if.true, label %if.false
352 %loopcond = icmp slt i64 %iv, 200
353 br i1 %loopcond, label %loop, label %exit
359 ; check that we can prove that a recurrency is greater than another recurrency
360 ; in the same loop, with the same step, and with smaller starting value.
361 define void @test12(i64* %inc_ptr) {
362 ; CHECK-LABEL: @test12
364 %inc = load i64, i64* %inc_ptr, !range !0
365 %inc.minus.1 = sub i64 %inc, 1
369 %iv = phi i64 [ %inc, %entry ], [ %iv.next, %backedge ]
370 %iv.minus.1 = phi i64 [ %inc.minus.1, %entry ], [ %iv.minus.1.next, %backedge ]
371 %iv.next = add i64 %iv, 1
372 %iv.minus.1.next = add i64 %iv.minus.1, 1
373 %brcond = icmp sgt i64 %iv.next, %iv.minus.1.next
374 ; CHECK: br i1 true, label %if.true, label %if.false
375 br i1 %brcond, label %if.true, label %if.false
384 %loopcond = icmp slt i64 %iv, 200
385 br i1 %loopcond, label %loop, label %exit
391 !0 = !{i64 0, i64 100}
392 !1 = !{i64 -1, i64 100}