[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / IRCE / variable-loop-bounds.ll
blob5749b2c2d411912e34bf58c8eda0144113201943
1 ; RUN: opt -irce -S -verify-loop-info -irce-print-changed-loops -irce-skip-profitability-checks < %s 2>&1 | FileCheck %s
3 ; CHECK: irce: in function test_inc_eq: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting>
4 ; CHECK: irce: in function test_inc_ne: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting>
5 ; CHECK: irce: in function test_inc_slt: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting>
6 ; CHECK: irce: in function test_inc_ult: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%if.then,%for.inc<latch><exiting>
7 ; CHECK: irce: in function signed_var_imm_dec_sgt: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting>
8 ; CHECK-NOT: irce: in function signed_var_imm_dec_slt: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting>
9 ; CHECK: irce: in function signed_var_imm_dec_sge: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting>
10 ; CHECK: irce: in function signed_var_imm_dec_ne: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting>
11 ; CHECK-NOT: irce: in function signed_var_imm_dec_eq: constrained Loop at depth 1 containing: %for.body<header>,%if.else,%for.inc<latch><exiting>
13 ; CHECK-LABEL: test_inc_eq(
14 ; CHECK: main.exit.selector:
15 ; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ]
16 ; CHECK: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], %N
17 ; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit
18 define void @test_inc_eq(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) {
19 entry:
20   %cmp16 = icmp sgt i32 %N, 0
21   br i1 %cmp16, label %for.body, label %for.cond.cleanup
23 for.cond.cleanup:
24   ret void
26 for.body:
27   %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
28   %cmp1 = icmp ult i32 %i.017, 512
29   %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017
30   %0 = load i32, i32* %arrayidx, align 4
31   %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017
32   %1 = load i32, i32* %arrayidx2, align 4
33   br i1 %cmp1, label %if.then, label %if.else
35 if.then:
36   %sub = sub i32 %0, %1
37   %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017
38   %2 = load i32, i32* %arrayidx3, align 4
39   %add = add nsw i32 %sub, %2
40   store i32 %add, i32* %arrayidx3, align 4
41   br label %for.inc
43 if.else:
44   %add6 = add nsw i32 %1, %0
45   %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017
46   store i32 %add6, i32* %arrayidx7, align 4
47   br label %for.inc
49 for.inc:
50   %inc = add nuw nsw i32 %i.017, 1
51   %exitcond = icmp eq i32 %inc, %N
52   br i1 %exitcond, label %for.cond.cleanup, label %for.body
55 ; CHECK-LABEL: test_inc_ne
56 ; CHECK: main.exit.selector:
57 ; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ]
58 ; CHECK: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], %N
59 ; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit
60 define void @test_inc_ne(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) {
61 entry:
62   %cmp16 = icmp sgt i32 %N, 0
63   br i1 %cmp16, label %for.body, label %for.cond.cleanup
65 for.cond.cleanup:
66   ret void
68 for.body:
69   %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
70   %cmp1 = icmp ult i32 %i.017, 512
71   %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017
72   %0 = load i32, i32* %arrayidx, align 4
73   %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017
74   %1 = load i32, i32* %arrayidx2, align 4
75   br i1 %cmp1, label %if.then, label %if.else
77 if.then:
78   %sub = sub i32 %0, %1
79   %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017
80   %2 = load i32, i32* %arrayidx3, align 4
81   %add = add nsw i32 %sub, %2
82   store i32 %add, i32* %arrayidx3, align 4
83   br label %for.inc
85 if.else:
86   %add6 = add nsw i32 %1, %0
87   %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017
88   store i32 %add6, i32* %arrayidx7, align 4
89   br label %for.inc
91 for.inc:
92   %inc = add nuw nsw i32 %i.017, 1
93   %exitcond = icmp ne i32 %inc, %N
94   br i1 %exitcond, label %for.body, label %for.cond.cleanup
97 ; CHECK-LABEL: test_inc_slt(
98 ; CHECK: main.exit.selector:
99 ; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ]
100 ; CHECK: [[COND:%[^ ]+]] = icmp slt i32 [[PSEUDO_PHI]], %N
101 ; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit
102 define void @test_inc_slt(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) {
103 entry:
104   %cmp16 = icmp sgt i32 %N, 0
105   br i1 %cmp16, label %for.body, label %for.cond.cleanup
107 for.cond.cleanup:
108   ret void
110 for.body:
111   %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
112   %cmp1 = icmp ult i32 %i.017, 512
113   %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017
114   %0 = load i32, i32* %arrayidx, align 4
115   %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017
116   %1 = load i32, i32* %arrayidx2, align 4
117   br i1 %cmp1, label %if.then, label %if.else
119 if.then:
120   %sub = sub i32 %0, %1
121   %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017
122   %2 = load i32, i32* %arrayidx3, align 4
123   %add = add nsw i32 %sub, %2
124   store i32 %add, i32* %arrayidx3, align 4
125   br label %for.inc
127 if.else:
128   %add6 = add nsw i32 %1, %0
129   %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017
130   store i32 %add6, i32* %arrayidx7, align 4
131   br label %for.inc
133 for.inc:
134   %inc = add nuw nsw i32 %i.017, 1
135   %exitcond = icmp slt i32 %inc, %N
136   br i1 %exitcond, label %for.body, label %for.cond.cleanup
139 ; CHECK-LABEL: test_inc_ult
140 ; CHECK: main.exit.selector:
141 ; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %inc, %for.inc ]
142 ; CHECK: [[COND:%[^ ]+]] = icmp ult i32 [[PSEUDO_PHI]], %N
143 ; CHECK: br i1 [[COND]], label %main.pseudo.exit, label %for.cond.cleanup.loopexit
144 define void @test_inc_ult(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) {
145 entry:
146   %cmp16 = icmp ugt i32 %N, 0
147   br i1 %cmp16, label %for.body, label %for.cond.cleanup
149 for.cond.cleanup:
150   ret void
152 for.body:
153   %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
154   %cmp1 = icmp ult i32 %i.017, 512
155   %arrayidx = getelementptr inbounds i32, i32* %b, i32 %i.017
156   %0 = load i32, i32* %arrayidx, align 4
157   %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %i.017
158   %1 = load i32, i32* %arrayidx2, align 4
159   br i1 %cmp1, label %if.then, label %if.else
161 if.then:
162   %sub = sub i32 %0, %1
163   %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %i.017
164   %2 = load i32, i32* %arrayidx3, align 4
165   %add = add nsw i32 %sub, %2
166   store i32 %add, i32* %arrayidx3, align 4
167   br label %for.inc
169 if.else:
170   %add6 = add nsw i32 %1, %0
171   %arrayidx7 = getelementptr inbounds i32, i32* %a, i32 %i.017
172   store i32 %add6, i32* %arrayidx7, align 4
173   br label %for.inc
175 for.inc:
176   %inc = add nuw nsw i32 %i.017, 1
177   %exitcond = icmp ult i32 %inc, %N
178   br i1 %exitcond, label %for.body, label %for.cond.cleanup
181 ; CHECK-LABEL: signed_var_imm_dec_sgt(
182 ; CHECK: main.exit.selector:
183 ; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %dec, %for.inc ]
184 ; CHECK: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], %M
185 ; CHECK: br i1 [[COND]]
186 define void @signed_var_imm_dec_sgt(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) {
187 entry:
188   %cmp14 = icmp slt i32 %M, 1024
189   br i1 %cmp14, label %for.body, label %for.cond.cleanup
191 for.cond.cleanup:                                 ; preds = %for.inc, %entry
192   ret void
194 for.body:                                         ; preds = %entry, %for.inc
195   %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
196   %cmp1 = icmp slt i32 %iv, 1024
197   %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv
198   %0 = load i32, i32* %arrayidx, align 4
199   %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv
200   %1 = load i32, i32* %arrayidx2, align 4
201   %mul = mul nsw i32 %1, %0
202   %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv
203   br i1 %cmp1, label %for.inc, label %if.else
205 if.else:                                          ; preds = %for.body
206   %2 = load i32, i32* %arrayidx3, align 4
207   %add = add nsw i32 %2, %mul
208   br label %for.inc
210 for.inc:                                          ; preds = %for.body, %if.else
211   %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
212   store i32 %storemerge, i32* %arrayidx3, align 4
213   %dec = add nsw i32 %iv, -1
214   %cmp = icmp sgt i32 %dec, %M
215   br i1 %cmp, label %for.body, label %for.cond.cleanup
218 ; CHECK-LABEL: signed_var_imm_dec_sge(
219 ; CHECK: main.exit.selector:          ; preds = %for.inc
220 ; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %iv, %for.inc ]
221 ; CHECK: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], %M
222 ; CHECK: br i1 [[COND]]
223 define void @signed_var_imm_dec_sge(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) {
224 entry:
225   %cmp14 = icmp sgt i32 %M, 1024
226   br i1 %cmp14, label %for.cond.cleanup, label %for.body
228 for.cond.cleanup:                                 ; preds = %for.inc, %entry
229   ret void
231 for.body:                                         ; preds = %entry, %for.inc
232   %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
233   %cmp1 = icmp slt i32 %iv, 1024
234   %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv
235   %0 = load i32, i32* %arrayidx, align 4
236   %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv
237   %1 = load i32, i32* %arrayidx2, align 4
238   %mul = mul nsw i32 %1, %0
239   %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv
240   br i1 %cmp1, label %for.inc, label %if.else
242 if.else:                                          ; preds = %for.body
243   %2 = load i32, i32* %arrayidx3, align 4
244   %add = add nsw i32 %2, %mul
245   br label %for.inc
247 for.inc:                                          ; preds = %for.body, %if.else
248   %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
249   store i32 %storemerge, i32* %arrayidx3, align 4
250   %dec = add nsw i32 %iv, -1
251   %cmp = icmp sgt i32 %iv, %M
252   br i1 %cmp, label %for.body, label %for.cond.cleanup
255 define void @signed_var_imm_dec_slt(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) {
256 entry:
257   %cmp14 = icmp sgt i32 %M, 1024
258   br i1 %cmp14, label %for.cond.cleanup, label %for.body
260 for.cond.cleanup:                                 ; preds = %for.inc, %entry
261   ret void
263 for.body:                                         ; preds = %entry, %for.inc
264   %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
265   %cmp1 = icmp slt i32 %iv, 1024
266   %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv
267   %0 = load i32, i32* %arrayidx, align 4
268   %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv
269   %1 = load i32, i32* %arrayidx2, align 4
270   %mul = mul nsw i32 %1, %0
271   %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv
272   br i1 %cmp1, label %for.inc, label %if.else
274 if.else:                                          ; preds = %for.body
275   %2 = load i32, i32* %arrayidx3, align 4
276   %add = add nsw i32 %2, %mul
277   br label %for.inc
279 for.inc:                                          ; preds = %for.body, %if.else
280   %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
281   store i32 %storemerge, i32* %arrayidx3, align 4
282   %dec = add nsw i32 %iv, -1
283   %cmp = icmp slt i32 %iv, %M
284   br i1 %cmp, label %for.cond.cleanup, label %for.body
287 ; CHECK-LABEL: signed_var_imm_dec_ne(
288 ; CHECK: main.exit.selector:          ; preds = %for.inc
289 ; CHECK: [[PSEUDO_PHI:%[^ ]+]] = phi i32 [ %dec, %for.inc ]
290 ; CHECK: [[COND:%[^ ]+]] = icmp sgt i32 [[PSEUDO_PHI]], %M
291 ; CHECK: br i1 [[COND]]
292 define void @signed_var_imm_dec_ne(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) {
293 entry:
294   %cmp14 = icmp slt i32 %M, 1024
295   br i1 %cmp14, label %for.body, label %for.cond.cleanup
297 for.cond.cleanup:                                 ; preds = %for.inc, %entry
298   ret void
300 for.body:                                         ; preds = %entry, %for.inc
301   %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
302   %cmp1 = icmp slt i32 %iv, 1024
303   %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv
304   %0 = load i32, i32* %arrayidx, align 4
305   %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv
306   %1 = load i32, i32* %arrayidx2, align 4
307   %mul = mul nsw i32 %1, %0
308   %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv
309   br i1 %cmp1, label %for.inc, label %if.else
311 if.else:                                          ; preds = %for.body
312   %2 = load i32, i32* %arrayidx3, align 4
313   %add = add nsw i32 %2, %mul
314   br label %for.inc
316 for.inc:                                          ; preds = %for.body, %if.else
317   %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
318   store i32 %storemerge, i32* %arrayidx3, align 4
319   %dec = add nsw i32 %iv, -1
320   %cmp = icmp ne i32 %dec, %M
321   br i1 %cmp, label %for.body, label %for.cond.cleanup
324 define void @signed_var_imm_dec_eq(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %M) {
325 entry:
326   %cmp14 = icmp slt i32 %M, 1024
327   br i1 %cmp14, label %for.body, label %for.cond.cleanup
329 for.cond.cleanup:                                 ; preds = %for.inc, %entry
330   ret void
332 for.body:                                         ; preds = %entry, %for.inc
333   %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
334   %cmp1 = icmp slt i32 %iv, 1024
335   %arrayidx = getelementptr inbounds i32, i32* %b, i32 %iv
336   %0 = load i32, i32* %arrayidx, align 4
337   %arrayidx2 = getelementptr inbounds i32, i32* %c, i32 %iv
338   %1 = load i32, i32* %arrayidx2, align 4
339   %mul = mul nsw i32 %1, %0
340   %arrayidx3 = getelementptr inbounds i32, i32* %a, i32 %iv
341   br i1 %cmp1, label %for.inc, label %if.else
343 if.else:                                          ; preds = %for.body
344   %2 = load i32, i32* %arrayidx3, align 4
345   %add = add nsw i32 %2, %mul
346   br label %for.inc
348 for.inc:                                          ; preds = %for.body, %if.else
349   %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
350   store i32 %storemerge, i32* %arrayidx3, align 4
351   %dec = add nsw i32 %iv, -1
352   %cmp = icmp eq i32 %dec, %M
353   br i1 %cmp, label %for.cond.cleanup, label %for.body