• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -indvars -indvars-post-increment-ranges -S | FileCheck %s
2
3target datalayout = "p:64:64:64-n32:64"
4
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.
9define void @test(i32* %base, i32 %limit, i32 %start) {
10; CHECK-LABEL: @test(
11; CHECK-NOT: trunc
12
13for.body.lr.ph:
14  br label %for.body
15
16for.body:
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
20
21continue:
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
25  br label %for.inc
26
27for.inc:
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
31
32for.end:
33  br label %exit
34
35exit:
36  ret void
37}
38
39define void @test_false_edge(i32* %base, i32 %limit, i32 %start) {
40; CHECK-LABEL: @test_false_edge(
41; CHECK-NOT: trunc
42
43for.body.lr.ph:
44  br label %for.body
45
46for.body:
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
50
51continue:
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
55  br label %for.inc
56
57for.inc:
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
61
62for.end:
63  br label %exit
64
65exit:
66  ret void
67}
68
69define void @test_range_metadata(i32* %array_length_ptr, i32* %base,
70                                 i32 %limit, i32 %start) {
71; CHECK-LABEL: @test_range_metadata(
72; CHECK-NOT: trunc
73
74for.body.lr.ph:
75  br label %for.body
76
77for.body:
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
82
83continue:
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
87  br label %for.inc
88
89for.inc:
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
93
94for.end:
95  br label %exit
96
97exit:
98  ret void
99}
100
101; Negative version of the test above, we don't know anything about
102; array_length_ptr range.
103define void @test_neg(i32* %array_length_ptr, i32* %base,
104                      i32 %limit, i32 %start) {
105; CHECK-LABEL: @test_neg(
106; CHECK: trunc i64
107
108for.body.lr.ph:
109  br label %for.body
110
111for.body:
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
116
117continue:
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
121  br label %for.inc
122
123for.inc:
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
127
128for.end:
129  br label %exit
130
131exit:
132  ret void
133}
134
135define void @test_transitive_use(i32* %base, i32 %limit, i32 %start) {
136; CHECK-LABEL: @test_transitive_use(
137; CHECK-NOT: trunc
138; CHECK: %result = icmp slt i64
139
140for.body.lr.ph:
141  br label %for.body
142
143for.body:
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
147
148continue:
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
152
153guarded:
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
157
158continue.2:
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
162  br label %for.inc
163
164for.inc:
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
168
169
170for.end:
171  br label %exit
172
173exit:
174  ret void
175}
176
177declare void @llvm.experimental.guard(i1, ...)
178
179define void @test_guard_one_bb(i32* %base, i32 %limit, i32 %start) {
180; CHECK-LABEL: @test_guard_one_bb(
181; CHECK-NOT: trunc
182; CHECK-NOT: icmp slt i32
183
184for.body.lr.ph:
185  br label %for.body
186
187for.body:
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
197
198for.end:
199  br label %exit
200
201exit:
202  ret void
203}
204
205define void @test_guard_in_the_same_bb(i32* %base, i32 %limit, i32 %start) {
206; CHECK-LABEL: @test_guard_in_the_same_bb(
207; CHECK-NOT: trunc
208; CHECK-NOT: icmp slt i32
209
210for.body.lr.ph:
211  br label %for.body
212
213for.body:
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
219  br label %for.inc
220
221for.inc:
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
226
227for.end:
228  br label %exit
229
230exit:
231  ret void
232}
233
234define void @test_guard_in_idom(i32* %base, i32 %limit, i32 %start) {
235; CHECK-LABEL: @test_guard_in_idom(
236; CHECK-NOT: trunc
237; CHECK-NOT: icmp slt i32
238
239for.body.lr.ph:
240  br label %for.body
241
242for.body:
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
249  br label %for.inc
250
251for.inc:
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
255
256for.end:
257  br label %exit
258
259exit:
260  ret void
261}
262
263define void @test_guard_merge_ranges(i32* %base, i32 %limit, i32 %start) {
264; CHECK-LABEL: @test_guard_merge_ranges(
265; CHECK-NOT: trunc
266; CHECK-NOT: icmp slt i32
267
268for.body.lr.ph:
269  br label %for.body
270
271for.body:
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
283
284for.end:
285  br label %exit
286
287exit:
288  ret void
289}
290