1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=indvars -S < %s | FileCheck %s
4 ; Monotonic decrementing iv. we should be able to prove that %iv.next <s len
5 ; basing on its nsw and the fact that its starting value <s len.
6 define i32 @test_01(ptr %p) {
7 ; CHECK-LABEL: @test_01(
9 ; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[P:%.*]], align 4, [[RNG0:!range !.*]]
10 ; CHECK-NEXT: br label [[LOOP:%.*]]
12 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
13 ; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], -1
14 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
16 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 0
17 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
19 ; CHECK-NEXT: ret i32 -1
21 ; CHECK-NEXT: ret i32 0
24 %len = load i32, ptr %p, !range !0
28 %iv = phi i32 [%len, %entry], [%iv.next, %backedge]
29 %iv.next = add i32 %iv, -1
30 %rc = icmp slt i32 %iv.next, %len
31 br i1 %rc, label %backedge, label %fail
34 %loop.cond = icmp ne i32 %iv, 0
35 br i1 %loop.cond, label %loop, label %exit
44 ; We should not remove this range check because signed overflow is possible here (start at len = 0).
45 define i32 @test_01_neg(ptr %p) {
46 ; CHECK-LABEL: @test_01_neg(
48 ; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[P:%.*]], align 4, [[RNG0]]
49 ; CHECK-NEXT: br label [[LOOP:%.*]]
51 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
52 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
53 ; CHECK-NEXT: [[RC:%.*]] = icmp slt i32 [[IV_NEXT]], [[LEN]]
54 ; CHECK-NEXT: br i1 [[RC]], label [[BACKEDGE]], label [[FAIL:%.*]]
56 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 1
57 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
59 ; CHECK-NEXT: ret i32 -1
61 ; CHECK-NEXT: ret i32 0
64 %len = load i32, ptr %p, !range !0
68 %iv = phi i32 [%len, %entry], [%iv.next, %backedge]
69 %iv.next = add i32 %iv, -1
70 %rc = icmp slt i32 %iv.next, %len
71 br i1 %rc, label %backedge, label %fail
74 %loop.cond = icmp ne i32 %iv, 1
75 br i1 %loop.cond, label %loop, label %exit
84 ; Monotonic incrementing iv. we should be able to prove that %iv.next >s len
85 ; basing on its nsw and the fact that its starting value >s len.
86 define i32 @test_02(ptr %p) {
87 ; CHECK-LABEL: @test_02(
89 ; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[P:%.*]], align 4, [[RNG1:!range !.*]]
90 ; CHECK-NEXT: br label [[LOOP:%.*]]
92 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
93 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
94 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
96 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 0
97 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
99 ; CHECK-NEXT: ret i32 -1
101 ; CHECK-NEXT: ret i32 0
104 %len = load i32, ptr %p, !range !1
108 %iv = phi i32 [%len, %entry], [%iv.next, %backedge]
109 %iv.next = add i32 %iv, 1
110 %rc = icmp sgt i32 %iv.next, %len
111 br i1 %rc, label %backedge, label %fail
114 %loop.cond = icmp ne i32 %iv, 0
115 br i1 %loop.cond, label %loop, label %exit
124 ; We should not remove this range check because signed overflow is possible here (start at len = -1).
125 define i32 @test_02_neg(ptr %p) {
126 ; CHECK-LABEL: @test_02_neg(
128 ; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[P:%.*]], align 4, [[RNG1]]
129 ; CHECK-NEXT: br label [[LOOP:%.*]]
131 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
132 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
133 ; CHECK-NEXT: [[RC:%.*]] = icmp sgt i32 [[IV_NEXT]], [[LEN]]
134 ; CHECK-NEXT: br i1 [[RC]], label [[BACKEDGE]], label [[FAIL:%.*]]
136 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], -2
137 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
139 ; CHECK-NEXT: ret i32 -1
141 ; CHECK-NEXT: ret i32 0
144 %len = load i32, ptr %p, !range !1
148 %iv = phi i32 [%len, %entry], [%iv.next, %backedge]
149 %iv.next = add i32 %iv, 1
150 %rc = icmp sgt i32 %iv.next, %len
151 br i1 %rc, label %backedge, label %fail
154 %loop.cond = icmp ne i32 %iv, -2
155 br i1 %loop.cond, label %loop, label %exit
164 define i32 @test_03(ptr %p) {
165 ; CHECK-LABEL: @test_03(
167 ; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[P:%.*]], align 4, [[RNG2:!range !.*]]
168 ; CHECK-NEXT: br label [[LOOP:%.*]]
170 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
171 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
172 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
174 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 1000
175 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
177 ; CHECK-NEXT: ret i32 -1
179 ; CHECK-NEXT: ret i32 0
182 %len = load i32, ptr %p, !range !2
186 %iv = phi i32 [%len, %entry], [%iv.next, %backedge]
187 %iv.next = add i32 %iv, 1
188 %rc = icmp sgt i32 %iv.next, %len
189 br i1 %rc, label %backedge, label %fail
192 %loop.cond = icmp ne i32 %iv, 1000
193 br i1 %loop.cond, label %loop, label %exit
202 define i32 @test_04(ptr %p) {
203 ; CHECK-LABEL: @test_04(
205 ; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[P:%.*]], align 4, [[RNG2]]
206 ; CHECK-NEXT: br label [[LOOP:%.*]]
208 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
209 ; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], -1
210 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
212 ; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 0
213 ; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
215 ; CHECK-NEXT: ret i32 -1
217 ; CHECK-NEXT: ret i32 0
220 %len = load i32, ptr %p, !range !2
224 %iv = phi i32 [%len, %entry], [%iv.next, %backedge]
225 %iv.next = add i32 %iv, -1
226 %rc = icmp slt i32 %iv.next, %len
227 br i1 %rc, label %backedge, label %fail
230 %loop.cond = icmp ne i32 %iv, 0
231 br i1 %loop.cond, label %loop, label %exit
240 !0 = !{i32 0, i32 2147483647}
241 !1 = !{i32 -2147483648, i32 0}
242 !2 = !{i32 0, i32 1000}