Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / PowerPC / stack-guard-oob.ll
blob998095188fd3228d4b1288f3dcadfe996f7127de
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, ptr %var, align 4
11   %ret = load i32, ptr %var, align 4
12   ret i32 %ret
15 ; CHECK-LABEL: constant_out_of_bounds:
16 ; CHECK: __stack_chk_guard
17 ; AIX: __ssp_canary_word
18 define i32 @constant_out_of_bounds() #0 {
19   %var = alloca i32, align 4
20   store i32 0, ptr %var, align 4
21   %gep = getelementptr inbounds i32, ptr %var, i32 1
22   %ret = load i32, ptr %gep, align 4
23   ret i32 %ret
26 ; CHECK-LABEL: nonconstant_out_of_bounds:
27 ; CHECK: __stack_chk_guard
28 ; AIX: __ssp_canary_word
29 define i32 @nonconstant_out_of_bounds(i32 %n) #0 {
30   %var = alloca i32, align 4
31   store i32 0, ptr %var, align 4
32   %gep = getelementptr inbounds i32, ptr %var, i32 %n
33   %ret = load i32, ptr %gep, align 4
34   ret i32 %ret
37 ; CHECK-LABEL: phi_before_gep_in_bounds:
38 ; CHECK-NOT: __stack_chk_guard
39 ; AIX-NOT: __ssp_canary_word
40 define i32 @phi_before_gep_in_bounds(i32 %k) #0 {
41 entry:
42   %var1 = alloca i32, align 4
43   %var2 = alloca i32, align 4
44   store i32 0, ptr %var1, align 4
45   store i32 0, ptr %var2, align 4
46   %cmp = icmp ne i32 %k, 0
47   br i1 %cmp, label %if, label %then
49 if:
50   br label %then
52 then:
53   %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ]
54   %ret = load i32, ptr %ptr, align 4
55   ret i32 %ret
58 ; CHECK-LABEL: phi_before_gep_constant_out_of_bounds:
59 ; CHECK: __stack_chk_guard
60 ; AIX: __ssp_canary_word
61 define i32 @phi_before_gep_constant_out_of_bounds(i32 %k) #0 {
62 entry:
63   %var1 = alloca i32, align 4
64   %var2 = alloca i32, align 4
65   store i32 0, ptr %var1, align 4
66   store i32 0, ptr %var2, align 4
67   %cmp = icmp ne i32 %k, 0
68   br i1 %cmp, label %if, label %then
70 if:
71   br label %then
73 then:
74   %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ]
75   %gep = getelementptr inbounds i32, ptr %ptr, i32 1
76   %ret = load i32, ptr %gep, align 4
77   ret i32 %ret
80 ; CHECK-LABEL: phi_before_gep_nonconstant_out_of_bounds:
81 ; CHECK: __stack_chk_guard
82 ; AIX: __ssp_canary_word
83 define i32 @phi_before_gep_nonconstant_out_of_bounds(i32 %k, i32 %n) #0 {
84 entry:
85   %var1 = alloca i32, align 4
86   %var2 = alloca i32, align 4
87   store i32 0, ptr %var1, align 4
88   store i32 0, ptr %var2, align 4
89   %cmp = icmp ne i32 %k, 0
90   br i1 %cmp, label %if, label %then
92 if:
93   br label %then
95 then:
96   %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ]
97   %gep = getelementptr inbounds i32, ptr %ptr, i32 %n
98   %ret = load i32, ptr %gep, align 4
99   ret i32 %ret
102 ; CHECK-LABEL: phi_after_gep_in_bounds:
103 ; CHECK-NOT: __stack_chk_guard
104 ; AIX-NOT: __ssp_canary_word
105 define i32 @phi_after_gep_in_bounds(i32 %k) #0 {
106 entry:
107   %var1 = alloca i32, align 4
108   %var2 = alloca i32, align 4
109   store i32 0, ptr %var1, align 4
110   store i32 0, ptr %var2, align 4
111   %cmp = icmp ne i32 %k, 0
112   br i1 %cmp, label %if, label %else
115   br label %then
117 else:
118   br label %then
120 then:
121   %ptr = phi ptr [ %var1, %if ], [ %var2, %else ]
122   %ret = load i32, ptr %ptr, align 4
123   ret i32 %ret
126 ; CHECK-LABEL: phi_after_gep_constant_out_of_bounds_a:
127 ; CHECK: __stack_chk_guard
128 ; AIX: __ssp_canary_word
129 define i32 @phi_after_gep_constant_out_of_bounds_a(i32 %k) #0 {
130 entry:
131   %var1 = alloca i32, align 4
132   %var2 = alloca i32, align 4
133   store i32 0, ptr %var1, align 4
134   store i32 0, ptr %var2, align 4
135   %cmp = icmp ne i32 %k, 0
136   br i1 %cmp, label %if, label %else
139   br label %then
141 else:
142   %gep2 = getelementptr inbounds i32, ptr %var2, i32 1
143   br label %then
145 then:
146   %ptr = phi ptr [ %var1, %if ], [ %gep2, %else ]
147   %ret = load i32, ptr %ptr, align 4
148   ret i32 %ret
151 ; CHECK-LABEL: phi_after_gep_constant_out_of_bounds_b:
152 ; CHECK: __stack_chk_guard
153 ; AIX: __ssp_canary_word
154 define i32 @phi_after_gep_constant_out_of_bounds_b(i32 %k) #0 {
155 entry:
156   %var1 = alloca i32, align 4
157   %var2 = alloca i32, align 4
158   store i32 0, ptr %var1, align 4
159   store i32 0, ptr %var2, align 4
160   %cmp = icmp ne i32 %k, 0
161   br i1 %cmp, label %if, label %else
164   %gep1 = getelementptr inbounds i32, ptr %var1, i32 1
165   br label %then
167 else:
168   br label %then
170 then:
171   %ptr = phi ptr [ %gep1, %if ], [ %var2, %else ]
172   %ret = load i32, ptr %ptr, align 4
173   ret i32 %ret
176 ; CHECK-LABEL: phi_different_types_a:
177 ; CHECK: __stack_chk_guard
178 ; AIX: __ssp_canary_word
179 define i64 @phi_different_types_a(i32 %k) #0 {
180 entry:
181   %var1 = alloca i64, align 4
182   %var2 = alloca i32, align 4
183   store i64 0, ptr %var1, align 4
184   store i32 0, ptr %var2, align 4
185   %cmp = icmp ne i32 %k, 0
186   br i1 %cmp, label %if, label %then
189   br label %then
191 then:
192   %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ]
193   %ret = load i64, ptr %ptr, align 4
194   ret i64 %ret
197 ; CHECK-LABEL: phi_different_types_b:
198 ; CHECK: __stack_chk_guard
199 ; AIX: __ssp_canary_word
200 define i64 @phi_different_types_b(i32 %k) #0 {
201 entry:
202   %var1 = alloca i32, align 4
203   %var2 = alloca i64, align 4
204   store i32 0, ptr %var1, align 4
205   store i64 0, ptr %var2, align 4
206   %cmp = icmp ne i32 %k, 0
207   br i1 %cmp, label %if, label %then
210   br label %then
212 then:
213   %ptr = phi ptr [ %var2, %entry ], [ %var1, %if ]
214   %ret = load i64, ptr %ptr, align 4
215   ret i64 %ret
218 ; CHECK-LABEL: phi_after_gep_nonconstant_out_of_bounds_a:
219 ; CHECK: __stack_chk_guard
220 ; AIX: __ssp_canary_word
221 define i32 @phi_after_gep_nonconstant_out_of_bounds_a(i32 %k, i32 %n) #0 {
222 entry:
223   %var1 = alloca i32, align 4
224   %var2 = alloca i32, align 4
225   store i32 0, ptr %var1, align 4
226   store i32 0, ptr %var2, align 4
227   %cmp = icmp ne i32 %k, 0
228   br i1 %cmp, label %if, label %else
231   br label %then
233 else:
234   %gep2 = getelementptr inbounds i32, ptr %var2, i32 %n
235   br label %then
237 then:
238   %ptr = phi ptr [ %var1, %if ], [ %gep2, %else ]
239   %ret = load i32, ptr %ptr, align 4
240   ret i32 %ret
243 ; CHECK-LABEL: phi_after_gep_nonconstant_out_of_bounds_b:
244 ; CHECK: __stack_chk_guard
245 ; AIX: __ssp_canary_word
246 define i32 @phi_after_gep_nonconstant_out_of_bounds_b(i32 %k, i32 %n) #0 {
247 entry:
248   %var1 = alloca i32, align 4
249   %var2 = alloca i32, align 4
250   store i32 0, ptr %var1, align 4
251   store i32 0, ptr %var2, align 4
252   %cmp = icmp ne i32 %k, 0
253   br i1 %cmp, label %if, label %else
256   %gep1 = getelementptr inbounds i32, ptr %var1, i32 %n
257   br label %then
259 else:
260   br label %then
262 then:
263   %ptr = phi ptr [ %gep1, %if ], [ %var2, %else ]
264   %ret = load i32, ptr %ptr, align 4
265   ret i32 %ret
268 %struct.outer = type { %struct.inner, %struct.inner }
269 %struct.inner = type { i32, i32 }
271 ; CHECK-LABEL: struct_in_bounds:
272 ; CHECK-NOT: __stack_chk_guard
273 ; AIX-NOT: __ssp_canary_word
274 define void @struct_in_bounds() #0 {
275   %var = alloca %struct.outer, align 4
276   %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 0, i32 1
277   %innergep = getelementptr inbounds %struct.inner, ptr %outergep, i32 0, i32 1
278   store i32 0, ptr %innergep, align 4
279   ret void
282 ; CHECK-LABEL: struct_constant_out_of_bounds_a:
283 ; CHECK: __stack_chk_guard
284 ; AIX: __ssp_canary_word
285 define void @struct_constant_out_of_bounds_a() #0 {
286   %var = alloca %struct.outer, align 4
287   %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 1, i32 0
288   store i32 0, ptr %outergep, align 4
289   ret void
292 ; CHECK-LABEL: struct_constant_out_of_bounds_b:
293 ; Here the offset is out-of-bounds of the addressed struct.inner member, but
294 ; still within bounds of the outer struct so no stack guard is needed.
295 ; CHECK-NOT: __stack_chk_guard
296 ; AIX-NOT: __ssp_canary_word
297 define void @struct_constant_out_of_bounds_b() #0 {
298   %var = alloca %struct.outer, align 4
299   %innergep = getelementptr inbounds %struct.inner, ptr %var, i32 1, i32 0
300   store i32 0, ptr %innergep, align 4
301   ret void
304 ; CHECK-LABEL: struct_constant_out_of_bounds_c:
305 ; Here we are out-of-bounds of both the inner and outer struct.
306 ; CHECK: __stack_chk_guard
307 ; AIX: __ssp_canary_word
308 define void @struct_constant_out_of_bounds_c() #0 {
309   %var = alloca %struct.outer, align 4
310   %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 0, i32 1
311   %innergep = getelementptr inbounds %struct.inner, ptr %outergep, i32 1, i32 0
312   store i32 0, ptr %innergep, align 4
313   ret void
316 ; CHECK-LABEL: struct_nonconstant_out_of_bounds_a:
317 ; CHECK: __stack_chk_guard
318 ; AIX: __ssp_canary_word
319 define void @struct_nonconstant_out_of_bounds_a(i32 %n) #0 {
320   %var = alloca %struct.outer, align 4
321   %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 %n, i32 0
322   store i32 0, ptr %outergep, align 4
323   ret void
326 ; CHECK-LABEL: struct_nonconstant_out_of_bounds_b:
327 ; CHECK: __stack_chk_guard
328 ; AIX: __ssp_canary_word
329 define void @struct_nonconstant_out_of_bounds_b(i32 %n) #0 {
330   %var = alloca %struct.outer, align 4
331   %innergep = getelementptr inbounds %struct.inner, ptr %var, i32 %n, i32 0
332   store i32 0, ptr %innergep, align 4
333   ret void
336 ; CHECK-LABEL: bitcast_smaller_load
337 ; CHECK-NOT: __stack_chk_guard
338 ; AIX-NOT: __ssp_canary_word
339 define i32 @bitcast_smaller_load() #0 {
340   %var = alloca i64, align 4
341   store i64 0, ptr %var, align 4
342   %ret = load i32, ptr %var, align 4
343   ret i32 %ret
346 ; CHECK-LABEL: bitcast_same_size_load
347 ; CHECK-NOT: __stack_chk_guard
348 ; AIX-NOT: __ssp_canary_word
349 define i32 @bitcast_same_size_load() #0 {
350   %var = alloca i64, align 4
351   store i64 0, ptr %var, align 4
352   %gep = getelementptr inbounds %struct.inner, ptr %var, i32 0, i32 1
353   %ret = load i32, ptr %gep, align 4
354   ret i32 %ret
357 ; CHECK-LABEL: bitcast_larger_load
358 ; CHECK: __stack_chk_guard
359 ; AIX: __ssp_canary_word
360 define i64 @bitcast_larger_load() #0 {
361   %var = alloca i32, align 4
362   store i32 0, ptr %var, align 4
363   %ret = load i64, ptr %var, align 4
364   ret i64 %ret
367 ; CHECK-LABEL: bitcast_larger_store
368 ; CHECK: __stack_chk_guard
369 ; AIX: __ssp_canary_word
370 define i32 @bitcast_larger_store() #0 {
371   %var = alloca i32, align 4
372   store i64 0, ptr %var, align 4
373   %ret = load i32, ptr %var, align 4
374   ret i32 %ret
377 ; CHECK-LABEL: bitcast_larger_cmpxchg
378 ; CHECK: __stack_chk_guard
379 ; AIX: __ssp_canary_word
380 define i64 @bitcast_larger_cmpxchg(i64 %desired, i64 %new) #0 {
381   %var = alloca i32, align 4
382   %pair = cmpxchg ptr %var, i64 %desired, i64 %new seq_cst monotonic
383   %ret = extractvalue { i64, i1 } %pair, 0
384   ret i64 %ret
387 ; CHECK-LABEL: bitcast_larger_atomic_rmw
388 ; CHECK: __stack_chk_guard
389 ; AIX: __ssp_canary_word
390 define i64 @bitcast_larger_atomic_rmw() #0 {
391   %var = alloca i32, align 4
392   %ret = atomicrmw add ptr %var, i64 1 monotonic
393   ret i64 %ret
396 %struct.packed = type <{ i16, i32 }>
398 ; CHECK-LABEL: bitcast_overlap
399 ; CHECK: __stack_chk_guard
400 ; AIX: __ssp_canary_word
401 define i32 @bitcast_overlap() #0 {
402   %var = alloca i32, align 4
403   %gep = getelementptr inbounds %struct.packed, ptr %var, i32 0, i32 1
404   %ret = load i32, ptr %gep, align 2
405   ret i32 %ret
408 %struct.multi_dimensional = type { [10 x [10 x i32]], i32 }
410 ; CHECK-LABEL: multi_dimensional_array
411 ; CHECK: __stack_chk_guard
412 ; AIX: __ssp_canary_word
413 define i32 @multi_dimensional_array() #0 {
414   %var = alloca %struct.multi_dimensional, align 4
415   %gep2 = getelementptr inbounds [10 x [10 x i32]], ptr %var, i32 0, i32 10
416   %gep3 = getelementptr inbounds [10 x i32], ptr %gep2, i32 0, i32 5
417   %ret = load i32, ptr %gep3, align 4
418   ret i32 %ret
421 attributes #0 = { sspstrong }
423 !llvm.module.flags = !{!0}
424 !0 = !{i32 7, !"direct-access-external-data", i32 1}