Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / X86 / ssp-data-layout.ll
blobbda2598384db8487fb213c35fb648848b2eb6d8a
1 ; RUN: llc < %s -stack-symbol-ordering=0 -frame-pointer=all -mtriple=x86_64-pc-linux-gnu -mcpu=corei7 -o - | FileCheck %s
2 ;  This test is fairly fragile.  The goal is to ensure that "large" stack
3 ;  objects are allocated closest to the stack protector (i.e., farthest away
4 ;  from the Stack Pointer.)  In standard SSP mode this means that large (>=
5 ;  ssp-buffer-size) arrays and structures containing such arrays are
6 ;  closet to the protector.  With sspstrong and sspreq this means large
7 ;  arrays/structures-with-arrays are closest, followed by small (< ssp-buffer-size)
8 ;  arrays/structures-with-arrays, and then addr-taken variables.
10 ;  Ideally, we only want verify that the objects appear in the correct groups
11 ;  and that the groups have the correct relative stack offset.  The ordering
12 ;  within a group is not relevant to this test.  Unfortunately, there is not
13 ;  an elegant way to do this, so just match the offset for each object.
14 ; RUN: llc < %s -frame-pointer=all -mtriple=x86_64-unknown-unknown -O0 -mcpu=corei7 -o - \
15 ; RUN:   | FileCheck --check-prefix=FAST-NON-LIN %s
16 ; FastISel was not setting the StackProtectorIndex when lowering
17 ; Intrinsic::stackprotector and as a result the stack re-arrangement code was
18 ; never applied.  This problem only shows up on non-Linux platforms because on
19 ; Linux the stack protector cookie is loaded from a special address space which
20 ; always triggers standard ISel.  Run a basic test to ensure that at -O0
21 ; on a non-linux target the data layout rules are triggered.
23 %struct.struct_large_char = type { [8 x i8] }
24 %struct.struct_small_char = type { [2 x i8] }
25 %struct.struct_large_nonchar = type { [8 x i32] }
26 %struct.struct_small_nonchar = type { [2 x i16] }
28 define void @layout_ssp() ssp {
29 entry:
30 ; Expected stack layout for ssp is
31 ;  -16 large_char          . Group 1, nested arrays, arrays >= ssp-buffer-size
32 ;  -24 struct_large_char   .
33 ;  -28 scalar1             | Everything else
34 ;  -32 scalar2
35 ;  -36 scalar3
36 ;  -40 addr-of
37 ;  -44 small_nonchar
38 ;  -80 large_nonchar
39 ;  -82 small_char
40 ;  -88 struct_small_char
41 ;  -120 struct_large_nonchar
42 ;  -128 struct_small_nonchar
44 ; CHECK: layout_ssp:
45 ; CHECK: call{{l|q}} get_scalar1
46 ; CHECK: movl %eax, -28(
47 ; CHECK: call{{l|q}} end_scalar1
49 ; CHECK: call{{l|q}} get_scalar2
50 ; CHECK: movl %eax, -32(
51 ; CHECK: call{{l|q}} end_scalar2
53 ; CHECK: call{{l|q}} get_scalar3
54 ; CHECK: movl %eax, -36(
55 ; CHECK: call{{l|q}} end_scalar3
57 ; CHECK: call{{l|q}} get_addrof
58 ; CHECK: movl %eax, -40(
59 ; CHECK: call{{l|q}} end_addrof
61 ; CHECK: get_small_nonchar
62 ; CHECK: movw %ax, -44(
63 ; CHECK: call{{l|q}} end_small_nonchar
65 ; CHECK: call{{l|q}} get_large_nonchar
66 ; CHECK: movl %eax, -80(
67 ; CHECK: call{{l|q}} end_large_nonchar
69 ; CHECK: call{{l|q}} get_small_char
70 ; CHECK: movb %al, -82(
71 ; CHECK: call{{l|q}} end_small_char
73 ; CHECK: call{{l|q}} get_large_char
74 ; CHECK: movb %al, -16(
75 ; CHECK: call{{l|q}} end_large_char
77 ; CHECK: call{{l|q}} get_struct_large_char
78 ; CHECK: movb %al, -24(
79 ; CHECK: call{{l|q}} end_struct_large_char
81 ; CHECK: call{{l|q}} get_struct_small_char
82 ; CHECK: movb %al, -88(
83 ; CHECK: call{{l|q}} end_struct_small_char
85 ; CHECK: call{{l|q}} get_struct_large_nonchar
86 ; CHECK: movl %eax, -120(
87 ; CHECK: call{{l|q}} end_struct_large_nonchar
89 ; CHECK: call{{l|q}} get_struct_small_nonchar
90 ; CHECK: movw %ax, -128(
91 ; CHECK: call{{l|q}} end_struct_small_nonchar
92   %x = alloca i32, align 4
93   %y = alloca i32, align 4
94   %z = alloca i32, align 4
95   %ptr = alloca i32, align 4
96   %small2 = alloca [2 x i16], align 4
97   %large2 = alloca [8 x i32], align 16
98   %small = alloca [2 x i8], align 2
99   %large = alloca [8 x i8], align 8
100   %a = alloca %struct.struct_large_char, align 8
101   %b = alloca %struct.struct_small_char, align 8
102   %c = alloca %struct.struct_large_nonchar, align 8
103   %d = alloca %struct.struct_small_nonchar, align 8
104   %call = call i32 @get_scalar1()
105   store i32 %call, ptr %x, align 4
106   call void @end_scalar1()
107   %call1 = call i32 @get_scalar2()
108   store i32 %call1, ptr %y, align 4
109   call void @end_scalar2()
110   %call2 = call i32 @get_scalar3()
111   store i32 %call2, ptr %z, align 4
112   call void @end_scalar3()
113   %call3 = call i32 @get_addrof()
114   store i32 %call3, ptr %ptr, align 4
115   call void @end_addrof()
116   %call4 = call signext i16 @get_small_nonchar()
117   store i16 %call4, ptr %small2, align 2
118   call void @end_small_nonchar()
119   %call5 = call i32 @get_large_nonchar()
120   store i32 %call5, ptr %large2, align 4
121   call void @end_large_nonchar()
122   %call7 = call signext i8 @get_small_char()
123   store i8 %call7, ptr %small, align 1
124   call void @end_small_char()
125   %call9 = call signext i8 @get_large_char()
126   store i8 %call9, ptr %large, align 1
127   call void @end_large_char()
128   %call11 = call signext i8 @get_struct_large_char()
129   store i8 %call11, ptr %a, align 1
130   call void @end_struct_large_char()
131   %call13 = call signext i8 @get_struct_small_char()
132   store i8 %call13, ptr %b, align 1
133   call void @end_struct_small_char()
134   %call16 = call i32 @get_struct_large_nonchar()
135   store i32 %call16, ptr %c, align 4
136   call void @end_struct_large_nonchar()
137   %call19 = call signext i16 @get_struct_small_nonchar()
138   store i16 %call19, ptr %d, align 2
139   call void @end_struct_small_nonchar()
140   %0 = load i32, ptr %x, align 4
141   %1 = load i32, ptr %y, align 4
142   %2 = load i32, ptr %z, align 4
143   %3 = load i64, ptr %a, align 1
144   %4 = load i16, ptr %b, align 1
145   %5 = load i32, ptr %d, align 1
146   call void @takes_all(i64 %3, i16 %4, ptr byval(%struct.struct_large_nonchar) align 8 %c, i32 %5, ptr %large, ptr %small, ptr %large2, ptr %small2, ptr %ptr, i32 %0, i32 %1, i32 %2)
147   ret void
150 define void @layout_sspstrong() nounwind uwtable sspstrong {
151 entry:
152 ; Expected stack layout for sspstrong is
153 ;   -48   large_nonchar          . Group 1, nested arrays,
154 ;   -56   large_char             .  arrays >= ssp-buffer-size
155 ;   -64   struct_large_char      .
156 ;   -96   struct_large_nonchar   .
157 ;   -100  small_non_char         | Group 2, nested arrays,
158 ;   -102  small_char             |  arrays < ssp-buffer-size
159 ;   -104  struct_small_char      |
160 ;   -112  struct_small_nonchar   |
161 ;   -116  addrof                 * Group 3, addr-of local
162 ;   -120  scalar                 + Group 4, everything else
163 ;   -124  scalar                 +
164 ;   -128  scalar                 +
166 ; CHECK: layout_sspstrong:
167 ; CHECK: call{{l|q}} get_scalar1
168 ; CHECK: movl %eax, -120(
169 ; CHECK: call{{l|q}} end_scalar1
171 ; CHECK: call{{l|q}} get_scalar2
172 ; CHECK: movl %eax, -124(
173 ; CHECK: call{{l|q}} end_scalar2
175 ; CHECK: call{{l|q}} get_scalar3
176 ; CHECK: movl %eax, -128(
177 ; CHECK: call{{l|q}} end_scalar3
179 ; CHECK: call{{l|q}} get_addrof
180 ; CHECK: movl %eax, -116(
181 ; CHECK: call{{l|q}} end_addrof
183 ; CHECK: get_small_nonchar
184 ; CHECK: movw %ax, -100(
185 ; CHECK: call{{l|q}} end_small_nonchar
187 ; CHECK: call{{l|q}} get_large_nonchar
188 ; CHECK: movl %eax, -48(
189 ; CHECK: call{{l|q}} end_large_nonchar
191 ; CHECK: call{{l|q}} get_small_char
192 ; CHECK: movb %al, -102(
193 ; CHECK: call{{l|q}} end_small_char
195 ; CHECK: call{{l|q}} get_large_char
196 ; CHECK: movb %al, -56(
197 ; CHECK: call{{l|q}} end_large_char
199 ; CHECK: call{{l|q}} get_struct_large_char
200 ; CHECK: movb %al, -64(
201 ; CHECK: call{{l|q}} end_struct_large_char
203 ; CHECK: call{{l|q}} get_struct_small_char
204 ; CHECK: movb %al, -104(
205 ; CHECK: call{{l|q}} end_struct_small_char
207 ; CHECK: call{{l|q}} get_struct_large_nonchar
208 ; CHECK: movl %eax, -96(
209 ; CHECK: call{{l|q}} end_struct_large_nonchar
211 ; CHECK: call{{l|q}} get_struct_small_nonchar
212 ; CHECK: movw %ax, -112(
213 ; CHECK: call{{l|q}} end_struct_small_nonchar
214   %x = alloca i32, align 4
215   %y = alloca i32, align 4
216   %z = alloca i32, align 4
217   %ptr = alloca i32, align 4
218   %small2 = alloca [2 x i16], align 2
219   %large2 = alloca [8 x i32], align 16
220   %small = alloca [2 x i8], align 2
221   %large = alloca [8 x i8], align 8
222   %a = alloca %struct.struct_large_char, align 8
223   %b = alloca %struct.struct_small_char, align 8
224   %c = alloca %struct.struct_large_nonchar, align 8
225   %d = alloca %struct.struct_small_nonchar, align 8
226   %call = call i32 @get_scalar1()
227   store i32 %call, ptr %x, align 4
228   call void @end_scalar1()
229   %call1 = call i32 @get_scalar2()
230   store i32 %call1, ptr %y, align 4
231   call void @end_scalar2()
232   %call2 = call i32 @get_scalar3()
233   store i32 %call2, ptr %z, align 4
234   call void @end_scalar3()
235   %call3 = call i32 @get_addrof()
236   store i32 %call3, ptr %ptr, align 4
237   call void @end_addrof()
238   %call4 = call signext i16 @get_small_nonchar()
239   store i16 %call4, ptr %small2, align 2
240   call void @end_small_nonchar()
241   %call5 = call i32 @get_large_nonchar()
242   store i32 %call5, ptr %large2, align 4
243   call void @end_large_nonchar()
244   %call7 = call signext i8 @get_small_char()
245   store i8 %call7, ptr %small, align 1
246   call void @end_small_char()
247   %call9 = call signext i8 @get_large_char()
248   store i8 %call9, ptr %large, align 1
249   call void @end_large_char()
250   %call11 = call signext i8 @get_struct_large_char()
251   store i8 %call11, ptr %a, align 1
252   call void @end_struct_large_char()
253   %call13 = call signext i8 @get_struct_small_char()
254   store i8 %call13, ptr %b, align 1
255   call void @end_struct_small_char()
256   %call16 = call i32 @get_struct_large_nonchar()
257   store i32 %call16, ptr %c, align 4
258   call void @end_struct_large_nonchar()
259   %call19 = call signext i16 @get_struct_small_nonchar()
260   store i16 %call19, ptr %d, align 2
261   call void @end_struct_small_nonchar()
262   %0 = load i32, ptr %x, align 4
263   %1 = load i32, ptr %y, align 4
264   %2 = load i32, ptr %z, align 4
265   %3 = load i64, ptr %a, align 1
266   %4 = load i16, ptr %b, align 1
267   %5 = load i32, ptr %d, align 1
268   call void @takes_all(i64 %3, i16 %4, ptr byval(%struct.struct_large_nonchar) align 8 %c, i32 %5, ptr %large, ptr %small, ptr %large2, ptr %small2, ptr %ptr, i32 %0, i32 %1, i32 %2)
269   ret void
272 define void @layout_sspreq() nounwind uwtable sspreq {
273 entry:
274 ; Expected stack layout for sspreq is the same as sspstrong
276 ; CHECK: layout_sspreq:
277 ; CHECK: call{{l|q}} get_scalar1
278 ; CHECK: movl %eax, -120(
279 ; CHECK: call{{l|q}} end_scalar1
281 ; CHECK: call{{l|q}} get_scalar2
282 ; CHECK: movl %eax, -124(
283 ; CHECK: call{{l|q}} end_scalar2
285 ; CHECK: call{{l|q}} get_scalar3
286 ; CHECK: movl %eax, -128(
287 ; CHECK: call{{l|q}} end_scalar3
289 ; CHECK: call{{l|q}} get_addrof
290 ; CHECK: movl %eax, -116(
291 ; CHECK: call{{l|q}} end_addrof
293 ; CHECK: get_small_nonchar
294 ; CHECK: movw %ax, -100(
295 ; CHECK: call{{l|q}} end_small_nonchar
297 ; CHECK: call{{l|q}} get_large_nonchar
298 ; CHECK: movl %eax, -48(
299 ; CHECK: call{{l|q}} end_large_nonchar
301 ; CHECK: call{{l|q}} get_small_char
302 ; CHECK: movb %al, -102(
303 ; CHECK: call{{l|q}} end_small_char
305 ; CHECK: call{{l|q}} get_large_char
306 ; CHECK: movb %al, -56(
307 ; CHECK: call{{l|q}} end_large_char
309 ; CHECK: call{{l|q}} get_struct_large_char
310 ; CHECK: movb %al, -64(
311 ; CHECK: call{{l|q}} end_struct_large_char
313 ; CHECK: call{{l|q}} get_struct_small_char
314 ; CHECK: movb %al, -104(
315 ; CHECK: call{{l|q}} end_struct_small_char
317 ; CHECK: call{{l|q}} get_struct_large_nonchar
318 ; CHECK: movl %eax, -96(
319 ; CHECK: call{{l|q}} end_struct_large_nonchar
321 ; CHECK: call{{l|q}} get_struct_small_nonchar
322 ; CHECK: movw %ax, -112(
323 ; CHECK: call{{l|q}} end_struct_small_nonchar
324   %x = alloca i32, align 4
325   %y = alloca i32, align 4
326   %z = alloca i32, align 4
327   %ptr = alloca i32, align 4
328   %small2 = alloca [2 x i16], align 4
329   %large2 = alloca [8 x i32], align 16
330   %small = alloca [2 x i8], align 2
331   %large = alloca [8 x i8], align 8
332   %a = alloca %struct.struct_large_char, align 8
333   %b = alloca %struct.struct_small_char, align 8
334   %c = alloca %struct.struct_large_nonchar, align 8
335   %d = alloca %struct.struct_small_nonchar, align 8
336   %call = call i32 @get_scalar1()
337   store i32 %call, ptr %x, align 4
338   call void @end_scalar1()
339   %call1 = call i32 @get_scalar2()
340   store i32 %call1, ptr %y, align 4
341   call void @end_scalar2()
342   %call2 = call i32 @get_scalar3()
343   store i32 %call2, ptr %z, align 4
344   call void @end_scalar3()
345   %call3 = call i32 @get_addrof()
346   store i32 %call3, ptr %ptr, align 4
347   call void @end_addrof()
348   %call4 = call signext i16 @get_small_nonchar()
349   store i16 %call4, ptr %small2, align 2
350   call void @end_small_nonchar()
351   %call5 = call i32 @get_large_nonchar()
352   store i32 %call5, ptr %large2, align 4
353   call void @end_large_nonchar()
354   %call7 = call signext i8 @get_small_char()
355   store i8 %call7, ptr %small, align 1
356   call void @end_small_char()
357   %call9 = call signext i8 @get_large_char()
358   store i8 %call9, ptr %large, align 1
359   call void @end_large_char()
360   %call11 = call signext i8 @get_struct_large_char()
361   store i8 %call11, ptr %a, align 1
362   call void @end_struct_large_char()
363   %call13 = call signext i8 @get_struct_small_char()
364   store i8 %call13, ptr %b, align 1
365   call void @end_struct_small_char()
366   %call16 = call i32 @get_struct_large_nonchar()
367   store i32 %call16, ptr %c, align 4
368   call void @end_struct_large_nonchar()
369   %call19 = call signext i16 @get_struct_small_nonchar()
370   store i16 %call19, ptr %d, align 2
371   call void @end_struct_small_nonchar()
372   %0 = load i32, ptr %x, align 4
373   %1 = load i32, ptr %y, align 4
374   %2 = load i32, ptr %z, align 4
375   %3 = load i64, ptr %a, align 1
376   %4 = load i16, ptr %b, align 1
377   %5 = load i32, ptr %d, align 1
378   call void @takes_all(i64 %3, i16 %4, ptr byval(%struct.struct_large_nonchar) align 8 %c, i32 %5, ptr %large, ptr %small, ptr %large2, ptr %small2, ptr %ptr, i32 %0, i32 %1, i32 %2)
379   ret void
382 define void @fast_non_linux() ssp {
383 entry:
384 ; FAST-NON-LIN: fast_non_linux:
385 ; FAST-NON-LIN: call{{l|q}} get_scalar1
386 ; FAST-NON-LIN: movl %eax, -20(
387 ; FAST-NON-LIN: call{{l|q}} end_scalar1
389 ; FAST-NON-LIN: call{{l|q}} get_large_char
390 ; FAST-NON-LIN: movb %al, -16(
391 ; FAST-NON-LIN: call{{l|q}} end_large_char
392   %x = alloca i32, align 4
393   %large = alloca [8 x i8], align 1
394   %call = call i32 @get_scalar1()
395   store i32 %call, ptr %x, align 4
396   call void @end_scalar1()
397   %call1 = call signext i8 @get_large_char()
398   store i8 %call1, ptr %large, align 1
399   call void @end_large_char()
400   %0 = load i32, ptr %x, align 4
401   call void @takes_two(i32 %0, ptr %large)
402   ret void
405 declare i32 @get_scalar1()
406 declare void @end_scalar1()
408 declare i32 @get_scalar2()
409 declare void @end_scalar2()
411 declare i32 @get_scalar3()
412 declare void @end_scalar3()
414 declare i32 @get_addrof()
415 declare void @end_addrof()
417 declare signext i16 @get_small_nonchar()
418 declare void @end_small_nonchar()
420 declare i32 @get_large_nonchar()
421 declare void @end_large_nonchar()
423 declare signext i8 @get_small_char()
424 declare void @end_small_char()
426 declare signext i8 @get_large_char()
427 declare void @end_large_char()
429 declare signext i8 @get_struct_large_char()
430 declare void @end_struct_large_char()
432 declare signext i8 @get_struct_small_char()
433 declare void @end_struct_small_char()
435 declare i32 @get_struct_large_nonchar()
436 declare void @end_struct_large_nonchar()
438 declare signext i16 @get_struct_small_nonchar()
439 declare void @end_struct_small_nonchar()
441 declare void @takes_all(i64, i16, ptr byval(%struct.struct_large_nonchar) align 8, i32, ptr, ptr, ptr, ptr, ptr, i32, i32, i32)
442 declare void @takes_two(i32, ptr)