Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / X86 / stack-guard-oob.ll
blob5b7ae832315b31f0a484a95438c741254dad48b6
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, ptr %var, align 4
9   %ret = load i32, ptr %var, align 4
10   ret i32 %ret
13 ; CHECK-LABEL: constant_out_of_bounds:
14 ; CHECK: __stack_chk_guard
15 define i32 @constant_out_of_bounds() #0 {
16   %var = alloca i32, align 4
17   store i32 0, ptr %var, align 4
18   %gep = getelementptr inbounds i32, ptr %var, i32 1
19   %ret = load i32, ptr %gep, align 4
20   ret i32 %ret
23 ; CHECK-LABEL: nonconstant_out_of_bounds:
24 ; CHECK: __stack_chk_guard
25 define i32 @nonconstant_out_of_bounds(i32 %n) #0 {
26   %var = alloca i32, align 4
27   store i32 0, ptr %var, align 4
28   %gep = getelementptr inbounds i32, ptr %var, i32 %n
29   %ret = load i32, ptr %gep, align 4
30   ret i32 %ret
33 ; CHECK-LABEL: phi_before_gep_in_bounds:
34 ; CHECK-NOT: __stack_chk_guard
35 define i32 @phi_before_gep_in_bounds(i32 %k) #0 {
36 entry:
37   %var1 = alloca i32, align 4
38   %var2 = alloca i32, align 4
39   store i32 0, ptr %var1, align 4
40   store i32 0, ptr %var2, align 4
41   %cmp = icmp ne i32 %k, 0
42   br i1 %cmp, label %if, label %then
44 if:
45   br label %then
47 then:
48   %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ]
49   %ret = load i32, ptr %ptr, align 4
50   ret i32 %ret
53 ; CHECK-LABEL: phi_before_gep_constant_out_of_bounds:
54 ; CHECK: __stack_chk_guard
55 define i32 @phi_before_gep_constant_out_of_bounds(i32 %k) #0 {
56 entry:
57   %var1 = alloca i32, align 4
58   %var2 = alloca i32, align 4
59   store i32 0, ptr %var1, align 4
60   store i32 0, ptr %var2, align 4
61   %cmp = icmp ne i32 %k, 0
62   br i1 %cmp, label %if, label %then
64 if:
65   br label %then
67 then:
68   %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ]
69   %gep = getelementptr inbounds i32, ptr %ptr, i32 1
70   %ret = load i32, ptr %gep, align 4
71   ret i32 %ret
74 ; CHECK-LABEL: phi_before_gep_nonconstant_out_of_bounds:
75 ; CHECK: __stack_chk_guard
76 define i32 @phi_before_gep_nonconstant_out_of_bounds(i32 %k, i32 %n) #0 {
77 entry:
78   %var1 = alloca i32, align 4
79   %var2 = alloca i32, align 4
80   store i32 0, ptr %var1, align 4
81   store i32 0, ptr %var2, align 4
82   %cmp = icmp ne i32 %k, 0
83   br i1 %cmp, label %if, label %then
85 if:
86   br label %then
88 then:
89   %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ]
90   %gep = getelementptr inbounds i32, ptr %ptr, i32 %n
91   %ret = load i32, ptr %gep, align 4
92   ret i32 %ret
95 ; CHECK-LABEL: phi_after_gep_in_bounds:
96 ; CHECK-NOT: __stack_chk_guard
97 define i32 @phi_after_gep_in_bounds(i32 %k) #0 {
98 entry:
99   %var1 = alloca i32, align 4
100   %var2 = alloca i32, align 4
101   store i32 0, ptr %var1, align 4
102   store i32 0, ptr %var2, align 4
103   %cmp = icmp ne i32 %k, 0
104   br i1 %cmp, label %if, label %else
107   br label %then
109 else:
110   br label %then
112 then:
113   %ptr = phi ptr [ %var1, %if ], [ %var2, %else ]
114   %ret = load i32, ptr %ptr, align 4
115   ret i32 %ret
118 ; CHECK-LABEL: phi_after_gep_constant_out_of_bounds_a:
119 ; CHECK: __stack_chk_guard
120 define i32 @phi_after_gep_constant_out_of_bounds_a(i32 %k) #0 {
121 entry:
122   %var1 = alloca i32, align 4
123   %var2 = alloca i32, align 4
124   store i32 0, ptr %var1, align 4
125   store i32 0, ptr %var2, align 4
126   %cmp = icmp ne i32 %k, 0
127   br i1 %cmp, label %if, label %else
130   br label %then
132 else:
133   %gep2 = getelementptr inbounds i32, ptr %var2, i32 1
134   br label %then
136 then:
137   %ptr = phi ptr [ %var1, %if ], [ %gep2, %else ]
138   %ret = load i32, ptr %ptr, align 4
139   ret i32 %ret
142 ; CHECK-LABEL: phi_after_gep_constant_out_of_bounds_b:
143 ; CHECK: __stack_chk_guard
144 define i32 @phi_after_gep_constant_out_of_bounds_b(i32 %k) #0 {
145 entry:
146   %var1 = alloca i32, align 4
147   %var2 = alloca i32, align 4
148   store i32 0, ptr %var1, align 4
149   store i32 0, ptr %var2, align 4
150   %cmp = icmp ne i32 %k, 0
151   br i1 %cmp, label %if, label %else
154   %gep1 = getelementptr inbounds i32, ptr %var1, i32 1
155   br label %then
157 else:
158   br label %then
160 then:
161   %ptr = phi ptr [ %gep1, %if ], [ %var2, %else ]
162   %ret = load i32, ptr %ptr, align 4
163   ret i32 %ret
166 ; CHECK-LABEL: phi_different_types_a:
167 ; CHECK: __stack_chk_guard
168 define i64 @phi_different_types_a(i32 %k) #0 {
169 entry:
170   %var1 = alloca i64, align 4
171   %var2 = alloca i32, align 4
172   store i64 0, ptr %var1, align 4
173   store i32 0, ptr %var2, align 4
174   %cmp = icmp ne i32 %k, 0
175   br i1 %cmp, label %if, label %then
178   br label %then
180 then:
181   %ptr = phi ptr [ %var1, %entry ], [ %var2, %if ]
182   %ret = load i64, ptr %ptr, align 4
183   ret i64 %ret
186 ; CHECK-LABEL: phi_different_types_b:
187 ; CHECK: __stack_chk_guard
188 define i64 @phi_different_types_b(i32 %k) #0 {
189 entry:
190   %var1 = alloca i32, align 4
191   %var2 = alloca i64, align 4
192   store i32 0, ptr %var1, align 4
193   store i64 0, ptr %var2, align 4
194   %cmp = icmp ne i32 %k, 0
195   br i1 %cmp, label %if, label %then
198   br label %then
200 then:
201   %ptr = phi ptr [ %var2, %entry ], [ %var1, %if ]
202   %ret = load i64, ptr %ptr, align 4
203   ret i64 %ret
206 ; CHECK-LABEL: phi_after_gep_nonconstant_out_of_bounds_a:
207 ; CHECK: __stack_chk_guard
208 define i32 @phi_after_gep_nonconstant_out_of_bounds_a(i32 %k, i32 %n) #0 {
209 entry:
210   %var1 = alloca i32, align 4
211   %var2 = alloca i32, align 4
212   store i32 0, ptr %var1, align 4
213   store i32 0, ptr %var2, align 4
214   %cmp = icmp ne i32 %k, 0
215   br i1 %cmp, label %if, label %else
218   br label %then
220 else:
221   %gep2 = getelementptr inbounds i32, ptr %var2, i32 %n
222   br label %then
224 then:
225   %ptr = phi ptr [ %var1, %if ], [ %gep2, %else ]
226   %ret = load i32, ptr %ptr, align 4
227   ret i32 %ret
230 ; CHECK-LABEL: phi_after_gep_nonconstant_out_of_bounds_b:
231 ; CHECK: __stack_chk_guard
232 define i32 @phi_after_gep_nonconstant_out_of_bounds_b(i32 %k, i32 %n) #0 {
233 entry:
234   %var1 = alloca i32, align 4
235   %var2 = alloca i32, align 4
236   store i32 0, ptr %var1, align 4
237   store i32 0, ptr %var2, align 4
238   %cmp = icmp ne i32 %k, 0
239   br i1 %cmp, label %if, label %else
242   %gep1 = getelementptr inbounds i32, ptr %var1, i32 %n
243   br label %then
245 else:
246   br label %then
248 then:
249   %ptr = phi ptr [ %gep1, %if ], [ %var2, %else ]
250   %ret = load i32, ptr %ptr, align 4
251   ret i32 %ret
254 %struct.outer = type { %struct.inner, %struct.inner }
255 %struct.inner = type { i32, i32 }
257 ; CHECK-LABEL: struct_in_bounds:
258 ; CHECK-NOT: __stack_chk_guard
259 define void @struct_in_bounds() #0 {
260   %var = alloca %struct.outer, align 4
261   %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 0, i32 1
262   %innergep = getelementptr inbounds %struct.inner, ptr %outergep, i32 0, i32 1
263   store i32 0, ptr %innergep, align 4
264   ret void
267 ; CHECK-LABEL: struct_constant_out_of_bounds_a:
268 ; CHECK: __stack_chk_guard
269 define void @struct_constant_out_of_bounds_a() #0 {
270   %var = alloca %struct.outer, align 4
271   %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 1, i32 0
272   store i32 0, ptr %outergep, align 4
273   ret void
276 ; CHECK-LABEL: struct_constant_out_of_bounds_b:
277 ; Here the offset is out-of-bounds of the addressed struct.inner member, but
278 ; still within bounds of the outer struct so no stack guard is needed.
279 ; CHECK-NOT: __stack_chk_guard
280 define void @struct_constant_out_of_bounds_b() #0 {
281   %var = alloca %struct.outer, align 4
282   %innergep = getelementptr inbounds %struct.inner, ptr %var, i32 1, i32 0
283   store i32 0, ptr %innergep, align 4
284   ret void
287 ; CHECK-LABEL: struct_constant_out_of_bounds_c:
288 ; Here we are out-of-bounds of both the inner and outer struct.
289 ; CHECK: __stack_chk_guard
290 define void @struct_constant_out_of_bounds_c() #0 {
291   %var = alloca %struct.outer, align 4
292   %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 0, i32 1
293   %innergep = getelementptr inbounds %struct.inner, ptr %outergep, i32 1, i32 0
294   store i32 0, ptr %innergep, align 4
295   ret void
298 ; CHECK-LABEL: struct_nonconstant_out_of_bounds_a:
299 ; CHECK: __stack_chk_guard
300 define void @struct_nonconstant_out_of_bounds_a(i32 %n) #0 {
301   %var = alloca %struct.outer, align 4
302   %outergep = getelementptr inbounds %struct.outer, ptr %var, i32 %n, i32 0
303   store i32 0, ptr %outergep, align 4
304   ret void
307 ; CHECK-LABEL: struct_nonconstant_out_of_bounds_b:
308 ; CHECK: __stack_chk_guard
309 define void @struct_nonconstant_out_of_bounds_b(i32 %n) #0 {
310   %var = alloca %struct.outer, align 4
311   %innergep = getelementptr inbounds %struct.inner, ptr %var, i32 %n, i32 0
312   store i32 0, ptr %innergep, align 4
313   ret void
316 ; CHECK-LABEL: bitcast_smaller_load
317 ; CHECK-NOT: __stack_chk_guard
318 define i32 @bitcast_smaller_load() #0 {
319   %var = alloca i64, align 4
320   store i64 0, ptr %var, align 4
321   %ret = load i32, ptr %var, align 4
322   ret i32 %ret
325 ; CHECK-LABEL: bitcast_same_size_load
326 ; CHECK-NOT: __stack_chk_guard
327 define i32 @bitcast_same_size_load() #0 {
328   %var = alloca i64, align 4
329   store i64 0, ptr %var, align 4
330   %gep = getelementptr inbounds %struct.inner, ptr %var, i32 0, i32 1
331   %ret = load i32, ptr %gep, align 4
332   ret i32 %ret
335 ; CHECK-LABEL: bitcast_larger_load
336 ; CHECK: __stack_chk_guard
337 define i64 @bitcast_larger_load() #0 {
338   %var = alloca i32, align 4
339   store i32 0, ptr %var, align 4
340   %ret = load i64, ptr %var, align 4
341   ret i64 %ret
344 ; CHECK-LABEL: bitcast_larger_store
345 ; CHECK: __stack_chk_guard
346 define i32 @bitcast_larger_store() #0 {
347   %var = alloca i32, align 4
348   store i64 0, ptr %var, align 4
349   %ret = load i32, ptr %var, align 4
350   ret i32 %ret
353 ; CHECK-LABEL: bitcast_larger_cmpxchg
354 ; CHECK: __stack_chk_guard
355 define i64 @bitcast_larger_cmpxchg(i64 %desired, i64 %new) #0 {
356   %var = alloca i32, align 4
357   %pair = cmpxchg ptr %var, i64 %desired, i64 %new seq_cst monotonic
358   %ret = extractvalue { i64, i1 } %pair, 0
359   ret i64 %ret
362 ; CHECK-LABEL: bitcast_larger_atomic_rmw
363 ; CHECK: __stack_chk_guard
364 define i64 @bitcast_larger_atomic_rmw() #0 {
365   %var = alloca i32, align 4
366   %ret = atomicrmw add ptr %var, i64 1 monotonic
367   ret i64 %ret
370 %struct.packed = type <{ i16, i32 }>
372 ; CHECK-LABEL: bitcast_overlap
373 ; CHECK: __stack_chk_guard
374 define i32 @bitcast_overlap() #0 {
375   %var = alloca i32, align 4
376   %gep = getelementptr inbounds %struct.packed, ptr %var, i32 0, i32 1
377   %ret = load i32, ptr %gep, align 2
378   ret i32 %ret
381 %struct.multi_dimensional = type { [10 x [10 x i32]], i32 }
383 ; CHECK-LABEL: multi_dimensional_array
384 ; CHECK: __stack_chk_guard
385 define i32 @multi_dimensional_array() #0 {
386   %var = alloca %struct.multi_dimensional, align 4
387   %gep2 = getelementptr inbounds [10 x [10 x i32]], ptr %var, i32 0, i32 10
388   %gep3 = getelementptr inbounds [10 x i32], ptr %gep2, i32 0, i32 5
389   %ret = load i32, ptr %gep3, align 4
390   ret i32 %ret
393 attributes #0 = { sspstrong }