• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; 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
276!1 = !{i64 -1, i64 100}
277
278
279declare void @foo()
280