1 ; RUN: opt < %s -passes=bounds-checking -S | FileCheck %s
2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4 ; CHECK-LABEL: @sumSize
5 define dso_local i32 @sumSize(i32 %n) {
7 %foo = alloca [1000 x i32], align 16
8 call void @llvm.lifetime.start.p0(i64 4000, ptr nonnull %foo)
9 call void @fill(ptr nonnull %foo, i32 %n)
12 for.body.i: ; preds = %for.body.i, %entry
13 %indvars.iv.i = phi i64 [ 0, %entry ], [ %indvars.iv.next.i, %for.body.i ]
14 %sum.07.i = phi i32 [ 0, %entry ], [ %add.i, %for.body.i ]
15 %arrayidx.i = getelementptr inbounds [1000 x i32], ptr %foo, i64 0, i64 %indvars.iv.i
17 %0 = load i32, ptr %arrayidx.i, align 4
18 %add.i = add nsw i32 %0, %sum.07.i
19 %indvars.iv.next.i = add nuw nsw i64 %indvars.iv.i, 1
20 %exitcond.i = icmp eq i64 %indvars.iv.next.i, 1000
21 br i1 %exitcond.i, label %accumulate.exit, label %for.body.i
23 accumulate.exit: ; preds = %for.body.i
24 call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %foo)
28 declare void @llvm.lifetime.start.p0(i64, ptr nocapture)
30 declare dso_local void @fill(ptr, i32)
32 declare void @llvm.lifetime.end.p0(i64, ptr nocapture)
34 ; CHECK-LABEL: @sumSizePlusOne
35 define dso_local i32 @sumSizePlusOne(i32 %n) {
37 %foo = alloca [1000 x i32], align 16
38 call void @llvm.lifetime.start.p0(i64 4000, ptr nonnull %foo)
39 call void @fill(ptr nonnull %foo, i32 %n)
42 for.body.i: ; preds = %for.body.i, %entry
43 %indvars.iv.i = phi i64 [ 0, %entry ], [ %indvars.iv.next.i, %for.body.i ]
44 %sum.01.i = phi i32 [ 0, %entry ], [ %add.i, %for.body.i ]
45 %arrayidx.i = getelementptr inbounds [1000 x i32], ptr %foo, i64 0, i64 %indvars.iv.i
46 ; CHECK: mul i64 {{.*}}, 4
47 ; CHECK: sub i64 4000, %
48 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
51 %0 = load i32, ptr %arrayidx.i, align 4
52 %add.i = add nsw i32 %0, %sum.01.i
53 %indvars.iv.next.i = add nuw nsw i64 %indvars.iv.i, 1
54 %exitcond.i = icmp eq i64 %indvars.iv.next.i, 1001
55 br i1 %exitcond.i, label %accumulate.exit, label %for.body.i
57 accumulate.exit: ; preds = %for.body.i
58 call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %foo)
62 ; CHECK-LABEL: @sumLarger
63 define dso_local i32 @sumLarger(i32 %n) {
65 %foo = alloca [1000 x i32], align 16
66 call void @llvm.lifetime.start.p0(i64 4000, ptr nonnull %foo)
67 call void @fill(ptr nonnull %foo, i32 %n)
70 for.body.i: ; preds = %for.body.i, %entry
71 %indvars.iv.i = phi i64 [ 0, %entry ], [ %indvars.iv.next.i, %for.body.i ]
72 %sum.07.i = phi i32 [ 0, %entry ], [ %add.i, %for.body.i ]
73 %arrayidx.i = getelementptr inbounds [1000 x i32], ptr %foo, i64 0, i64 %indvars.iv.i
74 ; CHECK: mul i64 {{.*}}, 4
75 ; CHECK: sub i64 4000, %
76 ; CHECK-NEXT: icmp ult i64 4000, %
77 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
80 %0 = load i32, ptr %arrayidx.i, align 4
81 %add.i = add nsw i32 %0, %sum.07.i
82 %indvars.iv.next.i = add nuw nsw i64 %indvars.iv.i, 1
83 %exitcond.i = icmp eq i64 %indvars.iv.next.i, 2000
84 br i1 %exitcond.i, label %accumulate.exit, label %for.body.i
86 accumulate.exit: ; preds = %for.body.i
87 call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %foo)
91 ; CHECK-LABEL: @sumUnknown
92 define dso_local i32 @sumUnknown(i32 %n) {
94 %foo = alloca [1000 x i32], align 16
95 call void @llvm.lifetime.start.p0(i64 4000, ptr nonnull %foo)
96 call void @fill(ptr nonnull %foo, i32 %n)
97 %cmp6.i = icmp eq i32 %n, 0
98 br i1 %cmp6.i, label %accumulate.exit, label %for.body.preheader.i
100 for.body.preheader.i: ; preds = %entry
101 %wide.trip.count.i = zext i32 %n to i64
104 for.body.i: ; preds = %for.body.i, %for.body.preheader.i
105 %indvars.iv.i = phi i64 [ 0, %for.body.preheader.i ], [ %indvars.iv.next.i, %for.body.i ]
106 %sum.07.i = phi i32 [ 0, %for.body.preheader.i ], [ %add.i, %for.body.i ]
107 %arrayidx.i = getelementptr inbounds [1000 x i32], ptr %foo, i64 0, i64 %indvars.iv.i
108 ; CHECK: mul i64 {{.*}}, 4
109 ; CHECK: sub i64 4000, %
110 ; CHECK-NEXT: icmp ult i64 4000, %
111 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
114 %0 = load i32, ptr %arrayidx.i, align 4
115 %add.i = add nsw i32 %0, %sum.07.i
116 %indvars.iv.next.i = add nuw nsw i64 %indvars.iv.i, 1
117 %exitcond.i = icmp eq i64 %indvars.iv.next.i, %wide.trip.count.i
118 br i1 %exitcond.i, label %accumulate.exit, label %for.body.i
120 accumulate.exit: ; preds = %for.body.i, %entry
121 %sum.0.lcssa.i = phi i32 [ 0, %entry ], [ %add.i, %for.body.i ]
122 call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %foo)
123 ret i32 %sum.0.lcssa.i
126 ; CHECK-LABEL: @twoDimSize
127 define dso_local i32 @twoDimSize(i32 %n) {
129 %foo = alloca [2 x [2 x i32]], align 16
130 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %foo)
131 call void @fill(ptr nonnull %foo, i32 %n)
132 br label %for.cond1.preheader
134 for.cond1.preheader: ; preds = %for.cond.cleanup3, %entry
135 %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for.cond.cleanup3 ]
136 %sum.021 = phi i32 [ 0, %entry ], [ %add, %for.cond.cleanup3 ]
139 for.cond.cleanup: ; preds = %for.cond.cleanup3
140 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %foo)
143 for.cond.cleanup3: ; preds = %for.body4
144 %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
145 %exitcond25 = icmp eq i64 %indvars.iv.next24, 2
146 br i1 %exitcond25, label %for.cond.cleanup, label %for.cond1.preheader
148 for.body4: ; preds = %for.body4, %for.cond1.preheader
149 %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.body4 ]
150 %sum.119 = phi i32 [ %sum.021, %for.cond1.preheader ], [ %add, %for.body4 ]
151 %arrayidx7 = getelementptr inbounds [2 x [2 x i32]], ptr %foo, i64 0, i64 %indvars.iv23, i64 %indvars.iv
153 %0 = load i32, ptr %arrayidx7, align 4
154 %add = add nsw i32 %0, %sum.119
155 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
156 %exitcond = icmp eq i64 %indvars.iv.next, 2
157 br i1 %exitcond, label %for.cond.cleanup3, label %for.body4
160 ; CHECK-LABEL: @twoDimLarger1
161 define dso_local i32 @twoDimLarger1(i32 %n) {
163 %foo = alloca [2 x [2 x i32]], align 16
164 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %foo)
165 call void @fill(ptr nonnull %foo, i32 %n)
166 br label %for.cond1.preheader
168 for.cond1.preheader: ; preds = %for.cond.cleanup3, %entry
169 %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for.cond.cleanup3 ]
170 %sum.021 = phi i32 [ 0, %entry ], [ %add, %for.cond.cleanup3 ]
173 for.cond.cleanup: ; preds = %for.cond.cleanup3
174 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %foo)
177 for.cond.cleanup3: ; preds = %for.body4
178 %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
179 %exitcond25 = icmp eq i64 %indvars.iv.next24, 3
180 br i1 %exitcond25, label %for.cond.cleanup, label %for.cond1.preheader
182 for.body4: ; preds = %for.body4, %for.cond1.preheader
183 %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.body4 ]
184 %sum.119 = phi i32 [ %sum.021, %for.cond1.preheader ], [ %add, %for.body4 ]
185 %arrayidx7 = getelementptr inbounds [2 x [2 x i32]], ptr %foo, i64 0, i64 %indvars.iv23, i64 %indvars.iv
186 ; CHECK: mul i64 {{.*}}, 8
187 ; CHECK: mul i64 {{.*}}, 4
189 ; CHECK: sub i64 16, %
190 ; CHECK-NEXT: icmp ult i64 16, %
191 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
194 %0 = load i32, ptr %arrayidx7, align 4
195 %add = add nsw i32 %0, %sum.119
196 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
197 %exitcond = icmp eq i64 %indvars.iv.next, 2
198 br i1 %exitcond, label %for.cond.cleanup3, label %for.body4
201 ; CHECK-LABEL: @twoDimLarger2
202 define dso_local i32 @twoDimLarger2(i32 %n) {
204 %foo = alloca [2 x [2 x i32]], align 16
205 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %foo)
206 call void @fill(ptr nonnull %foo, i32 %n)
207 br label %for.cond1.preheader
209 for.cond1.preheader: ; preds = %for.cond.cleanup3, %entry
210 %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for.cond.cleanup3 ]
211 %sum.021 = phi i32 [ 0, %entry ], [ %add, %for.cond.cleanup3 ]
214 for.cond.cleanup: ; preds = %for.cond.cleanup3
215 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %foo)
218 for.cond.cleanup3: ; preds = %for.body4
219 %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
220 %exitcond25 = icmp eq i64 %indvars.iv.next24, 2
221 br i1 %exitcond25, label %for.cond.cleanup, label %for.cond1.preheader
223 for.body4: ; preds = %for.body4, %for.cond1.preheader
224 %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.body4 ]
225 %sum.119 = phi i32 [ %sum.021, %for.cond1.preheader ], [ %add, %for.body4 ]
226 %arrayidx7 = getelementptr inbounds [2 x [2 x i32]], ptr %foo, i64 0, i64 %indvars.iv23, i64 %indvars.iv
227 ; CHECK: mul i64 {{.*}}, 8
228 ; CHECK: mul i64 {{.*}}, 4
230 ; CHECK: sub i64 16, %
231 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
234 %0 = load i32, ptr %arrayidx7, align 4
235 %add = add nsw i32 %0, %sum.119
236 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
237 %exitcond = icmp eq i64 %indvars.iv.next, 3
238 br i1 %exitcond, label %for.cond.cleanup3, label %for.body4
241 ; CHECK-LABEL: @twoDimUnknown
242 define dso_local i32 @twoDimUnknown(i32 %n) {
244 %foo = alloca [2 x [2 x i32]], align 16
245 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %foo)
246 call void @fill(ptr nonnull %foo, i32 %n)
247 %cmp24 = icmp eq i32 %n, 0
248 br i1 %cmp24, label %for.cond.cleanup, label %for.cond1.preheader.lr.ph
250 for.cond1.preheader.lr.ph: ; preds = %entry
251 %wide.trip.count = zext i32 %n to i64
252 %wide.trip.count.le = zext i32 %n to i64
253 br label %for.body4.lr.ph
255 for.body4.lr.ph: ; preds = %for.cond1.preheader.lr.ph, %for.cond.cleanup3
256 %indvars.iv28 = phi i64 [ 0, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next29, %for.cond.cleanup3 ]
257 %sum.025 = phi i32 [ 0, %for.cond1.preheader.lr.ph ], [ %add, %for.cond.cleanup3 ]
260 for.cond.cleanup: ; preds = %for.cond.cleanup3, %entry
261 %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.cond.cleanup3 ]
262 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %foo)
265 for.cond.cleanup3: ; preds = %for.body4
266 %indvars.iv.next29 = add nuw nsw i64 %indvars.iv28, 1
267 %exitcond31 = icmp eq i64 %indvars.iv.next29, %wide.trip.count.le
268 br i1 %exitcond31, label %for.cond.cleanup, label %for.body4.lr.ph
270 for.body4: ; preds = %for.body4, %for.body4.lr.ph
271 %indvars.iv = phi i64 [ 0, %for.body4.lr.ph ], [ %indvars.iv.next, %for.body4 ]
272 %sum.122 = phi i32 [ %sum.025, %for.body4.lr.ph ], [ %add, %for.body4 ]
273 %arrayidx7 = getelementptr inbounds [2 x [2 x i32]], ptr %foo, i64 0, i64 %indvars.iv28, i64 %indvars.iv
274 ; CHECK: mul i64 {{.*}}, 8
275 ; CHECK: mul i64 {{.*}}, 4
277 ; CHECK: sub i64 16, %
278 ; CHECK-NEXT: icmp ult i64 16, %
279 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
282 %0 = load i32, ptr %arrayidx7, align 4
283 %add = add nsw i32 %0, %sum.122
284 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
285 %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count
286 br i1 %exitcond, label %for.cond.cleanup3, label %for.body4
289 ; CHECK-LABEL: @countDownGood
290 define dso_local i32 @countDownGood(i32 %n) {
292 %foo = alloca [1000 x i32], align 16
293 call void @llvm.lifetime.start.p0(i64 4000, ptr nonnull %foo)
294 call void @fill(ptr nonnull %foo, i32 %n)
297 for.cond.cleanup: ; preds = %for.body
298 call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %foo)
301 for.body: ; preds = %for.body, %entry
302 %indvars.iv = phi i64 [ 999, %entry ], [ %indvars.iv.next, %for.body ]
303 %sum.06 = phi i32 [ 0, %entry ], [ %add, %for.body ]
304 %arrayidx = getelementptr inbounds [1000 x i32], ptr %foo, i64 0, i64 %indvars.iv
306 %0 = load i32, ptr %arrayidx, align 4
307 %add = add nsw i32 %0, %sum.06
308 %indvars.iv.next = add nsw i64 %indvars.iv, -1
309 %cmp = icmp eq i64 %indvars.iv, 0
310 br i1 %cmp, label %for.cond.cleanup, label %for.body
313 ; CHECK-LABEL: @countDownBad
314 define dso_local i32 @countDownBad(i32 %n) {
316 %foo = alloca [1000 x i32], align 16
317 call void @llvm.lifetime.start.p0(i64 4000, ptr nonnull %foo)
318 call void @fill(ptr nonnull %foo, i32 %n)
321 for.cond.cleanup: ; preds = %for.body
322 call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %foo)
325 for.body: ; preds = %entry, %for.body
326 %indvars.iv = phi i64 [ 999, %entry ], [ %indvars.iv.next, %for.body ]
327 %sum.06 = phi i32 [ 0, %entry ], [ %add, %for.body ]
328 %arrayidx = getelementptr inbounds [1000 x i32], ptr %foo, i64 0, i64 %indvars.iv
329 ; CHECK: mul i64 {{.*}}, 4
330 ; CHECK: sub i64 4000, %
331 ; CHECK-NEXT: icmp ult i64 4000, %
333 %0 = load i32, ptr %arrayidx, align 4
334 %add = add nsw i32 %0, %sum.06
335 %indvars.iv.next = add nsw i64 %indvars.iv, -1
336 %cmp = icmp sgt i64 %indvars.iv, -1
337 br i1 %cmp, label %for.body, label %for.cond.cleanup