[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / PowerPC / stack-guard-oob.ll
blob182d037988fa75962f56c1f1fc5092bf6bb4eb15
1 ; RUN: llc -mtriple=powerpc64le -O0 < %s | FileCheck %s
2 ; RUN: llc -mtriple=powerpc64-ibm-aix-xcoff -O0 < %s | FileCheck %s --check-prefix=AIX
3 ; RUN: llc -mtriple=powerpc-ibm-aix-xcoff -O0 < %s | FileCheck %s --check-prefix=AIX
5 ; CHECK-LABEL: in_bounds:
6 ; CHECK-NOT: __stack_chk_guard
7 ; AIX-NOT: __ssp_canary_word
8 define i32 @in_bounds() #0 {
9   %var = alloca i32, align 4
10   store i32 0, i32* %var, align 4
11   %gep = getelementptr inbounds i32, i32* %var, i32 0
12   %ret = load i32, i32* %gep, align 4
13   ret i32 %ret
16 ; CHECK-LABEL: constant_out_of_bounds:
17 ; CHECK: __stack_chk_guard
18 ; AIX: __ssp_canary_word
19 define i32 @constant_out_of_bounds() #0 {
20   %var = alloca i32, align 4
21   store i32 0, i32* %var, align 4
22   %gep = getelementptr inbounds i32, i32* %var, i32 1
23   %ret = load i32, i32* %gep, align 4
24   ret i32 %ret
27 ; CHECK-LABEL: nonconstant_out_of_bounds:
28 ; CHECK: __stack_chk_guard
29 ; AIX: __ssp_canary_word
30 define i32 @nonconstant_out_of_bounds(i32 %n) #0 {
31   %var = alloca i32, align 4
32   store i32 0, i32* %var, align 4
33   %gep = getelementptr inbounds i32, i32* %var, i32 %n
34   %ret = load i32, i32* %gep, align 4
35   ret i32 %ret
38 ; CHECK-LABEL: phi_before_gep_in_bounds:
39 ; CHECK-NOT: __stack_chk_guard
40 ; AIX-NOT: __ssp_canary_word
41 define i32 @phi_before_gep_in_bounds(i32 %k) #0 {
42 entry:
43   %var1 = alloca i32, align 4
44   %var2 = alloca i32, align 4
45   store i32 0, i32* %var1, align 4
46   store i32 0, i32* %var2, align 4
47   %cmp = icmp ne i32 %k, 0
48   br i1 %cmp, label %if, label %then
50 if:
51   br label %then
53 then:
54   %ptr = phi i32* [ %var1, %entry ], [ %var2, %if ]
55   %gep = getelementptr inbounds i32, i32* %ptr, i32 0
56   %ret = load i32, i32* %gep, align 4
57   ret i32 %ret
60 ; CHECK-LABEL: phi_before_gep_constant_out_of_bounds:
61 ; CHECK: __stack_chk_guard
62 ; AIX: __ssp_canary_word
63 define i32 @phi_before_gep_constant_out_of_bounds(i32 %k) #0 {
64 entry:
65   %var1 = alloca i32, align 4
66   %var2 = alloca i32, align 4
67   store i32 0, i32* %var1, align 4
68   store i32 0, i32* %var2, align 4
69   %cmp = icmp ne i32 %k, 0
70   br i1 %cmp, label %if, label %then
72 if:
73   br label %then
75 then:
76   %ptr = phi i32* [ %var1, %entry ], [ %var2, %if ]
77   %gep = getelementptr inbounds i32, i32* %ptr, i32 1
78   %ret = load i32, i32* %gep, align 4
79   ret i32 %ret
82 ; CHECK-LABEL: phi_before_gep_nonconstant_out_of_bounds:
83 ; CHECK: __stack_chk_guard
84 ; AIX: __ssp_canary_word
85 define i32 @phi_before_gep_nonconstant_out_of_bounds(i32 %k, i32 %n) #0 {
86 entry:
87   %var1 = alloca i32, align 4
88   %var2 = alloca i32, align 4
89   store i32 0, i32* %var1, align 4
90   store i32 0, i32* %var2, align 4
91   %cmp = icmp ne i32 %k, 0
92   br i1 %cmp, label %if, label %then
94 if:
95   br label %then
97 then:
98   %ptr = phi i32* [ %var1, %entry ], [ %var2, %if ]
99   %gep = getelementptr inbounds i32, i32* %ptr, i32 %n
100   %ret = load i32, i32* %gep, align 4
101   ret i32 %ret
104 ; CHECK-LABEL: phi_after_gep_in_bounds:
105 ; CHECK-NOT: __stack_chk_guard
106 ; AIX-NOT: __ssp_canary_word
107 define i32 @phi_after_gep_in_bounds(i32 %k) #0 {
108 entry:
109   %var1 = alloca i32, align 4
110   %var2 = alloca i32, align 4
111   store i32 0, i32* %var1, align 4
112   store i32 0, i32* %var2, align 4
113   %cmp = icmp ne i32 %k, 0
114   br i1 %cmp, label %if, label %else
117   %gep1 = getelementptr inbounds i32, i32* %var1, i32 0
118   br label %then
120 else:
121   %gep2 = getelementptr inbounds i32, i32* %var2, i32 0
122   br label %then
124 then:
125   %ptr = phi i32* [ %gep1, %if ], [ %gep2, %else ]
126   %ret = load i32, i32* %ptr, align 4
127   ret i32 %ret
130 ; CHECK-LABEL: phi_after_gep_constant_out_of_bounds_a:
131 ; CHECK: __stack_chk_guard
132 ; AIX: __ssp_canary_word
133 define i32 @phi_after_gep_constant_out_of_bounds_a(i32 %k) #0 {
134 entry:
135   %var1 = alloca i32, align 4
136   %var2 = alloca i32, align 4
137   store i32 0, i32* %var1, align 4
138   store i32 0, i32* %var2, align 4
139   %cmp = icmp ne i32 %k, 0
140   br i1 %cmp, label %if, label %else
143   %gep1 = getelementptr inbounds i32, i32* %var1, i32 0
144   br label %then
146 else:
147   %gep2 = getelementptr inbounds i32, i32* %var2, i32 1
148   br label %then
150 then:
151   %ptr = phi i32* [ %gep1, %if ], [ %gep2, %else ]
152   %ret = load i32, i32* %ptr, align 4
153   ret i32 %ret
156 ; CHECK-LABEL: phi_after_gep_constant_out_of_bounds_b:
157 ; CHECK: __stack_chk_guard
158 ; AIX: __ssp_canary_word
159 define i32 @phi_after_gep_constant_out_of_bounds_b(i32 %k) #0 {
160 entry:
161   %var1 = alloca i32, align 4
162   %var2 = alloca i32, align 4
163   store i32 0, i32* %var1, align 4
164   store i32 0, i32* %var2, align 4
165   %cmp = icmp ne i32 %k, 0
166   br i1 %cmp, label %if, label %else
169   %gep1 = getelementptr inbounds i32, i32* %var1, i32 1
170   br label %then
172 else:
173   %gep2 = getelementptr inbounds i32, i32* %var2, i32 0
174   br label %then
176 then:
177   %ptr = phi i32* [ %gep1, %if ], [ %gep2, %else ]
178   %ret = load i32, i32* %ptr, align 4
179   ret i32 %ret
182 ; CHECK-LABEL: phi_different_types_a:
183 ; CHECK: __stack_chk_guard
184 ; AIX: __ssp_canary_word
185 define i64 @phi_different_types_a(i32 %k) #0 {
186 entry:
187   %var1 = alloca i64, align 4
188   %var2 = alloca i32, align 4
189   store i64 0, i64* %var1, align 4
190   store i32 0, i32* %var2, align 4
191   %cmp = icmp ne i32 %k, 0
192   br i1 %cmp, label %if, label %then
195   %bitcast = bitcast i32* %var2 to i64*
196   br label %then
198 then:
199   %ptr = phi i64* [ %var1, %entry ], [ %bitcast, %if ]
200   %ret = load i64, i64* %ptr, align 4
201   ret i64 %ret
204 ; CHECK-LABEL: phi_different_types_b:
205 ; CHECK: __stack_chk_guard
206 ; AIX: __ssp_canary_word
207 define i64 @phi_different_types_b(i32 %k) #0 {
208 entry:
209   %var1 = alloca i32, align 4
210   %var2 = alloca i64, align 4
211   store i32 0, i32* %var1, align 4
212   store i64 0, i64* %var2, align 4
213   %cmp = icmp ne i32 %k, 0
214   br i1 %cmp, label %if, label %then
217   %bitcast = bitcast i32* %var1 to i64*
218   br label %then
220 then:
221   %ptr = phi i64* [ %var2, %entry ], [ %bitcast, %if ]
222   %ret = load i64, i64* %ptr, align 4
223   ret i64 %ret
226 ; CHECK-LABEL: phi_after_gep_nonconstant_out_of_bounds_a:
227 ; CHECK: __stack_chk_guard
228 ; AIX: __ssp_canary_word
229 define i32 @phi_after_gep_nonconstant_out_of_bounds_a(i32 %k, i32 %n) #0 {
230 entry:
231   %var1 = alloca i32, align 4
232   %var2 = alloca i32, align 4
233   store i32 0, i32* %var1, align 4
234   store i32 0, i32* %var2, align 4
235   %cmp = icmp ne i32 %k, 0
236   br i1 %cmp, label %if, label %else
239   %gep1 = getelementptr inbounds i32, i32* %var1, i32 0
240   br label %then
242 else:
243   %gep2 = getelementptr inbounds i32, i32* %var2, i32 %n
244   br label %then
246 then:
247   %ptr = phi i32* [ %gep1, %if ], [ %gep2, %else ]
248   %ret = load i32, i32* %ptr, align 4
249   ret i32 %ret
252 ; CHECK-LABEL: phi_after_gep_nonconstant_out_of_bounds_b:
253 ; CHECK: __stack_chk_guard
254 ; AIX: __ssp_canary_word
255 define i32 @phi_after_gep_nonconstant_out_of_bounds_b(i32 %k, i32 %n) #0 {
256 entry:
257   %var1 = alloca i32, align 4
258   %var2 = alloca i32, align 4
259   store i32 0, i32* %var1, align 4
260   store i32 0, i32* %var2, align 4
261   %cmp = icmp ne i32 %k, 0
262   br i1 %cmp, label %if, label %else
265   %gep1 = getelementptr inbounds i32, i32* %var1, i32 %n
266   br label %then
268 else:
269   %gep2 = getelementptr inbounds i32, i32* %var2, i32 0
270   br label %then
272 then:
273   %ptr = phi i32* [ %gep1, %if ], [ %gep2, %else ]
274   %ret = load i32, i32* %ptr, align 4
275   ret i32 %ret
278 %struct.outer = type { %struct.inner, %struct.inner }
279 %struct.inner = type { i32, i32 }
281 ; CHECK-LABEL: struct_in_bounds:
282 ; CHECK-NOT: __stack_chk_guard
283 ; AIX-NOT: __ssp_canary_word
284 define void @struct_in_bounds() #0 {
285   %var = alloca %struct.outer, align 4
286   %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 0, i32 1
287   %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 0, i32 1
288   store i32 0, i32* %innergep, align 4
289   ret void
292 ; CHECK-LABEL: struct_constant_out_of_bounds_a:
293 ; CHECK: __stack_chk_guard
294 ; AIX: __ssp_canary_word
295 define void @struct_constant_out_of_bounds_a() #0 {
296   %var = alloca %struct.outer, align 4
297   %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 1, i32 0
298   %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 0, i32 0
299   store i32 0, i32* %innergep, align 4
300   ret void
303 ; CHECK-LABEL: struct_constant_out_of_bounds_b:
304 ; Here the offset is out-of-bounds of the addressed struct.inner member, but
305 ; still within bounds of the outer struct so no stack guard is needed.
306 ; CHECK-NOT: __stack_chk_guard
307 ; AIX-NOT: __ssp_canary_word
308 define void @struct_constant_out_of_bounds_b() #0 {
309   %var = alloca %struct.outer, align 4
310   %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 0, i32 0
311   %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 1, i32 0
312   store i32 0, i32* %innergep, align 4
313   ret void
316 ; CHECK-LABEL: struct_constant_out_of_bounds_c:
317 ; Here we are out-of-bounds of both the inner and outer struct.
318 ; CHECK: __stack_chk_guard
319 ; AIX: __ssp_canary_word
320 define void @struct_constant_out_of_bounds_c() #0 {
321   %var = alloca %struct.outer, align 4
322   %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 0, i32 1
323   %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 1, i32 0
324   store i32 0, i32* %innergep, align 4
325   ret void
328 ; CHECK-LABEL: struct_nonconstant_out_of_bounds_a:
329 ; CHECK: __stack_chk_guard
330 ; AIX: __ssp_canary_word
331 define void @struct_nonconstant_out_of_bounds_a(i32 %n) #0 {
332   %var = alloca %struct.outer, align 4
333   %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 %n, i32 0
334   %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 0, i32 0
335   store i32 0, i32* %innergep, align 4
336   ret void
339 ; CHECK-LABEL: struct_nonconstant_out_of_bounds_b:
340 ; CHECK: __stack_chk_guard
341 ; AIX: __ssp_canary_word
342 define void @struct_nonconstant_out_of_bounds_b(i32 %n) #0 {
343   %var = alloca %struct.outer, align 4
344   %outergep = getelementptr inbounds %struct.outer, %struct.outer* %var, i32 0, i32 0
345   %innergep = getelementptr inbounds %struct.inner, %struct.inner* %outergep, i32 %n, i32 0
346   store i32 0, i32* %innergep, align 4
347   ret void
350 ; CHECK-LABEL: bitcast_smaller_load
351 ; CHECK-NOT: __stack_chk_guard
352 ; AIX-NOT: __ssp_canary_word
353 define i32 @bitcast_smaller_load() #0 {
354   %var = alloca i64, align 4
355   store i64 0, i64* %var, align 4
356   %bitcast = bitcast i64* %var to i32*
357   %ret = load i32, i32* %bitcast, align 4
358   ret i32 %ret
361 ; CHECK-LABEL: bitcast_same_size_load
362 ; CHECK-NOT: __stack_chk_guard
363 ; AIX-NOT: __ssp_canary_word
364 define i32 @bitcast_same_size_load() #0 {
365   %var = alloca i64, align 4
366   store i64 0, i64* %var, align 4
367   %bitcast = bitcast i64* %var to %struct.inner*
368   %gep = getelementptr inbounds %struct.inner, %struct.inner* %bitcast, i32 0, i32 1
369   %ret = load i32, i32* %gep, align 4
370   ret i32 %ret
373 ; CHECK-LABEL: bitcast_larger_load
374 ; CHECK: __stack_chk_guard
375 ; AIX: __ssp_canary_word
376 define i64 @bitcast_larger_load() #0 {
377   %var = alloca i32, align 4
378   store i32 0, i32* %var, align 4
379   %bitcast = bitcast i32* %var to i64*
380   %ret = load i64, i64* %bitcast, align 4
381   ret i64 %ret
384 ; CHECK-LABEL: bitcast_larger_store
385 ; CHECK: __stack_chk_guard
386 ; AIX: __ssp_canary_word
387 define i32 @bitcast_larger_store() #0 {
388   %var = alloca i32, align 4
389   %bitcast = bitcast i32* %var to i64*
390   store i64 0, i64* %bitcast, align 4
391   %ret = load i32, i32* %var, align 4
392   ret i32 %ret
395 ; CHECK-LABEL: bitcast_larger_cmpxchg
396 ; CHECK: __stack_chk_guard
397 ; AIX: __ssp_canary_word
398 define i64 @bitcast_larger_cmpxchg(i64 %desired, i64 %new) #0 {
399   %var = alloca i32, align 4
400   %bitcast = bitcast i32* %var to i64*
401   %pair = cmpxchg i64* %bitcast, i64 %desired, i64 %new seq_cst monotonic
402   %ret = extractvalue { i64, i1 } %pair, 0
403   ret i64 %ret
406 ; CHECK-LABEL: bitcast_larger_atomic_rmw
407 ; CHECK: __stack_chk_guard
408 ; AIX: __ssp_canary_word
409 define i64 @bitcast_larger_atomic_rmw() #0 {
410   %var = alloca i32, align 4
411   %bitcast = bitcast i32* %var to i64*
412   %ret = atomicrmw add i64* %bitcast, i64 1 monotonic
413   ret i64 %ret
416 %struct.packed = type <{ i16, i32 }>
418 ; CHECK-LABEL: bitcast_overlap
419 ; CHECK: __stack_chk_guard
420 ; AIX: __ssp_canary_word
421 define i32 @bitcast_overlap() #0 {
422   %var = alloca i32, align 4
423   %bitcast = bitcast i32* %var to %struct.packed*
424   %gep = getelementptr inbounds %struct.packed, %struct.packed* %bitcast, i32 0, i32 1
425   %ret = load i32, i32* %gep, align 2
426   ret i32 %ret
429 %struct.multi_dimensional = type { [10 x [10 x i32]], i32 }
431 ; CHECK-LABEL: multi_dimensional_array
432 ; CHECK: __stack_chk_guard
433 ; AIX: __ssp_canary_word
434 define i32 @multi_dimensional_array() #0 {
435   %var = alloca %struct.multi_dimensional, align 4
436   %gep1 = getelementptr inbounds %struct.multi_dimensional, %struct.multi_dimensional* %var, i32 0, i32 0
437   %gep2 = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* %gep1, i32 0, i32 10
438   %gep3 = getelementptr inbounds [10 x i32], [10 x i32]* %gep2, i32 0, i32 5
439   %ret = load i32, i32* %gep3, align 4
440   ret i32 %ret
443 attributes #0 = { sspstrong }