blob: 70cf714ba9f2a8a1cea23cdbcd51d9bdf9e683a4 [file] [log] [blame]
Sanjoy Das5dab2052015-07-27 21:42:49 +00001; RUN: opt -S -indvars %s | FileCheck %s
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3target triple = "x86_64-unknown-linux-gnu"
4
5define void @test1(i64 %start) {
6; CHECK-LABEL: @test1
7entry:
8 br label %loop
9
10loop:
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
16
17for.end: ; preds = %if.end, %entry
18 ret void
19}
20
21define void @test2(i64 %start) {
22; CHECK-LABEL: @test2
23entry:
24 br label %loop
25
26loop:
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
32
33for.end: ; preds = %if.end, %entry
34 ret void
35}
36
37; As long as the test dominates the backedge, we're good
38define void @test3(i64 %start) {
39; CHECK-LABEL: @test3
40entry:
41 br label %loop
42
43loop:
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
48
49backedge:
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
55
56for.end: ; preds = %if.end, %entry
57 ret void
58}
59
60define void @test4(i64 %start) {
61; CHECK-LABEL: @test4
62entry:
63 br label %loop
64
65loop:
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
70
71backedge:
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
77
78for.end: ; preds = %if.end, %entry
79 ret void
80}
81
82define void @test5(i64 %start) {
83; CHECK-LABEL: @test5
84entry:
85 br label %loop
86
87loop:
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
92
93backedge:
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
99
100for.end: ; preds = %if.end, %entry
101 ret void
102}
103
104define void @test6(i64 %start) {
105; CHECK-LABEL: @test6
106entry:
107 br label %loop
108
109loop:
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
114
115backedge:
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
121
122for.end: ; preds = %if.end, %entry
123 ret void
124}
125
126define void @test7(i64 %start, i64* %inc_ptr) {
127; CHECK-LABEL: @test7
128entry:
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
132
133loop:
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
139
140for.end: ; preds = %if.end, %entry
141 ret void
142}
143
144!0 = !{i64 0, i64 100}
145
146; Negative test - we can't show that the internal branch executes, so we can't
147; fold the test to a loop invariant one.
148define void @test1_neg(i64 %start) {
149; CHECK-LABEL: @test1_neg
150entry:
151 br label %loop
152
153loop:
154 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
155 %indvars.iv.next = add nsw i64 %indvars.iv, 1
156 %cmp = icmp eq i64 %indvars.iv.next, 25
157 br i1 %cmp, label %backedge, label %skip
158skip:
159 ; prevent flattening, needed to make sure we're testing what we intend
160 call void @foo()
161; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
162 %cmp1 = icmp slt i64 %indvars.iv, -1
163 br i1 %cmp1, label %for.end, label %backedge
164backedge:
165 ; prevent flattening, needed to make sure we're testing what we intend
166 call void @foo()
167 br label %loop
168
169for.end: ; preds = %if.end, %entry
170 ret void
171}
172
173; Slightly subtle version of @test4 where the icmp dominates the backedge,
174; but the exit branch doesn't.
175define void @test2_neg(i64 %start) {
176; CHECK-LABEL: @test2_neg
177entry:
178 br label %loop
179
180loop:
181 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
182 %indvars.iv.next = add nsw i64 %indvars.iv, 1
183 %cmp = icmp eq i64 %indvars.iv.next, 25
184; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
185 %cmp1 = icmp slt i64 %indvars.iv, -1
186 br i1 %cmp, label %backedge, label %skip
187skip:
188 ; prevent flattening, needed to make sure we're testing what we intend
189 call void @foo()
190 br i1 %cmp1, label %for.end, label %backedge
191backedge:
192 ; prevent flattening, needed to make sure we're testing what we intend
193 call void @foo()
194 br label %loop
195
196for.end: ; preds = %if.end, %entry
197 ret void
198}
199
200; The branch has to exit the loop if the condition is true
201define void @test3_neg(i64 %start) {
202; CHECK-LABEL: @test3_neg
203entry:
204 br label %loop
205
206loop:
207 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
208 %indvars.iv.next = add nsw i64 %indvars.iv, 1
209; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
210 %cmp1 = icmp slt i64 %indvars.iv, -1
211 br i1 %cmp1, label %loop, label %for.end
212
213for.end: ; preds = %if.end, %entry
214 ret void
215}
216
217define void @test4_neg(i64 %start) {
218; CHECK-LABEL: @test4_neg
219entry:
220 br label %loop
221
222loop:
223 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
224 %indvars.iv.next = add nsw i64 %indvars.iv, 1
225 %cmp = icmp eq i64 %indvars.iv.next, 25
226 br i1 %cmp, label %backedge, label %for.end
227
228backedge:
229 ; prevent flattening, needed to make sure we're testing what we intend
230 call void @foo()
231; CHECK: %cmp1 = icmp sgt i64 %indvars.iv, -1
232 %cmp1 = icmp sgt i64 %indvars.iv, -1
233
234; %cmp1 can be made loop invariant only if the branch below goes to
235; %the header when %cmp1 is true.
236 br i1 %cmp1, label %for.end, label %loop
237
238for.end: ; preds = %if.end, %entry
239 ret void
240}
241
242define void @test5_neg(i64 %start, i64 %inc) {
243; CHECK-LABEL: @test5_neg
244entry:
245 br label %loop
246
247loop:
248 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
249 %indvars.iv.next = add nsw i64 %indvars.iv, %inc
250; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
251 %cmp1 = icmp slt i64 %indvars.iv, -1
252 br i1 %cmp1, label %for.end, label %loop
253
254for.end: ; preds = %if.end, %entry
255 ret void
256}
257
258define void @test8(i64 %start, i64* %inc_ptr) {
259; CHECK-LABEL: @test8
260entry:
261 %inc = load i64, i64* %inc_ptr, !range !1
262 %ok = icmp sge i64 %inc, 0
263 br i1 %ok, label %loop, label %for.end
264
265loop:
266 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
267 %indvars.iv.next = add nsw i64 %indvars.iv, %inc
268; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
269 %cmp1 = icmp slt i64 %indvars.iv, -1
270 br i1 %cmp1, label %for.end, label %loop
271
272for.end: ; preds = %if.end, %entry
273 ret void
274}
275
Philip Reames59bf1e02017-10-31 05:16:46 +0000276; check to handle loops without preheaders, but invariant operands
277; (we handle this today by inserting a preheader)
278define void @test9(i1 %cnd, i64 %start) {
279; CHECK-LABEL: @test9
280; CHECK-LABEL: loop.preheader:
281entry:
282 br i1 %cnd, label %entry1, label %entry2
283entry1:
284 br label %loop
285entry2:
286 br label %loop
287loop:
288 %indvars.iv = phi i64 [ %start, %entry1 ],[ %start, %entry2 ], [ %indvars.iv.next, %loop ]
289 %indvars.iv.next = add nsw i64 %indvars.iv, 1
290; CHECK: %cmp1 = icmp slt i64 %start, -1
291 %cmp1 = icmp slt i64 %indvars.iv, -1
292 br i1 %cmp1, label %for.end, label %loop
293
294for.end: ; preds = %if.end, %entry
295 ret void
296}
297
Philip Reames6260cf72017-12-01 20:57:19 +0000298; 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
302define void @test10() {
303; CHECK-LABEL: @test10
304entry:
305 br label %loop
306
307loop:
308 %phi1 = phi i32 [ %phi2, %latch ], [ 0, %entry ]
309 %dec = add i32 %phi1, -1
310 br i1 false, label %left, label %right
311
312left:
313 br label %latch
314
315right:
316 br label %latch
317
318latch:
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
323
324exit:
325 ret void
326}
327
Sanjoy Das5dab2052015-07-27 21:42:49 +0000328!1 = !{i64 -1, i64 100}
329
330
331declare void @foo()