1 ; RUN: opt -hardware-loops -force-hardware-loops=true -hardware-loop-decrement=1 -hardware-loop-counter-bitwidth=32 -force-hardware-loop-guard=true -S %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-EXIT
2 ; RUN: opt -hardware-loops -force-hardware-loops=true -hardware-loop-decrement=1 -hardware-loop-counter-bitwidth=32 -force-hardware-loop-guard=true -force-hardware-loop-phi=true -S %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LATCH
3 ; RUN: opt -hardware-loops -force-hardware-loops=true -hardware-loop-decrement=1 -hardware-loop-counter-bitwidth=32 -force-hardware-loop-guard=false -S %s -o - | FileCheck %s --check-prefix=NO-GUARD
5 ; NO-GUARD-NOT: @llvm.test.set.loop.iterations
9 ; CHECK: [[CMP:%[^ ]+]] = icmp ugt i32 %N, 2
10 ; CHECK: [[MAX:%[^ ]+]] = select i1 [[CMP]], i32 %N, i32 2
11 ; CHECK: [[COUNT:%[^ ]+]] = add i32 [[MAX]], -1
12 ; CHECK: br i1 %t1, label %do.body.preheader
13 ; CHECK: do.body.preheader:
14 ; CHECK: call void @llvm.set.loop.iterations.i32(i32 [[COUNT]])
15 ; CHECK: br label %do.body
16 define void @test1(i1 zeroext %t1, i32* nocapture %a, i32* nocapture readonly %b, i32 %N) {
18 br i1 %t1, label %do.body, label %if.end
20 do.body: ; preds = %do.body, %entry
21 %b.addr.0 = phi i32* [ %incdec.ptr, %do.body ], [ %b, %entry ]
22 %a.addr.0 = phi i32* [ %incdec.ptr1, %do.body ], [ %a, %entry ]
23 %i.0 = phi i32 [ %inc, %do.body ], [ 1, %entry ]
24 %incdec.ptr = getelementptr inbounds i32, i32* %b.addr.0, i32 1
25 %tmp = load i32, i32* %b.addr.0, align 4
26 %incdec.ptr1 = getelementptr inbounds i32, i32* %a.addr.0, i32 1
27 store i32 %tmp, i32* %a.addr.0, align 4
28 %inc = add nuw i32 %i.0, 1
29 %cmp = icmp ult i32 %inc, %N
30 br i1 %cmp, label %do.body, label %if.end
32 if.end: ; preds = %do.body, %entry
37 ; CHECK-NOT: call i1 @llvm.test.set.loop.iterations
38 ; CHECK-NOT: call void @llvm.set.loop.iterations
39 define void @test2(i1 zeroext %t1, i32* nocapture %a, i32* nocapture readonly %b, i32 %N) {
41 br i1 %t1, label %do.body, label %if.end
43 do.body: ; preds = %do.body, %entry
44 %b.addr.0 = phi i32* [ %incdec.ptr, %do.body ], [ %b, %entry ]
45 %a.addr.0 = phi i32* [ %incdec.ptr1, %do.body ], [ %a, %entry ]
46 %i.0 = phi i32 [ %add, %do.body ], [ 1, %entry ]
47 %incdec.ptr = getelementptr inbounds i32, i32* %b.addr.0, i32 1
48 %tmp = load i32, i32* %b.addr.0, align 4
49 %incdec.ptr1 = getelementptr inbounds i32, i32* %a.addr.0, i32 1
50 store i32 %tmp, i32* %a.addr.0, align 4
51 %add = add i32 %i.0, 2
52 %cmp = icmp ult i32 %add, %N
53 br i1 %cmp, label %do.body, label %if.end
55 if.end: ; preds = %do.body, %entry
61 ; CHECK: [[CMP:%[^ ]+]] = icmp ugt i32 %N, 1
62 ; CHECK: [[COUNT:%[^ ]+]] = select i1 [[CMP]], i32 %N, i32 1
63 ; CHECK: br i1 %brmerge.demorgan, label %do.body.preheader
64 ; CHECK: do.body.preheader:
65 ; CHECK: call void @llvm.set.loop.iterations.i32(i32 [[COUNT]])
66 ; CHECK: br label %do.body
67 define void @test3(i1 zeroext %t1, i1 zeroext %t2, i32* nocapture %a, i32* nocapture readonly %b, i32 %N) {
69 %brmerge.demorgan = and i1 %t1, %t2
70 br i1 %brmerge.demorgan, label %do.body, label %if.end
72 do.body: ; preds = %do.body, %entry
73 %b.addr.0 = phi i32* [ %incdec.ptr, %do.body ], [ %b, %entry ]
74 %a.addr.0 = phi i32* [ %incdec.ptr3, %do.body ], [ %a, %entry ]
75 %i.0 = phi i32 [ %inc, %do.body ], [ 0, %entry ]
76 %incdec.ptr = getelementptr inbounds i32, i32* %b.addr.0, i32 1
77 %tmp = load i32, i32* %b.addr.0, align 4
78 %incdec.ptr3 = getelementptr inbounds i32, i32* %a.addr.0, i32 1
79 store i32 %tmp, i32* %a.addr.0, align 4
80 %inc = add nuw i32 %i.0, 1
81 %cmp = icmp ult i32 %inc, %N
82 br i1 %cmp, label %do.body, label %if.end
84 if.end: ; preds = %do.body, %entry
90 ; CHECK-LATCH: br i1 %brmerge.demorgan, label %while.cond
91 ; CHECK-LATCH-NOT: call void @llvm{{.*}}loop.iterations
92 ; CHECK-EXIT: br i1 %brmerge.demorgan, label %while.cond.preheader
93 ; CHECK-EXIT: while.cond.preheader:
94 ; CHECK-EXIT: [[COUNT:%[^ ]+]] = add i32 %N, 1
95 ; CHECK-EXIT: call void @llvm.set.loop.iterations.i32(i32 [[COUNT]])
96 ; CHECK-EXIT: br label %while.cond
97 define void @test4(i1 zeroext %t1, i1 zeroext %t2, i32* nocapture %a, i32* nocapture readonly %b, i32 %N) {
99 %brmerge.demorgan = and i1 %t1, %t2
100 br i1 %brmerge.demorgan, label %while.cond, label %if.end
102 while.cond: ; preds = %while.body, %entry
103 %b.addr.0 = phi i32* [ %incdec.ptr, %while.body ], [ %b, %entry ]
104 %a.addr.0 = phi i32* [ %incdec.ptr3, %while.body ], [ %a, %entry ]
105 %i.0 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
106 %exitcond = icmp eq i32 %i.0, %N
107 br i1 %exitcond, label %if.end, label %while.body
109 while.body: ; preds = %while.cond
110 %incdec.ptr = getelementptr inbounds i32, i32* %b.addr.0, i32 1
111 %tmp = load i32, i32* %b.addr.0, align 4
112 %incdec.ptr3 = getelementptr inbounds i32, i32* %a.addr.0, i32 1
113 store i32 %tmp, i32* %a.addr.0, align 4
114 %inc = add i32 %i.0, 1
117 if.end: ; preds = %while.cond, %entry
123 ; CHECK: br i1 %or.cond, label %while.body.preheader
124 ; CHECK: while.body.preheader:
125 ; CHECK: call void @llvm.set.loop.iterations.i32(i32 %N)
126 ; CHECK: br label %while.body
127 define void @test5(i1 zeroext %t1, i1 zeroext %t2, i32* nocapture %a, i32* nocapture readonly %b, i32 %N) {
129 %brmerge.demorgan = and i1 %t1, %t2
130 %cmp6 = icmp ne i32 %N, 0
131 %or.cond = and i1 %brmerge.demorgan, %cmp6
132 br i1 %or.cond, label %while.body, label %if.end
134 while.body: ; preds = %while.body, %entry
135 %i.09 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
136 %a.addr.08 = phi i32* [ %incdec.ptr3, %while.body ], [ %a, %entry ]
137 %b.addr.07 = phi i32* [ %incdec.ptr, %while.body ], [ %b, %entry ]
138 %incdec.ptr = getelementptr inbounds i32, i32* %b.addr.07, i32 1
139 %tmp = load i32, i32* %b.addr.07, align 4
140 %incdec.ptr3 = getelementptr inbounds i32, i32* %a.addr.08, i32 1
141 store i32 %tmp, i32* %a.addr.08, align 4
142 %inc = add nuw i32 %i.09, 1
143 %exitcond = icmp eq i32 %inc, %N
144 br i1 %exitcond, label %if.end, label %while.body
146 if.end: ; preds = %while.body, %entry
152 ; CHECK: br i1 %brmerge.demorgan, label %while.preheader
153 ; CHECK: while.preheader:
154 ; CHECK: [[TEST:%[^ ]+]] = call i1 @llvm.test.set.loop.iterations.i32(i32 %N)
155 ; CHECK: br i1 [[TEST]], label %while.body.preheader, label %if.end
156 ; CHECK: while.body.preheader:
157 ; CHECK: br label %while.body
158 define void @test6(i1 zeroext %t1, i1 zeroext %t2, i32* nocapture %a, i32* nocapture readonly %b, i32 %N) {
160 %brmerge.demorgan = and i1 %t1, %t2
161 br i1 %brmerge.demorgan, label %while.preheader, label %if.end
163 while.preheader: ; preds = %entry
164 %cmp = icmp ne i32 %N, 0
165 br i1 %cmp, label %while.body, label %if.end
167 while.body: ; preds = %while.body, %while.preheader
168 %i.09 = phi i32 [ %inc, %while.body ], [ 0, %while.preheader ]
169 %a.addr.08 = phi i32* [ %incdec.ptr3, %while.body ], [ %a, %while.preheader ]
170 %b.addr.07 = phi i32* [ %incdec.ptr, %while.body ], [ %b, %while.preheader ]
171 %incdec.ptr = getelementptr inbounds i32, i32* %b.addr.07, i32 1
172 %tmp = load i32, i32* %b.addr.07, align 4
173 %incdec.ptr3 = getelementptr inbounds i32, i32* %a.addr.08, i32 1
174 store i32 %tmp, i32* %a.addr.08, align 4
175 %inc = add nuw i32 %i.09, 1
176 %exitcond = icmp eq i32 %inc, %N
177 br i1 %exitcond, label %if.end, label %while.body
179 if.end: ; preds = %while.body, %while.preheader, %entry
185 ; CHECK: br i1 %brmerge.demorgan, label %while.preheader
186 ; CHECK: while.preheader:
187 ; CHECK: [[TEST:%[^ ]+]] = call i1 @llvm.test.set.loop.iterations.i32(i32 %N)
188 ; CHECK: br i1 [[TEST]], label %while.body.preheader, label %if.end
189 ; CHECK: while.body.preheader:
190 ; CHECK: br label %while.body
191 define void @test7(i1 zeroext %t1, i1 zeroext %t2, i32* nocapture %a, i32* nocapture readonly %b, i32 %N) {
193 %brmerge.demorgan = and i1 %t1, %t2
194 br i1 %brmerge.demorgan, label %while.preheader, label %if.end
196 while.preheader: ; preds = %entry
197 %cmp = icmp eq i32 %N, 0
198 br i1 %cmp, label %if.end, label %while.body
200 while.body: ; preds = %while.body, %while.preheader
201 %i.09 = phi i32 [ %inc, %while.body ], [ 0, %while.preheader ]
202 %a.addr.08 = phi i32* [ %incdec.ptr3, %while.body ], [ %a, %while.preheader ]
203 %b.addr.07 = phi i32* [ %incdec.ptr, %while.body ], [ %b, %while.preheader ]
204 %incdec.ptr = getelementptr inbounds i32, i32* %b.addr.07, i32 1
205 %tmp = load i32, i32* %b.addr.07, align 4
206 %incdec.ptr3 = getelementptr inbounds i32, i32* %a.addr.08, i32 1
207 store i32 %tmp, i32* %a.addr.08, align 4
208 %inc = add nuw i32 %i.09, 1
209 %exitcond = icmp eq i32 %inc, %N
210 br i1 %exitcond, label %if.end, label %while.body
212 if.end: ; preds = %while.body, %while.preheader, %entry
216 ; TODO: Can we rearrange the conditional blocks so that we can use the test form?
219 ; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 %N, 0
220 ; CHECK: br i1 [[CMP]], label %while.preheader
221 ; CHECK: while.preheader:
222 ; CHECK: br i1 %brmerge.demorgan, label %while.body.preheader
223 ; CHECK: while.body.preheader:
224 ; CHECK: call void @llvm.set.loop.iterations.i32(i32 %N)
225 ; CHECK: br label %while.body
226 define void @test8(i1 zeroext %t1, i1 zeroext %t2, i32* nocapture %a, i32* nocapture readonly %b, i32 %N) {
228 %cmp = icmp ne i32 %N, 0
229 br i1 %cmp, label %while.preheader, label %if.end
231 while.preheader: ; preds = %entry
232 %brmerge.demorgan = and i1 %t1, %t2
233 br i1 %brmerge.demorgan, label %while.body, label %if.end
235 while.body: ; preds = %while.body, %while.preheader
236 %i.09 = phi i32 [ %inc, %while.body ], [ 0, %while.preheader ]
237 %a.addr.08 = phi i32* [ %incdec.ptr3, %while.body ], [ %a, %while.preheader ]
238 %b.addr.07 = phi i32* [ %incdec.ptr, %while.body ], [ %b, %while.preheader ]
239 %incdec.ptr = getelementptr inbounds i32, i32* %b.addr.07, i32 1
240 %tmp = load i32, i32* %b.addr.07, align 4
241 %incdec.ptr3 = getelementptr inbounds i32, i32* %a.addr.08, i32 1
242 store i32 %tmp, i32* %a.addr.08, align 4
243 %inc = add nuw i32 %i.09, 1
244 %exitcond = icmp eq i32 %inc, %N
245 br i1 %exitcond, label %if.end, label %while.body
247 if.end: ; preds = %while.body, %while.preheader, %entry
253 ; CHECK: br i1 %brmerge.demorgan, label %do.body.preheader
254 ; CHECK: do.body.preheader:
255 ; CHECK: call void @llvm.set.loop.iterations.i32(i32 %N)
256 ; CHECK: br label %do.body
257 define void @test9(i1 zeroext %t1, i32* nocapture %a, i32* nocapture readonly %b, i32 %N) {
259 %cmp = icmp ne i32 %N, 0
260 %brmerge.demorgan = and i1 %t1, %cmp
261 br i1 %brmerge.demorgan, label %do.body, label %if.end
263 do.body: ; preds = %do.body, %entry
264 %b.addr.0 = phi i32* [ %incdec.ptr, %do.body ], [ %b, %entry ]
265 %a.addr.0 = phi i32* [ %incdec.ptr3, %do.body ], [ %a, %entry ]
266 %i.0 = phi i32 [ %inc, %do.body ], [ 0, %entry ]
267 %incdec.ptr = getelementptr inbounds i32, i32* %b.addr.0, i32 1
268 %tmp = load i32, i32* %b.addr.0, align 4
269 %incdec.ptr3 = getelementptr inbounds i32, i32* %a.addr.0, i32 1
270 store i32 %tmp, i32* %a.addr.0, align 4
271 %inc = add nuw i32 %i.0, 1
272 %cmp.1 = icmp ult i32 %inc, %N
273 br i1 %cmp.1, label %do.body, label %if.end
275 if.end: ; preds = %do.body, %entry
279 ; CHECK-LABEL: test10
281 ; CHECK: br i1 %cmp.1, label %do.body.preheader
282 ; CHECK: do.body.preheader:
283 ; CHECK: call void @llvm.set.loop.iterations.i32(i32
284 ; CHECK: br label %do.body
285 define void @test10(i32* nocapture %a, i32* nocapture readonly %b, i32 %N) {
287 %cmp = icmp ne i32 %N, 0
289 %be = select i1 %cmp, i32 0, i32 %sub
290 %cmp.1 = icmp ne i32 %be, 0
291 br i1 %cmp.1, label %do.body, label %if.end
293 do.body: ; preds = %do.body, %entry
294 %b.addr.0 = phi i32* [ %incdec.ptr, %do.body ], [ %b, %entry ]
295 %a.addr.0 = phi i32* [ %incdec.ptr3, %do.body ], [ %a, %entry ]
296 %i.0 = phi i32 [ %inc, %do.body ], [ 0, %entry ]
297 %incdec.ptr = getelementptr inbounds i32, i32* %b.addr.0, i32 1
298 %tmp = load i32, i32* %b.addr.0, align 4
299 %incdec.ptr3 = getelementptr inbounds i32, i32* %a.addr.0, i32 1
300 store i32 %tmp, i32* %a.addr.0, align 4
301 %inc = add nuw i32 %i.0, 1
302 %cmp.2 = icmp ult i32 %inc, %N
303 br i1 %cmp.2, label %do.body, label %if.end
305 if.end: ; preds = %do.body, %entry
309 ; CHECK-LABEL: test11
311 ; CHECK: br label %do.body.preheader
312 ; CHECK: do.body.preheader:
313 ; CHECK: [[TEST:%[^ ]+]] = call i1 @llvm.test.set.loop.iterations.i32(i32 %N)
314 ; CHECK: br i1 [[TEST]], label %do.body.preheader1, label %if.end
315 ; CHECK: do.body.preheader1:
316 ; CHECK: br label %do.body
317 define void @test11(i1 zeroext %t1, i32* nocapture %a, i32* nocapture readonly %b, i32 %N) {
319 br label %do.body.preheader
322 %cmp = icmp ne i32 %N, 0
323 br i1 %cmp, label %do.body, label %if.end
326 %b.addr.0 = phi i32* [ %incdec.ptr, %do.body ], [ %b, %do.body.preheader ]
327 %a.addr.0 = phi i32* [ %incdec.ptr3, %do.body ], [ %a, %do.body.preheader ]
328 %i.0 = phi i32 [ %inc, %do.body ], [ 0, %do.body.preheader ]
329 %incdec.ptr = getelementptr inbounds i32, i32* %b.addr.0, i32 1
330 %tmp = load i32, i32* %b.addr.0, align 4
331 %incdec.ptr3 = getelementptr inbounds i32, i32* %a.addr.0, i32 1
332 store i32 %tmp, i32* %a.addr.0, align 4
333 %inc = add nuw i32 %i.0, 1
334 %cmp.1 = icmp ult i32 %inc, %N
335 br i1 %cmp.1, label %do.body, label %if.end
337 if.end: ; preds = %do.body, %entry