xref: /llvm-project/llvm/test/Instrumentation/BoundsChecking/opt.ll (revision e87afb9730d4cf8cd8c6f9c2f45e8e5f040bb8e9)
1; RUN: opt < %s -passes=bounds-checking -S | FileCheck %s
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3
4; CHECK-LABEL: @sumSize
5define dso_local i32 @sumSize(i32 %n) {
6entry:
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)
10  br label %for.body.i
11
12for.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
16; CHECK-NOT: trap
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
22
23accumulate.exit:                                  ; preds = %for.body.i
24  call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %foo)
25  ret i32 %add.i
26}
27
28declare void @llvm.lifetime.start.p0(i64, ptr nocapture)
29
30declare dso_local void @fill(ptr, i32)
31
32declare void @llvm.lifetime.end.p0(i64, ptr nocapture)
33
34; CHECK-LABEL: @sumSizePlusOne
35define dso_local i32 @sumSizePlusOne(i32 %n) {
36entry:
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)
40  br label %for.body.i
41
42for.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
49; CHECK-NEXT: or i1
50; CHECK: trap
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
56
57accumulate.exit:                                  ; preds = %for.body.i
58  call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %foo)
59  ret i32 %add.i
60}
61
62; CHECK-LABEL: @sumLarger
63define dso_local i32 @sumLarger(i32 %n) {
64entry:
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)
68  br label %for.body.i
69
70for.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
78; CHECK-NEXT: or i1
79; CHECK: trap
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
85
86accumulate.exit:                                  ; preds = %for.body.i
87  call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %foo)
88  ret i32 %add.i
89}
90
91; CHECK-LABEL: @sumUnknown
92define dso_local i32 @sumUnknown(i32 %n) {
93entry:
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
99
100for.body.preheader.i:                             ; preds = %entry
101  %wide.trip.count.i = zext i32 %n to i64
102  br label %for.body.i
103
104for.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
112; CHECK-NEXT: or i1
113; CHECK: trap
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
119
120accumulate.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
124}
125
126; CHECK-LABEL: @twoDimSize
127define dso_local i32 @twoDimSize(i32 %n) {
128entry:
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
133
134for.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 ]
137  br label %for.body4
138
139for.cond.cleanup:                                 ; preds = %for.cond.cleanup3
140  call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %foo)
141  ret i32 %add
142
143for.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
147
148for.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
152; CHECK-NOT: trap
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
158}
159
160; CHECK-LABEL: @twoDimLarger1
161define dso_local i32 @twoDimLarger1(i32 %n) {
162entry:
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
167
168for.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 ]
171  br label %for.body4
172
173for.cond.cleanup:                                 ; preds = %for.cond.cleanup3
174  call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %foo)
175  ret i32 %add
176
177for.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
181
182for.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
188; CHECK: add i64
189; CHECK: sub i64 16, %
190; CHECK-NEXT: icmp ult i64 16, %
191; CHECK-NEXT: icmp ult i64 {{.*}}, 4
192; CHECK-NEXT: or i1
193; CHECK: trap
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
199}
200
201; CHECK-LABEL: @twoDimLarger2
202define dso_local i32 @twoDimLarger2(i32 %n) {
203entry:
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
208
209for.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 ]
212  br label %for.body4
213
214for.cond.cleanup:                                 ; preds = %for.cond.cleanup3
215  call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %foo)
216  ret i32 %add
217
218for.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
222
223for.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
229; CHECK: add i64
230; CHECK: sub i64 16, %
231; CHECK-NEXT: icmp ult i64 {{.*}}, 4
232; CHECK-NEXT: or i1
233; CHECK: trap
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
239}
240
241; CHECK-LABEL: @twoDimUnknown
242define dso_local i32 @twoDimUnknown(i32 %n) {
243entry:
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
249
250for.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
254
255for.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 ]
258  br label %for.body4
259
260for.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)
263  ret i32 %sum.0.lcssa
264
265for.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
269
270for.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
276; CHECK: add i64
277; CHECK: sub i64 16, %
278; CHECK-NEXT: icmp ult i64 16, %
279; CHECK-NEXT: icmp ult i64 {{.*}}, 4
280; CHECK-NEXT: or i1
281; CHECK: trap
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
287}
288
289; CHECK-LABEL: @countDownGood
290define dso_local i32 @countDownGood(i32 %n) {
291entry:
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)
295  br label %for.body
296
297for.cond.cleanup:                                 ; preds = %for.body
298  call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %foo)
299  ret i32 %add
300
301for.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
305; CHECK-NOT: trap
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
311}
312
313; CHECK-LABEL: @countDownBad
314define dso_local i32 @countDownBad(i32 %n) {
315entry:
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)
319  br label %for.body
320
321for.cond.cleanup:                                 ; preds = %for.body
322  call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %foo)
323  ret i32 %add
324
325for.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, %
332; CHECK: trap
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
338}
339