1 ; RUN: opt < %s -indvars -indvars-post-increment-ranges -S | FileCheck %s
3 target datalayout = "p:64:64:64-n32:64"
5 ; When the IV in this loop is widened we want to widen this use as well:
6 ; icmp slt i32 %i.inc, %limit
7 ; In order to do this indvars need to prove that the narrow IV def (%i.inc)
8 ; is not-negative from the range check inside of the loop.
9 define void @test(i32* %base, i32 %limit, i32 %start) {
17 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
18 %within_limits = icmp ult i32 %i, 64
19 br i1 %within_limits, label %continue, label %for.end
22 %i.i64 = zext i32 %i to i64
23 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
24 %val = load i32, i32* %arrayidx, align 4
28 %i.inc = add nsw nuw i32 %i, 1
29 %cmp = icmp slt i32 %i.inc, %limit
30 br i1 %cmp, label %for.body, label %for.end
39 define void @test_false_edge(i32* %base, i32 %limit, i32 %start) {
40 ; CHECK-LABEL: @test_false_edge(
47 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
48 %out_of_bounds = icmp ugt i32 %i, 64
49 br i1 %out_of_bounds, label %for.end, label %continue
52 %i.i64 = zext i32 %i to i64
53 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
54 %val = load i32, i32* %arrayidx, align 4
58 %i.inc = add nsw nuw i32 %i, 1
59 %cmp = icmp slt i32 %i.inc, %limit
60 br i1 %cmp, label %for.body, label %for.end
69 define void @test_range_metadata(i32* %array_length_ptr, i32* %base,
70 i32 %limit, i32 %start) {
71 ; CHECK-LABEL: @test_range_metadata(
78 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
79 %array_length = load i32, i32* %array_length_ptr, !range !{i32 0, i32 64 }
80 %within_limits = icmp ult i32 %i, %array_length
81 br i1 %within_limits, label %continue, label %for.end
84 %i.i64 = zext i32 %i to i64
85 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
86 %val = load i32, i32* %arrayidx, align 4
90 %i.inc = add nsw nuw i32 %i, 1
91 %cmp = icmp slt i32 %i.inc, %limit
92 br i1 %cmp, label %for.body, label %for.end
101 ; Negative version of the test above, we don't know anything about
102 ; array_length_ptr range.
103 define void @test_neg(i32* %array_length_ptr, i32* %base,
104 i32 %limit, i32 %start) {
105 ; CHECK-LABEL: @test_neg(
112 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
113 %array_length = load i32, i32* %array_length_ptr
114 %within_limits = icmp ult i32 %i, %array_length
115 br i1 %within_limits, label %continue, label %for.end
118 %i.i64 = zext i32 %i to i64
119 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
120 %val = load i32, i32* %arrayidx, align 4
124 %i.inc = add nsw nuw i32 %i, 1
125 %cmp = icmp slt i32 %i.inc, %limit
126 br i1 %cmp, label %for.body, label %for.end
135 define void @test_transitive_use(i32* %base, i32 %limit, i32 %start) {
136 ; CHECK-LABEL: @test_transitive_use(
138 ; CHECK: %result = icmp slt i64
144 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
145 %within_limits = icmp ult i32 %i, 64
146 br i1 %within_limits, label %continue, label %for.end
149 %i.mul.3 = mul nsw nuw i32 %i, 3
150 %mul_within = icmp ult i32 %i.mul.3, 64
151 br i1 %mul_within, label %guarded, label %continue.2
154 %i.mul.3.inc = add nsw nuw i32 %i.mul.3, 1
155 %result = icmp slt i32 %i.mul.3.inc, %limit
156 br i1 %result, label %continue.2, label %for.end
159 %i.i64 = zext i32 %i to i64
160 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
161 %val = load i32, i32* %arrayidx, align 4
165 %i.inc = add nsw nuw i32 %i, 1
166 %cmp = icmp slt i32 %i.inc, %limit
167 br i1 %cmp, label %for.body, label %for.end
177 declare void @llvm.experimental.guard(i1, ...)
179 define void @test_guard_one_bb(i32* %base, i32 %limit, i32 %start) {
180 ; CHECK-LABEL: @test_guard_one_bb(
182 ; CHECK-NOT: icmp slt i32
188 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.body ]
189 %within_limits = icmp ult i32 %i, 64
190 %i.i64 = zext i32 %i to i64
191 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
192 %val = load i32, i32* %arrayidx, align 4
193 call void(i1, ...) @llvm.experimental.guard(i1 %within_limits) [ "deopt"() ]
194 %i.inc = add nsw nuw i32 %i, 1
195 %cmp = icmp slt i32 %i.inc, %limit
196 br i1 %cmp, label %for.body, label %for.end
205 define void @test_guard_in_the_same_bb(i32* %base, i32 %limit, i32 %start) {
206 ; CHECK-LABEL: @test_guard_in_the_same_bb(
208 ; CHECK-NOT: icmp slt i32
214 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
215 %within_limits = icmp ult i32 %i, 64
216 %i.i64 = zext i32 %i to i64
217 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
218 %val = load i32, i32* %arrayidx, align 4
222 call void(i1, ...) @llvm.experimental.guard(i1 %within_limits) [ "deopt"() ]
223 %i.inc = add nsw nuw i32 %i, 1
224 %cmp = icmp slt i32 %i.inc, %limit
225 br i1 %cmp, label %for.body, label %for.end
234 define void @test_guard_in_idom(i32* %base, i32 %limit, i32 %start) {
235 ; CHECK-LABEL: @test_guard_in_idom(
237 ; CHECK-NOT: icmp slt i32
243 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
244 %within_limits = icmp ult i32 %i, 64
245 call void(i1, ...) @llvm.experimental.guard(i1 %within_limits) [ "deopt"() ]
246 %i.i64 = zext i32 %i to i64
247 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
248 %val = load i32, i32* %arrayidx, align 4
252 %i.inc = add nsw nuw i32 %i, 1
253 %cmp = icmp slt i32 %i.inc, %limit
254 br i1 %cmp, label %for.body, label %for.end
263 define void @test_guard_merge_ranges(i32* %base, i32 %limit, i32 %start) {
264 ; CHECK-LABEL: @test_guard_merge_ranges(
266 ; CHECK-NOT: icmp slt i32
272 %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.body ]
273 %within_limits.1 = icmp ult i32 %i, 64
274 call void(i1, ...) @llvm.experimental.guard(i1 %within_limits.1) [ "deopt"() ]
275 %within_limits.2 = icmp ult i32 %i, 2147483647
276 call void(i1, ...) @llvm.experimental.guard(i1 %within_limits.2) [ "deopt"() ]
277 %i.i64 = zext i32 %i to i64
278 %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
279 %val = load i32, i32* %arrayidx, align 4
280 %i.inc = add nsw nuw i32 %i, 1
281 %cmp = icmp slt i32 %i.inc, %limit
282 br i1 %cmp, label %for.body, label %for.end