1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -indvars -S | FileCheck %s
4 @A = external global i32
6 define void @add_cr_nsw_nuw() {
7 ; CHECK-LABEL: @add_cr_nsw_nuw(
9 ; CHECK-NEXT: br label [[LOOP:%.*]]
11 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
12 ; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1
13 ; CHECK-NEXT: store i32 [[I]], i32* @A
14 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1000
15 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
17 ; CHECK-NEXT: ret void
23 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
24 %i.next = add i32 %i, 1
26 %c = icmp ne i32 %i.next, 1000
27 br i1 %c, label %loop, label %loopexit
33 define void @add_cr_nuw() {
34 ; CHECK-LABEL: @add_cr_nuw(
36 ; CHECK-NEXT: br label [[LOOP:%.*]]
38 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
39 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
40 ; CHECK-NEXT: store i32 [[I]], i32* @A
41 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], -1
42 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
44 ; CHECK-NEXT: ret void
50 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
51 %i.next = add i32 %i, 1
53 %c = icmp ne i32 %i.next, -1
54 br i1 %c, label %loop, label %loopexit
60 define void @add_cr_nsw() {
61 ; CHECK-LABEL: @add_cr_nsw(
63 ; CHECK-NEXT: br label [[LOOP:%.*]]
65 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ -10, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
66 ; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
67 ; CHECK-NEXT: store i32 [[I]], i32* @A
68 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 10
69 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
71 ; CHECK-NEXT: ret void
77 %i = phi i32 [ -10, %entry ], [ %i.next, %loop ]
78 %i.next = add i32 %i, 1
80 %c = icmp ne i32 %i.next, 10
81 br i1 %c, label %loop, label %loopexit
87 define void @add_cr_none() {
88 ; CHECK-LABEL: @add_cr_none(
90 ; CHECK-NEXT: br label [[LOOP:%.*]]
92 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 10, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
93 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
94 ; CHECK-NEXT: store i32 [[I]], i32* @A
95 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0
96 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
98 ; CHECK-NEXT: ret void
104 %i = phi i32 [ 10, %entry ], [ %i.next, %loop ]
105 %i.next = add i32 %i, 1
106 store i32 %i, i32* @A
107 %c = icmp ne i32 %i.next, 0
108 br i1 %c, label %loop, label %loopexit
114 define void @add_unknown_none(i32 %n) {
115 ; CHECK-LABEL: @add_unknown_none(
117 ; CHECK-NEXT: br label [[LOOP:%.*]]
119 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
120 ; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
121 ; CHECK-NEXT: store i32 [[I]], i32* @A
122 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], [[N:%.*]]
123 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
125 ; CHECK-NEXT: ret void
131 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
132 %i.next = add i32 %i, 1
133 store i32 %i, i32* @A
134 %c = icmp ne i32 %i.next, %n
135 br i1 %c, label %loop, label %loopexit
141 define void @sub_cr_nsw_nuw() {
142 ; CHECK-LABEL: @sub_cr_nsw_nuw(
144 ; CHECK-NEXT: br label [[LOOP:%.*]]
146 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
147 ; CHECK-NEXT: [[I_NEXT]] = sub nsw i32 [[I]], -1
148 ; CHECK-NEXT: store i32 [[I]], i32* @A
149 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1000
150 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
152 ; CHECK-NEXT: ret void
158 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
159 %i.next = sub i32 %i, -1
160 store i32 %i, i32* @A
161 %c = icmp ne i32 %i.next, 1000
162 br i1 %c, label %loop, label %loopexit
169 define void @sub_unknown_none(i32 %n) {
170 ; CHECK-LABEL: @sub_unknown_none(
172 ; CHECK-NEXT: br label [[LOOP:%.*]]
174 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
175 ; CHECK-NEXT: [[I_NEXT]] = sub i32 [[I]], -1
176 ; CHECK-NEXT: store i32 [[I]], i32* @A
177 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], [[N:%.*]]
178 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
180 ; CHECK-NEXT: ret void
186 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
187 %i.next = sub i32 %i, -1
188 store i32 %i, i32* @A
189 %c = icmp ne i32 %i.next, %n
190 br i1 %c, label %loop, label %loopexit
197 ; NOTE: For the rest of these, it looks like we're failing to use a statically
198 ; computable backedge taken count to infer a range on the IV and thus fail to
199 ; prove flags via constant range reasoning.
202 define void @mul_cr_nsw_nuw() {
203 ; CHECK-LABEL: @mul_cr_nsw_nuw(
205 ; CHECK-NEXT: br label [[LOOP:%.*]]
207 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
208 ; CHECK-NEXT: [[I_NEXT]] = mul i32 [[I]], 2
209 ; CHECK-NEXT: store i32 [[I]], i32* @A
210 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1024
211 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
213 ; CHECK-NEXT: ret void
219 %i = phi i32 [ 1, %entry ], [ %i.next, %loop ]
220 %i.next = mul i32 %i, 2
221 store i32 %i, i32* @A
222 %c = icmp ne i32 %i.next, 1024
223 br i1 %c, label %loop, label %loopexit
230 define void @shl_cr_nsw_nuw() {
231 ; CHECK-LABEL: @shl_cr_nsw_nuw(
233 ; CHECK-NEXT: br label [[LOOP:%.*]]
235 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
236 ; CHECK-NEXT: [[I_NEXT]] = shl i32 [[I]], 1
237 ; CHECK-NEXT: store i32 [[I]], i32* @A
238 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1024
239 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
241 ; CHECK-NEXT: ret void
247 %i = phi i32 [ 1, %entry ], [ %i.next, %loop ]
248 %i.next = shl i32 %i, 1
249 store i32 %i, i32* @A
250 %c = icmp ne i32 %i.next, 1024
251 br i1 %c, label %loop, label %loopexit
258 define void @lshr_cr_nsw_nuw() {
259 ; CHECK-LABEL: @lshr_cr_nsw_nuw(
261 ; CHECK-NEXT: br label [[LOOP:%.*]]
263 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 1024, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
264 ; CHECK-NEXT: [[I_NEXT]] = lshr i32 [[I]], 1
265 ; CHECK-NEXT: store i32 [[I]], i32* @A
266 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0
267 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
269 ; CHECK-NEXT: ret void
275 %i = phi i32 [ 1024, %entry ], [ %i.next, %loop ]
276 %i.next = lshr i32 %i, 1
277 store i32 %i, i32* @A
278 %c = icmp ne i32 %i.next, 0
279 br i1 %c, label %loop, label %loopexit
286 define void @lshr_cr_nuw() {
287 ; CHECK-LABEL: @lshr_cr_nuw(
289 ; CHECK-NEXT: br label [[LOOP:%.*]]
291 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
292 ; CHECK-NEXT: [[I_NEXT]] = lshr i32 [[I]], 1
293 ; CHECK-NEXT: store i32 [[I]], i32* @A
294 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0
295 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
297 ; CHECK-NEXT: ret void
303 %i = phi i32 [ -1, %entry ], [ %i.next, %loop ]
304 %i.next = lshr i32 %i, 1
305 store i32 %i, i32* @A
306 %c = icmp ne i32 %i.next, 0
307 br i1 %c, label %loop, label %loopexit
314 define void @ashr_cr_nsw_nuw() {
315 ; CHECK-LABEL: @ashr_cr_nsw_nuw(
317 ; CHECK-NEXT: br label [[LOOP:%.*]]
319 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 1024, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
320 ; CHECK-NEXT: [[I_NEXT]] = ashr i32 [[I]], 1
321 ; CHECK-NEXT: store i32 [[I]], i32* @A
322 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 0
323 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
325 ; CHECK-NEXT: ret void
331 %i = phi i32 [ 1024, %entry ], [ %i.next, %loop ]
332 %i.next = ashr i32 %i, 1
333 store i32 %i, i32* @A
334 %c = icmp ne i32 %i.next, 0
335 br i1 %c, label %loop, label %loopexit
342 define void @ashr_cr_nsw() {
343 ; CHECK-LABEL: @ashr_cr_nsw(
345 ; CHECK-NEXT: br label [[LOOP:%.*]]
347 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ -1024, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
348 ; CHECK-NEXT: [[I_NEXT]] = ashr i32 [[I]], 1
349 ; CHECK-NEXT: store i32 [[I]], i32* @A
350 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], 1
351 ; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
353 ; CHECK-NEXT: ret void
359 %i = phi i32 [ -1024, %entry ], [ %i.next, %loop ]
360 %i.next = ashr i32 %i, 1
361 store i32 %i, i32* @A
362 %c = icmp ne i32 %i.next, 1
363 br i1 %c, label %loop, label %loopexit