1 ; RUN: llc -mtriple=i686 -O0 < %s | FileCheck %s
2 ; RUN: llc -mtriple=x86_64 -O0 < %s | FileCheck %s
4 ; CHECK-LABEL: in_bounds:
5 ; CHECK-NOT: __stack_chk_guard
6 define i32 @in_bounds() #0 {
7 %var = alloca i32, align 4
8 store i32 0, i32* %var, align 4
9 %gep = getelementptr inbounds i32, i32* %var, i32 0
10 %ret = load i32, i32* %gep, align 4
14 ; CHECK-LABEL: constant_out_of_bounds:
15 ; CHECK: __stack_chk_guard
16 define i32 @constant_out_of_bounds() #0 {
17 %var = alloca i32, align 4
18 store i32 0, i32* %var, align 4
19 %gep = getelementptr inbounds i32, i32* %var, i32 1
20 %ret = load i32, i32* %gep, align 4
24 ; CHECK-LABEL: nonconstant_out_of_bounds:
25 ; CHECK: __stack_chk_guard
26 define i32 @nonconstant_out_of_bounds(i32 %n) #0 {
27 %var = alloca i32, align 4
28 store i32 0, i32* %var, align 4
29 %gep = getelementptr inbounds i32, i32* %var, i32 %n
30 %ret = load i32, i32* %gep, align 4
34 ; CHECK-LABEL: phi_before_gep_in_bounds:
35 ; CHECK-NOT: __stack_chk_guard
36 define i32 @phi_before_gep_in_bounds(i32 %k) #0 {
38 %var1 = alloca i32, align 4
39 %var2 = alloca i32, align 4
40 store i32 0, i32* %var1, align 4
41 store i32 0, i32* %var2, align 4
42 %cmp = icmp ne i32 %k, 0
43 br i1 %cmp, label %if, label %then
49 %ptr = phi i32* [ %var1, %entry ], [ %var2, %if ]
50 %gep = getelementptr inbounds i32, i32* %ptr, i32 0
51 %ret = load i32, i32* %gep, align 4
55 ; CHECK-LABEL: phi_before_gep_constant_out_of_bounds:
56 ; CHECK: __stack_chk_guard
57 define i32 @phi_before_gep_constant_out_of_bounds(i32 %k) #0 {
59 %var1 = alloca i32, align 4
60 %var2 = alloca i32, align 4
61 store i32 0, i32* %var1, align 4
62 store i32 0, i32* %var2, align 4
63 %cmp = icmp ne i32 %k, 0
64 br i1 %cmp, label %if, label %then
70 %ptr = phi i32* [ %var1, %entry ], [ %var2, %if ]
71 %gep = getelementptr inbounds i32, i32* %ptr, i32 1
72 %ret = load i32, i32* %gep, align 4
76 ; CHECK-LABEL: phi_before_gep_nonconstant_out_of_bounds:
77 ; CHECK: __stack_chk_guard
78 define i32 @phi_before_gep_nonconstant_out_of_bounds(i32 %k, i32 %n) #0 {
80 %var1 = alloca i32, align 4
81 %var2 = alloca i32, align 4
82 store i32 0, i32* %var1, align 4
83 store i32 0, i32* %var2, align 4
84 %cmp = icmp ne i32 %k, 0
85 br i1 %cmp, label %if, label %then
91 %ptr = phi i32* [ %var1, %entry ], [ %var2, %if ]
92 %gep = getelementptr inbounds i32, i32* %ptr, i32 %n
93 %ret = load i32, i32* %gep, align 4
97 ; CHECK-LABEL: phi_after_gep_in_bounds:
98 ; CHECK-NOT: __stack_chk_guard
99 define i32 @phi_after_gep_in_bounds(i32 %k) #0 {
101 %var1 = alloca i32, align 4
102 %var2 = alloca i32, align 4
103 store i32 0, i32* %var1, align 4
104 store i32 0, i32* %var2, align 4
105 %cmp = icmp ne i32 %k, 0
106 br i1 %cmp, label %if, label %else
109 %gep1 = getelementptr inbounds i32, i32* %var1, i32 0
113 %gep2 = getelementptr inbounds i32, i32* %var2, i32 0
117 %ptr = phi i32* [ %gep1, %if ], [ %gep2, %else ]
118 %ret = load i32, i32* %ptr, align 4
122 ; CHECK-LABEL: phi_after_gep_constant_out_of_bounds_a:
123 ; CHECK: __stack_chk_guard
124 define i32 @phi_after_gep_constant_out_of_bounds_a(i32 %k) #0 {
126 %var1 = alloca i32, align 4
127 %var2 = alloca i32, align 4
128 store i32 0, i32* %var1, align 4
129 store i32 0, i32* %var2, align 4
130 %cmp = icmp ne i32 %k, 0
131 br i1 %cmp, label %if, label %else
134 %gep1 = getelementptr inbounds i32, i32* %var1, i32 0
138 %gep2 = getelementptr inbounds i32, i32* %var2, i32 1
142 %ptr = phi i32* [ %gep1, %if ], [ %gep2, %else ]
143 %ret = load i32, i32* %ptr, align 4
147 ; CHECK-LABEL: phi_after_gep_constant_out_of_bounds_b:
148 ; CHECK: __stack_chk_guard
149 define i32 @phi_after_gep_constant_out_of_bounds_b(i32 %k) #0 {
151 %var1 = alloca i32, align 4
152 %var2 = alloca i32, align 4
153 store i32 0, i32* %var1, align 4
154 store i32 0, i32* %var2, align 4
155 %cmp = icmp ne i32 %k, 0
156 br i1 %cmp, label %if, label %else
159 %gep1 = getelementptr inbounds i32, i32* %var1, i32 1
163 %gep2 = getelementptr inbounds i32, i32* %var2, i32 0
167 %ptr = phi i32* [ %gep1, %if ], [ %gep2, %else ]
168 %ret = load i32, i32* %ptr, align 4
172 ; CHECK-LABEL: phi_different_types_a:
173 ; CHECK: __stack_chk_guard
174 define i64 @phi_different_types_a(i32 %k) #0 {
176 %var1 = alloca i64, align 4
177 %var2 = alloca i32, align 4
178 store i64 0, i64* %var1, align 4
179 store i32 0, i32* %var2, align 4
180 %cmp = icmp ne i32 %k, 0
181 br i1 %cmp, label %if, label %then
184 %bitcast = bitcast i32* %var2 to i64*
188 %ptr = phi i64* [ %var1, %entry ], [ %bitcast, %if ]
189 %ret = load i64, i64* %ptr, align 4
193 ; CHECK-LABEL: phi_different_types_b:
194 ; CHECK: __stack_chk_guard
195 define i64 @phi_different_types_b(i32 %k) #0 {
197 %var1 = alloca i32, align 4
198 %var2 = alloca i64, align 4
199 store i32 0, i32* %var1, align 4
200 store i64 0, i64* %var2, align 4
201 %cmp = icmp ne i32 %k, 0
202 br i1 %cmp, label %if, label %then
205 %bitcast = bitcast i32* %var1 to i64*
209 %ptr = phi i64* [ %var2, %entry ], [ %bitcast, %if ]
210 %ret = load i64, i64* %ptr, align 4
214 ; CHECK-LABEL: phi_after_gep_nonconstant_out_of_bounds_a:
215 ; CHECK: __stack_chk_guard
216 define i32 @phi_after_gep_nonconstant_out_of_bounds_a(i32 %k, i32 %n) #0 {
218 %var1 = alloca i32, align 4
219 %var2 = alloca i32, align 4
220 store i32 0, i32* %var1, align 4
221 store i32 0, i32* %var2, align 4
222 %cmp = icmp ne i32 %k, 0
223 br i1 %cmp, label %if, label %else
226 %gep1 = getelementptr inbounds i32, i32* %var1, i32 0
230 %gep2 = getelementptr inbounds i32, i32* %var2, i32 %n
234 %ptr = phi i32* [ %gep1, %if ], [ %gep2, %else ]
235 %ret = load i32, i32* %ptr, align 4
239 ; CHECK-LABEL: phi_after_gep_nonconstant_out_of_bounds_b:
240 ; CHECK: __stack_chk_guard
241 define i32 @phi_after_gep_nonconstant_out_of_bounds_b(i32 %k, i32 %n) #0 {
243 %var1 = alloca i32, align 4
244 %var2 = alloca i32, align 4
245 store i32 0, i32* %var1, align 4
246 store i32 0, i32* %var2, align 4
247 %cmp = icmp ne i32 %k, 0
248 br i1 %cmp, label %if, label %else
251 %gep1 = getelementptr inbounds i32, i32* %var1, i32 %n
255 %gep2 = getelementptr inbounds i32, i32* %var2, i32 0
259 %ptr = phi i32* [ %gep1, %if ], [ %gep2, %else ]
260 %ret = load i32, i32* %ptr, align 4
264 %struct.outer = type { %struct.inner, %struct.inner }
265 %struct.inner = type { i32, i32 }
267 ; CHECK-LABEL: struct_in_bounds:
268 ; CHECK-NOT: __stack_chk_guard
269 define void @struct_in_bounds() #0 {
270 %var = alloca %struct.outer, align 4
271 %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 0, i32 1
272 %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 0, i32 1
273 store i32 0, i32* %innergep, align 4
277 ; CHECK-LABEL: struct_constant_out_of_bounds_a:
278 ; CHECK: __stack_chk_guard
279 define void @struct_constant_out_of_bounds_a() #0 {
280 %var = alloca %struct.outer, align 4
281 %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 1, i32 0
282 %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 0, i32 0
283 store i32 0, i32* %innergep, align 4
287 ; CHECK-LABEL: struct_constant_out_of_bounds_b:
288 ; Here the offset is out-of-bounds of the addressed struct.inner member, but
289 ; still within bounds of the outer struct so no stack guard is needed.
290 ; CHECK-NOT: __stack_chk_guard
291 define void @struct_constant_out_of_bounds_b() #0 {
292 %var = alloca %struct.outer, align 4
293 %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 0, i32 0
294 %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 1, i32 0
295 store i32 0, i32* %innergep, align 4
299 ; CHECK-LABEL: struct_constant_out_of_bounds_c:
300 ; Here we are out-of-bounds of both the inner and outer struct.
301 ; CHECK: __stack_chk_guard
302 define void @struct_constant_out_of_bounds_c() #0 {
303 %var = alloca %struct.outer, align 4
304 %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 0, i32 1
305 %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 1, i32 0
306 store i32 0, i32* %innergep, align 4
310 ; CHECK-LABEL: struct_nonconstant_out_of_bounds_a:
311 ; CHECK: __stack_chk_guard
312 define void @struct_nonconstant_out_of_bounds_a(i32 %n) #0 {
313 %var = alloca %struct.outer, align 4
314 %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 %n, i32 0
315 %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 0, i32 0
316 store i32 0, i32* %innergep, align 4
320 ; CHECK-LABEL: struct_nonconstant_out_of_bounds_b:
321 ; CHECK: __stack_chk_guard
322 define void @struct_nonconstant_out_of_bounds_b(i32 %n) #0 {
323 %var = alloca %struct.outer, align 4
324 %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 0, i32 0
325 %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 %n, i32 0
326 store i32 0, i32* %innergep, align 4
330 ; CHECK-LABEL: bitcast_smaller_load
331 ; CHECK-NOT: __stack_chk_guard
332 define i32 @bitcast_smaller_load() #0 {
333 %var = alloca i64, align 4
334 store i64 0, i64* %var, align 4
335 %bitcast = bitcast i64* %var to i32*
336 %ret = load i32, i32* %bitcast, align 4
340 ; CHECK-LABEL: bitcast_same_size_load
341 ; CHECK-NOT: __stack_chk_guard
342 define i32 @bitcast_same_size_load() #0 {
343 %var = alloca i64, align 4
344 store i64 0, i64* %var, align 4
345 %bitcast = bitcast i64* %var to %struct.inner*
346 %gep = getelementptr inbounds %struct.inner, %struct.inner* %bitcast, i32 0, i32 1
347 %ret = load i32, i32* %gep, align 4
351 ; CHECK-LABEL: bitcast_larger_load
352 ; CHECK: __stack_chk_guard
353 define i64 @bitcast_larger_load() #0 {
354 %var = alloca i32, align 4
355 store i32 0, i32* %var, align 4
356 %bitcast = bitcast i32* %var to i64*
357 %ret = load i64, i64* %bitcast, align 4
361 ; CHECK-LABEL: bitcast_larger_store
362 ; CHECK: __stack_chk_guard
363 define i32 @bitcast_larger_store() #0 {
364 %var = alloca i32, align 4
365 %bitcast = bitcast i32* %var to i64*
366 store i64 0, i64* %bitcast, align 4
367 %ret = load i32, i32* %var, align 4
371 ; CHECK-LABEL: bitcast_larger_cmpxchg
372 ; CHECK: __stack_chk_guard
373 define i64 @bitcast_larger_cmpxchg(i64 %desired, i64 %new) #0 {
374 %var = alloca i32, align 4
375 %bitcast = bitcast i32* %var to i64*
376 %pair = cmpxchg i64* %bitcast, i64 %desired, i64 %new seq_cst monotonic
377 %ret = extractvalue { i64, i1 } %pair, 0
381 ; CHECK-LABEL: bitcast_larger_atomic_rmw
382 ; CHECK: __stack_chk_guard
383 define i64 @bitcast_larger_atomic_rmw() #0 {
384 %var = alloca i32, align 4
385 %bitcast = bitcast i32* %var to i64*
386 %ret = atomicrmw add i64* %bitcast, i64 1 monotonic
390 %struct.packed = type <{ i16, i32 }>
392 ; CHECK-LABEL: bitcast_overlap
393 ; CHECK: __stack_chk_guard
394 define i32 @bitcast_overlap() #0 {
395 %var = alloca i32, align 4
396 %bitcast = bitcast i32* %var to %struct.packed*
397 %gep = getelementptr inbounds %struct.packed, %struct.packed* %bitcast, i32 0, i32 1
398 %ret = load i32, i32* %gep, align 2
402 %struct.multi_dimensional = type { [10 x [10 x i32]], i32 }
404 ; CHECK-LABEL: multi_dimensional_array
405 ; CHECK: __stack_chk_guard
406 define i32 @multi_dimensional_array() #0 {
407 %var = alloca %struct.multi_dimensional, align 4
408 %gep1 = getelementptr inbounds %struct.multi_dimensional, %struct.multi_dimensional* %var, i32 0, i32 0
409 %gep2 = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* %gep1, i32 0, i32 10
410 %gep3 = getelementptr inbounds [10 x i32], [10 x i32]* %gep2, i32 0, i32 5
411 %ret = load i32, i32* %gep3, align 4
415 attributes #0 = { sspstrong }