[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / IndVarSimplify / loop-invariant-conditions.ll
blob320f0b30cb98d5286e89e65d991988e9109f585f
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) {
6 ; CHECK-LABEL: @test1
7 entry:
8   br label %loop
10 loop:
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
18   ret void
21 define void @test2(i64 %start) {
22 ; CHECK-LABEL: @test2
23 entry:
24   br label %loop
26 loop:
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
34   ret void
37 ; As long as the test dominates the backedge, we're good
38 define void @test3(i64 %start) {
39 ; CHECK-LABEL: @test3
40 entry:
41   br label %loop
43 loop:
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
49 backedge:
50   ; prevent flattening, needed to make sure we're testing what we intend
51   call void @foo() 
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
57   ret void
60 define void @test4(i64 %start) {
61 ; CHECK-LABEL: @test4
62 entry:
63   br label %loop
65 loop:
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
71 backedge:
72   ; prevent flattening, needed to make sure we're testing what we intend
73   call void @foo() 
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
79   ret void
82 define void @test5(i64 %start) {
83 ; CHECK-LABEL: @test5
84 entry:
85   br label %loop
87 loop:
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
93 backedge:
94   ; prevent flattening, needed to make sure we're testing what we intend
95   call void @foo() 
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
101   ret void
104 define void @test6(i64 %start) {
105 ; CHECK-LABEL: @test6
106 entry:
107   br label %loop
109 loop:
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
115 backedge:
116   ; prevent flattening, needed to make sure we're testing what we intend
117   call void @foo() 
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
123   ret void
126 define void @test7(i64 %start, i64* %inc_ptr) {
127 ; CHECK-LABEL: @test7
128 entry:
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
133 loop:
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
141   ret void
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
148 entry:
149   br label %loop
151 loop:
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
156 skip:
157   ; prevent flattening, needed to make sure we're testing what we intend
158   call void @foo() 
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
162 backedge:
163   ; prevent flattening, needed to make sure we're testing what we intend
164   call void @foo() 
165   br label %loop
167 for.end:                                          ; preds = %if.end, %entry
168   ret void
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
175 entry:
176   br label %loop
178 loop:
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
185 skip:
186   ; prevent flattening, needed to make sure we're testing what we intend
187   call void @foo() 
188   br i1 %cmp1, label %for.end, label %backedge
189 backedge:
190   ; prevent flattening, needed to make sure we're testing what we intend
191   call void @foo() 
192   br label %loop
194 for.end:                                          ; preds = %if.end, %entry
195   ret void
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
201 entry:
202   br label %loop
204 loop:
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
212   ret void
215 define void @test4_neg(i64 %start) {
216 ; CHECK-LABEL: @test4_neg
217 entry:
218   br label %loop
220 loop:
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
226 backedge:
227   ; prevent flattening, needed to make sure we're testing what we intend
228   call void @foo() 
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
237   ret void
240 define void @test5_neg(i64 %start, i64 %inc) {
241 ; CHECK-LABEL: @test5_neg
242 entry:
243   br label %loop
245 loop:
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
253   ret void
256 define void @test8(i64 %start, i64* %inc_ptr) {
257 ; CHECK-LABEL: @test8
258 entry:
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
263 loop:
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
271   ret void
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:
279 entry:
280   br i1 %cnd, label %entry1, label %entry2
281 entry1:
282   br label %loop
283 entry2:
284   br label %loop
285 loop:
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
293   ret void
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
304 entry:
305   br label %loop
307 loop:
308   %phi1 = phi i32 [ %phi2, %latch ], [ 0, %entry ]
309   %dec = add i32 %phi1, -1
310   br i1 false, label %left, label %right
312 left:
313   br label %latch
315 right:
316   br label %latch
318 latch:
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
324 exit:
325   call void @use(i1 %cmp)
326   ret void
329 ; check that we can figure out that iv.next > 1 from the facts that iv >= 0 and
330 ; iv.start != 0.
331 define void @test11(i64* %inc_ptr) {
332 ; CHECK-LABEL: @test11
333 entry:
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
338 loop:
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
345 if.true:
346   br label %backedge
348 if.false:
349   br label %backedge
351 backedge:
352   %loopcond = icmp slt i64 %iv, 200
353   br i1 %loopcond, label %loop, label %exit
355 exit:
356   ret void
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
363 entry:
364   %inc = load i64, i64* %inc_ptr, !range !0
365   %inc.minus.1 = sub i64 %inc, 1
366   br label %loop
368 loop:
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
377 if.true:
378   br label %backedge
380 if.false:
381   br label %backedge
383 backedge:
384   %loopcond = icmp slt i64 %iv, 200
385   br i1 %loopcond, label %loop, label %exit
387 exit:
388   ret void
391 !0 = !{i64 0, i64 100}
392 !1 = !{i64 -1, i64 100}
394 declare void @foo()