[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / HardwareLoops / loop-guards.ll
blob652a5d872c0d07f345bfb318b18a5bc0122c9025
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
7 ; CHECK-LABEL: test1
8 ; CHECK: entry:
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) {
17 entry:
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
33   ret void
36 ; CHECK-LABEL: test2
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) {
40 entry:
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
56   ret void
59 ; CHECK-LABEL: test3
60 ; CHECK: 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) {
68 entry:
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
85   ret void
88 ; CHECK-LABEL: test4
89 ; CHECK: 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) {
98 entry:
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
115   br label %while.cond
117 if.end:                                           ; preds = %while.cond, %entry
118   ret void
121 ; CHECK-LABEL: test5
122 ; CHECK: 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) {
128 entry:
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
147   ret void
150 ; CHECK-LABEL: test6
151 ; CHECK: 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) {
159 entry:
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
180   ret void
183 ; CHECK-LABEL: test7
184 ; CHECK: 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) {
192 entry:
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
213   ret void
216 ; TODO: Can we rearrange the conditional blocks so that we can use the test form?
217 ; CHECK-LABEL: test8
218 ; CHECK: entry:
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) {
227 entry:
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
248   ret void
251 ; CHECK-LABEL: test9
252 ; CHECK: 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) {
258 entry:
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
276   ret void
279 ; CHECK-LABEL: test10
280 ; CHECK: entry:
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) {
286 entry:
287   %cmp = icmp ne i32 %N, 0
288   %sub = sub i32 %N, 1
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
306   ret void
309 ; CHECK-LABEL: test11
310 ; CHECK: entry:
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) {
318 entry:
319   br label %do.body.preheader
321 do.body.preheader:
322   %cmp = icmp ne i32 %N, 0
323   br i1 %cmp, label %do.body, label %if.end
325 do.body:
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
338   ret void