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) {
20 %cmp16 = icmp sgt i32 %N, 0
21 br i1 %cmp16, label %for.body, label %for.cond.cleanup
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
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
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
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) {
62 %cmp16 = icmp sgt i32 %N, 0
63 br i1 %cmp16, label %for.body, label %for.cond.cleanup
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
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
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
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) {
104 %cmp16 = icmp sgt i32 %N, 0
105 br i1 %cmp16, label %for.body, label %for.cond.cleanup
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
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
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
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) {
146 %cmp16 = icmp ugt i32 %N, 0
147 br i1 %cmp16, label %for.body, label %for.cond.cleanup
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
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
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
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) {
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
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
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) {
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
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
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) {
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
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
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) {
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
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
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) {
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
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
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