1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=indvars -S | FileCheck %s
4 define i32 @test.signed.add.0(ptr %array, i32 %length, i32 %init) {
5 ; CHECK-LABEL: @test.signed.add.0(
7 ; CHECK-NEXT: [[UPPER:%.*]] = icmp slt i32 [[INIT:%.*]], [[LENGTH:%.*]]
8 ; CHECK-NEXT: br i1 [[UPPER]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
9 ; CHECK: loop.preheader:
10 ; CHECK-NEXT: br label [[LOOP:%.*]]
12 ; CHECK-NEXT: [[CIV:%.*]] = phi i32 [ [[CIV_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
13 ; CHECK-NEXT: [[CIV_INC]] = add nsw i32 [[CIV]], 1
14 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CIV_INC]], [[LENGTH]]
15 ; CHECK-NEXT: br i1 [[CMP]], label [[LATCH]], label [[BREAK:%.*]]
17 ; CHECK-NEXT: store i32 0, ptr [[ARRAY:%.*]], align 4
18 ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[BREAK]]
20 ; CHECK-NEXT: [[CIV_INC_LCSSA:%.*]] = phi i32 [ [[LENGTH]], [[LATCH]] ], [ [[LENGTH]], [[LOOP]] ]
21 ; CHECK-NEXT: ret i32 [[CIV_INC_LCSSA]]
23 ; CHECK-NEXT: ret i32 42
26 %upper = icmp slt i32 %init, %length
27 br i1 %upper, label %loop, label %exit
30 %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ]
31 %civ.inc = add i32 %civ, 1
32 %cmp = icmp slt i32 %civ.inc, %length
33 br i1 %cmp, label %latch, label %break
36 store i32 0, ptr %array
37 %check = icmp slt i32 %civ.inc, %length
38 br i1 %check, label %loop, label %break
47 define i32 @test.signed.add.1(ptr %array, i32 %length, i32 %init) {
48 ; CHECK-LABEL: @test.signed.add.1(
50 ; CHECK-NEXT: [[UPPER:%.*]] = icmp sle i32 [[INIT:%.*]], [[LENGTH:%.*]]
51 ; CHECK-NEXT: br i1 [[UPPER]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
52 ; CHECK: loop.preheader:
53 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[INIT]], 1
54 ; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[LENGTH]], i32 [[TMP0]])
55 ; CHECK-NEXT: br label [[LOOP:%.*]]
57 ; CHECK-NEXT: [[CIV:%.*]] = phi i32 [ [[CIV_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
58 ; CHECK-NEXT: [[CIV_INC]] = add i32 [[CIV]], 1
59 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CIV_INC]], [[LENGTH]]
60 ; CHECK-NEXT: br i1 [[CMP]], label [[LATCH]], label [[BREAK:%.*]]
62 ; CHECK-NEXT: store i32 0, ptr [[ARRAY:%.*]], align 4
63 ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[BREAK]]
65 ; CHECK-NEXT: [[CIV_INC_LCSSA:%.*]] = phi i32 [ [[SMAX]], [[LATCH]] ], [ [[SMAX]], [[LOOP]] ]
66 ; CHECK-NEXT: ret i32 [[CIV_INC_LCSSA]]
68 ; CHECK-NEXT: ret i32 42
71 %upper = icmp sle i32 %init, %length
72 br i1 %upper, label %loop, label %exit
75 %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ]
76 %civ.inc = add i32 %civ, 1
77 %cmp = icmp slt i32 %civ.inc, %length
78 br i1 %cmp, label %latch, label %break
81 store i32 0, ptr %array
82 %check = icmp slt i32 %civ.inc, %length
83 br i1 %check, label %loop, label %break
92 define i32 @test.unsigned.add.0(ptr %array, i32 %length, i32 %init) {
93 ; CHECK-LABEL: @test.unsigned.add.0(
95 ; CHECK-NEXT: [[UPPER:%.*]] = icmp ult i32 [[INIT:%.*]], [[LENGTH:%.*]]
96 ; CHECK-NEXT: br i1 [[UPPER]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
97 ; CHECK: loop.preheader:
98 ; CHECK-NEXT: br label [[LOOP:%.*]]
100 ; CHECK-NEXT: [[CIV:%.*]] = phi i32 [ [[CIV_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
101 ; CHECK-NEXT: [[CIV_INC]] = add nuw i32 [[CIV]], 1
102 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CIV_INC]], [[LENGTH]]
103 ; CHECK-NEXT: br i1 [[CMP]], label [[LATCH]], label [[BREAK:%.*]]
105 ; CHECK-NEXT: store i32 0, ptr [[ARRAY:%.*]], align 4
106 ; CHECK-NEXT: [[CHECK:%.*]] = icmp ult i32 [[CIV_INC]], [[LENGTH]]
107 ; CHECK-NEXT: br i1 [[CHECK]], label [[LOOP]], label [[BREAK]]
109 ; CHECK-NEXT: [[CIV_INC_LCSSA:%.*]] = phi i32 [ [[CIV_INC]], [[LATCH]] ], [ [[CIV_INC]], [[LOOP]] ]
110 ; CHECK-NEXT: ret i32 [[CIV_INC_LCSSA]]
112 ; CHECK-NEXT: ret i32 42
115 %upper = icmp ult i32 %init, %length
116 br i1 %upper, label %loop, label %exit
119 %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ]
120 %civ.inc = add i32 %civ, 1
121 %cmp = icmp slt i32 %civ.inc, %length
122 br i1 %cmp, label %latch, label %break
125 store i32 0, ptr %array
126 %check = icmp ult i32 %civ.inc, %length
127 br i1 %check, label %loop, label %break
136 define i32 @test.unsigned.add.1(ptr %array, i32 %length, i32 %init) {
137 ; CHECK-LABEL: @test.unsigned.add.1(
139 ; CHECK-NEXT: [[UPPER:%.*]] = icmp ule i32 [[INIT:%.*]], [[LENGTH:%.*]]
140 ; CHECK-NEXT: br i1 [[UPPER]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
141 ; CHECK: loop.preheader:
142 ; CHECK-NEXT: br label [[LOOP:%.*]]
144 ; CHECK-NEXT: [[CIV:%.*]] = phi i32 [ [[CIV_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
145 ; CHECK-NEXT: [[CIV_INC]] = add i32 [[CIV]], 1
146 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CIV_INC]], [[LENGTH]]
147 ; CHECK-NEXT: br i1 [[CMP]], label [[LATCH]], label [[BREAK:%.*]]
149 ; CHECK-NEXT: store i32 0, ptr [[ARRAY:%.*]], align 4
150 ; CHECK-NEXT: [[CHECK:%.*]] = icmp ult i32 [[CIV_INC]], [[LENGTH]]
151 ; CHECK-NEXT: br i1 [[CHECK]], label [[LOOP]], label [[BREAK]]
153 ; CHECK-NEXT: [[CIV_INC_LCSSA:%.*]] = phi i32 [ [[CIV_INC]], [[LATCH]] ], [ [[CIV_INC]], [[LOOP]] ]
154 ; CHECK-NEXT: ret i32 [[CIV_INC_LCSSA]]
156 ; CHECK-NEXT: ret i32 42
159 %upper = icmp ule i32 %init, %length
160 br i1 %upper, label %loop, label %exit
163 %civ = phi i32 [ %init, %entry ], [ %civ.inc, %latch ]
164 %civ.inc = add i32 %civ, 1
165 %cmp = icmp slt i32 %civ.inc, %length
166 br i1 %cmp, label %latch, label %break
169 store i32 0, ptr %array
170 %check = icmp ult i32 %civ.inc, %length
171 br i1 %check, label %loop, label %break
180 define hidden void @test.shl.exact.equal() {
181 ; CHECK-LABEL: @test.shl.exact.equal(
183 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
185 ; CHECK-NEXT: [[K_021:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
186 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[K_021]]
187 ; CHECK-NEXT: [[SHR1:%.*]] = ashr exact i32 [[SHL]], 1
188 ; CHECK-NEXT: [[SHR2:%.*]] = lshr exact i32 [[SHL]], 1
189 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[K_021]], 1
190 ; CHECK-NEXT: br i1 true, label [[FOR_END:%.*]], label [[FOR_BODY]]
192 ; CHECK-NEXT: ret void
198 %k.021 = phi i32 [ 1, %entry ], [ %inc, %for.body ]
199 %shl = shl i32 1, %k.021
200 %shr1 = ashr i32 %shl, 1
201 %shr2 = lshr i32 %shl, 1
202 %inc = add nuw nsw i32 %k.021, 1
203 %exitcond = icmp eq i32 %inc, 9
204 br i1 %exitcond, label %for.end, label %for.body
210 define hidden void @test.shl.exact.greater() {
211 ; CHECK-LABEL: @test.shl.exact.greater(
213 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
215 ; CHECK-NEXT: [[K_021:%.*]] = phi i32 [ 3, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
216 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[K_021]]
217 ; CHECK-NEXT: [[SHR1:%.*]] = ashr exact i32 [[SHL]], 2
218 ; CHECK-NEXT: [[SHR2:%.*]] = lshr exact i32 [[SHL]], 2
219 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[K_021]], 1
220 ; CHECK-NEXT: br i1 true, label [[FOR_END:%.*]], label [[FOR_BODY]]
222 ; CHECK-NEXT: ret void
228 %k.021 = phi i32 [ 3, %entry ], [ %inc, %for.body ]
229 %shl = shl i32 1, %k.021
230 %shr1 = ashr i32 %shl, 2
231 %shr2 = lshr i32 %shl, 2
232 %inc = add nuw nsw i32 %k.021, 1
233 %exitcond = icmp eq i32 %inc, 9
234 br i1 %exitcond, label %for.end, label %for.body
240 define hidden void @test.shl.exact.unbound(i32 %arg) {
241 ; CHECK-LABEL: @test.shl.exact.unbound(
243 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
245 ; CHECK-NEXT: [[K_021:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
246 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[K_021]]
247 ; CHECK-NEXT: [[SHR1:%.*]] = ashr exact i32 [[SHL]], 2
248 ; CHECK-NEXT: [[SHR2:%.*]] = lshr exact i32 [[SHL]], 2
249 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[K_021]], 1
250 ; CHECK-NEXT: br i1 true, label [[FOR_END:%.*]], label [[FOR_BODY]]
252 ; CHECK-NEXT: ret void
258 %k.021 = phi i32 [ 2, %entry ], [ %inc, %for.body ]
259 %shl = shl i32 1, %k.021
260 %shr1 = ashr i32 %shl, 2
261 %shr2 = lshr i32 %shl, 2
262 %inc = add nuw nsw i32 %k.021, 1
263 %exitcond = icmp eq i32 %inc, %arg
264 br i1 %exitcond, label %for.end, label %for.body
270 define hidden void @test.shl.nonexact() {
271 ; CHECK-LABEL: @test.shl.nonexact(
273 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
275 ; CHECK-NEXT: [[K_021:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
276 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[K_021]]
277 ; CHECK-NEXT: [[SHR1:%.*]] = ashr i32 [[SHL]], 3
278 ; CHECK-NEXT: [[SHR2:%.*]] = lshr i32 [[SHL]], 3
279 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[K_021]], 1
280 ; CHECK-NEXT: br i1 true, label [[FOR_END:%.*]], label [[FOR_BODY]]
282 ; CHECK-NEXT: ret void
288 %k.021 = phi i32 [ 2, %entry ], [ %inc, %for.body ]
289 %shl = shl i32 1, %k.021
290 %shr1 = ashr i32 %shl, 3
291 %shr2 = lshr i32 %shl, 3
292 %inc = add nuw nsw i32 %k.021, 1
293 %exitcond = icmp eq i32 %inc, 9
294 br i1 %exitcond, label %for.end, label %for.body
300 define void @test_infer_nsw(ptr %p) {
301 ; CHECK-LABEL: @test_infer_nsw(
303 ; CHECK-NEXT: [[FREEZE:%.*]] = freeze i32 poison
304 ; CHECK-NEXT: br label [[BB1:%.*]]
306 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[ADD:%.*]], [[BB2:%.*]] ], [ 0, [[BB:%.*]] ]
307 ; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[FREEZE]], [[PHI]]
308 ; CHECK-NEXT: [[ICMP:%.*]] = icmp sgt i32 [[SUB]], 1
309 ; CHECK-NEXT: br i1 [[ICMP]], label [[BB2]], label [[BB3:%.*]]
311 ; CHECK-NEXT: store i16 1, ptr [[P:%.*]], align 2
312 ; CHECK-NEXT: [[ADD]] = add nuw i32 [[PHI]], 2
313 ; CHECK-NEXT: br label [[BB1]]
315 ; CHECK-NEXT: ret void
318 %freeze = freeze i32 poison
321 bb1: ; preds = %bb2, %bb
322 %phi = phi i32 [ %add, %bb2 ], [ 0, %bb ]
323 %sub = sub i32 %freeze, %phi
324 %icmp = icmp sgt i32 %sub, 1
325 br i1 %icmp, label %bb2, label %bb3
328 store i16 1, ptr %p, align 2
329 %add = add nuw i32 %phi, 2
337 !1 = !{i32 0, i32 42}