blob: 92fa0809ed2df47e22eefffcbe8b34a393a3bbd7 [file] [log] [blame]
Josh Magee58fa4932013-12-19 18:14:42 +00001; RUN: llc < %s -disable-fp-elim -march=arm -mcpu=cortex-a8 -mtriple arm-linux-gnu -o - | FileCheck %s
Josh Magee22b8ba22013-12-19 03:17:11 +00002; 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.
9;
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
15%struct.struct_large_char = type { [8 x i8] }
16%struct.struct_large_char2 = type { [2 x i8], [8 x i8] }
17%struct.struct_small_char = type { [2 x i8] }
18%struct.struct_large_nonchar = type { [8 x i32] }
19%struct.struct_small_nonchar = type { [2 x i16] }
20
21define void @layout_ssp() ssp {
22entry:
23; Expected stack layout for ssp is
Richard Barton30934c02015-03-17 18:20:47 +000024; 176 large_char . Group 1, nested arrays, arrays >= ssp-buffer-size
25; 168 struct_large_char .
26; 164 scalar1 | Everything else
27; 160 scalar2
28; 156 scalar3
29; 152 addr-of
30; 148 small_nonchar
Josh Magee22b8ba22013-12-19 03:17:11 +000031; 112 large_nonchar
32; 110 small_char
33; 108 struct_small_char
34; 72 struct_large_nonchar
35; 68 struct_small_nonchar
36
37; CHECK: layout_ssp:
Josh Magee22b8ba22013-12-19 03:17:11 +000038
39; CHECK: bl get_scalar1
Richard Barton30934c02015-03-17 18:20:47 +000040; CHECK: str r0, [sp, #164]
Josh Magee22b8ba22013-12-19 03:17:11 +000041; CHECK: bl end_scalar1
42
43; CHECK: bl get_scalar2
Richard Barton30934c02015-03-17 18:20:47 +000044; CHECK: str r0, [sp, #160]
Josh Magee22b8ba22013-12-19 03:17:11 +000045; CHECK: bl end_scalar2
46
47; CHECK: bl get_scalar3
Richard Barton30934c02015-03-17 18:20:47 +000048; CHECK: str r0, [sp, #156]
Josh Magee22b8ba22013-12-19 03:17:11 +000049; CHECK: bl end_scalar3
50
51; CHECK: bl get_addrof
Richard Barton30934c02015-03-17 18:20:47 +000052; CHECK: str r0, [sp, #152]
Josh Magee22b8ba22013-12-19 03:17:11 +000053; CHECK: bl end_addrof
54
55; CHECK: get_small_nonchar
Richard Barton30934c02015-03-17 18:20:47 +000056; CHECK: strh r0, [sp, #148]
Josh Magee22b8ba22013-12-19 03:17:11 +000057; CHECK: bl end_small_nonchar
58
59; CHECK: bl get_large_nonchar
60; CHECK: str r0, [sp, #112]
61; CHECK: bl end_large_nonchar
62
63; CHECK: bl get_small_char
64; CHECK: strb r0, [sp, #110]
65; CHECK: bl end_small_char
66
67; CHECK: bl get_large_char
Richard Barton30934c02015-03-17 18:20:47 +000068; CHECK: strb r0, [sp, #176]
Josh Magee22b8ba22013-12-19 03:17:11 +000069; CHECK: bl end_large_char
70
71; CHECK: bl get_struct_large_char
Richard Barton30934c02015-03-17 18:20:47 +000072; CHECK: strb r0, [sp, #168]
Josh Magee22b8ba22013-12-19 03:17:11 +000073; CHECK: bl end_struct_large_char
74
75; CHECK: bl get_struct_small_char
76; CHECK: strb r0, [sp, #108]
77; CHECK: bl end_struct_small_char
78
79; CHECK: bl get_struct_large_nonchar
80; CHECK:str r0, [sp, #72]
81; CHECK: bl end_struct_large_nonchar
82
83; CHECK: bl get_struct_small_nonchar
Richard Barton30934c02015-03-17 18:20:47 +000084; CHECK: strh r0, [sp, #68]
Josh Magee22b8ba22013-12-19 03:17:11 +000085; CHECK: bl end_struct_small_nonchar
86 %x = alloca i32, align 4
87 %y = alloca i32, align 4
88 %z = alloca i32, align 4
89 %ptr = alloca i32, align 4
90 %small2 = alloca [2 x i16], align 2
91 %large2 = alloca [8 x i32], align 16
92 %small = alloca [2 x i8], align 1
93 %large = alloca [8 x i8], align 1
94 %a = alloca %struct.struct_large_char, align 1
95 %b = alloca %struct.struct_small_char, align 1
96 %c = alloca %struct.struct_large_nonchar, align 8
97 %d = alloca %struct.struct_small_nonchar, align 2
98 %call = call i32 @get_scalar1()
99 store i32 %call, i32* %x, align 4
100 call void @end_scalar1()
101 %call1 = call i32 @get_scalar2()
102 store i32 %call1, i32* %y, align 4
103 call void @end_scalar2()
104 %call2 = call i32 @get_scalar3()
105 store i32 %call2, i32* %z, align 4
106 call void @end_scalar3()
107 %call3 = call i32 @get_addrof()
108 store i32 %call3, i32* %ptr, align 4
109 call void @end_addrof()
110 %call4 = call signext i16 @get_small_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000111 %arrayidx = getelementptr inbounds [2 x i16], [2 x i16]* %small2, i32 0, i64 0
Josh Magee22b8ba22013-12-19 03:17:11 +0000112 store i16 %call4, i16* %arrayidx, align 2
113 call void @end_small_nonchar()
114 %call5 = call i32 @get_large_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000115 %arrayidx6 = getelementptr inbounds [8 x i32], [8 x i32]* %large2, i32 0, i64 0
Josh Magee22b8ba22013-12-19 03:17:11 +0000116 store i32 %call5, i32* %arrayidx6, align 4
117 call void @end_large_nonchar()
118 %call7 = call signext i8 @get_small_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000119 %arrayidx8 = getelementptr inbounds [2 x i8], [2 x i8]* %small, i32 0, i64 0
Josh Magee22b8ba22013-12-19 03:17:11 +0000120 store i8 %call7, i8* %arrayidx8, align 1
121 call void @end_small_char()
122 %call9 = call signext i8 @get_large_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000123 %arrayidx10 = getelementptr inbounds [8 x i8], [8 x i8]* %large, i32 0, i64 0
Josh Magee22b8ba22013-12-19 03:17:11 +0000124 store i8 %call9, i8* %arrayidx10, align 1
125 call void @end_large_char()
126 %call11 = call signext i8 @get_struct_large_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000127 %foo = getelementptr inbounds %struct.struct_large_char, %struct.struct_large_char* %a, i32 0, i32 0
128 %arrayidx12 = getelementptr inbounds [8 x i8], [8 x i8]* %foo, i32 0, i64 0
Josh Magee22b8ba22013-12-19 03:17:11 +0000129 store i8 %call11, i8* %arrayidx12, align 1
130 call void @end_struct_large_char()
131 %call13 = call signext i8 @get_struct_small_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000132 %foo14 = getelementptr inbounds %struct.struct_small_char, %struct.struct_small_char* %b, i32 0, i32 0
133 %arrayidx15 = getelementptr inbounds [2 x i8], [2 x i8]* %foo14, i32 0, i64 0
Josh Magee22b8ba22013-12-19 03:17:11 +0000134 store i8 %call13, i8* %arrayidx15, align 1
135 call void @end_struct_small_char()
136 %call16 = call i32 @get_struct_large_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000137 %foo17 = getelementptr inbounds %struct.struct_large_nonchar, %struct.struct_large_nonchar* %c, i32 0, i32 0
138 %arrayidx18 = getelementptr inbounds [8 x i32], [8 x i32]* %foo17, i32 0, i64 0
Josh Magee22b8ba22013-12-19 03:17:11 +0000139 store i32 %call16, i32* %arrayidx18, align 4
140 call void @end_struct_large_nonchar()
141 %call19 = call signext i16 @get_struct_small_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000142 %foo20 = getelementptr inbounds %struct.struct_small_nonchar, %struct.struct_small_nonchar* %d, i32 0, i32 0
143 %arrayidx21 = getelementptr inbounds [2 x i16], [2 x i16]* %foo20, i32 0, i64 0
Josh Magee22b8ba22013-12-19 03:17:11 +0000144 store i16 %call19, i16* %arrayidx21, align 2
145 call void @end_struct_small_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000146 %arraydecay = getelementptr inbounds [8 x i8], [8 x i8]* %large, i32 0, i32 0
147 %arraydecay22 = getelementptr inbounds [2 x i8], [2 x i8]* %small, i32 0, i32 0
148 %arraydecay23 = getelementptr inbounds [8 x i32], [8 x i32]* %large2, i32 0, i32 0
149 %arraydecay24 = getelementptr inbounds [2 x i16], [2 x i16]* %small2, i32 0, i32 0
David Blaikiea79ac142015-02-27 21:17:42 +0000150 %0 = load i32, i32* %x, align 4
151 %1 = load i32, i32* %y, align 4
152 %2 = load i32, i32* %z, align 4
David Blaikie79e6c742015-02-27 19:29:02 +0000153 %coerce.dive = getelementptr %struct.struct_large_char, %struct.struct_large_char* %a, i32 0, i32 0
Josh Magee22b8ba22013-12-19 03:17:11 +0000154 %3 = bitcast [8 x i8]* %coerce.dive to i64*
David Blaikiea79ac142015-02-27 21:17:42 +0000155 %4 = load i64, i64* %3, align 1
David Blaikie79e6c742015-02-27 19:29:02 +0000156 %coerce.dive25 = getelementptr %struct.struct_small_char, %struct.struct_small_char* %b, i32 0, i32 0
Josh Magee22b8ba22013-12-19 03:17:11 +0000157 %5 = bitcast [2 x i8]* %coerce.dive25 to i16*
David Blaikiea79ac142015-02-27 21:17:42 +0000158 %6 = load i16, i16* %5, align 1
David Blaikie79e6c742015-02-27 19:29:02 +0000159 %coerce.dive26 = getelementptr %struct.struct_small_nonchar, %struct.struct_small_nonchar* %d, i32 0, i32 0
Josh Magee22b8ba22013-12-19 03:17:11 +0000160 %7 = bitcast [2 x i16]* %coerce.dive26 to i32*
David Blaikiea79ac142015-02-27 21:17:42 +0000161 %8 = load i32, i32* %7, align 1
Tim Northover8cda34f2015-03-11 18:54:22 +0000162 call void @takes_all(i64 %4, i16 %6, %struct.struct_large_nonchar* byval align 4 %c, i32 %8, i8* %arraydecay, i8* %arraydecay22, i32* %arraydecay23, i16* %arraydecay24, i32* %ptr, i32 %0, i32 %1, i32 %2)
Josh Magee22b8ba22013-12-19 03:17:11 +0000163 ret void
164}
165
Josh Magee24c7f062014-02-01 01:36:16 +0000166define void @layout_sspstrong() sspstrong {
167entry:
168; Expected stack layout for sspstrong is
169; 144 large_nonchar . Group 1, nested arrays,
170; 136 large_char . arrays >= ssp-buffer-size
171; 128 struct_large_char .
172; 96 struct_large_nonchar .
173; 84+8 small_non_char | Group 2, nested arrays,
174; 90 small_char | arrays < ssp-buffer-size
175; 88 struct_small_char |
176; 84 struct_small_nonchar |
177; 80 addrof * Group 3, addr-of local
178; 76 scalar1 + Group 4, everything else
179; 72 scalar2 +
180; 68 scalar3 +
181;
182; CHECK: layout_sspstrong:
Josh Magee24c7f062014-02-01 01:36:16 +0000183
184; CHECK: bl get_scalar1
185; CHECK: str r0, [sp, #76]
186; CHECK: bl end_scalar1
187
188; CHECK: bl get_scalar2
189; CHECK: str r0, [sp, #72]
190; CHECK: bl end_scalar2
191
192; CHECK: bl get_scalar3
193; CHECK: str r0, [sp, #68]
194; CHECK: bl end_scalar3
195
196; CHECK: bl get_addrof
197; CHECK: str r0, [sp, #80]
198; CHECK: bl end_addrof
199
200; CHECK: get_small_nonchar
Richard Barton30934c02015-03-17 18:20:47 +0000201; CHECK: strh r0, [sp, #92]
Josh Magee24c7f062014-02-01 01:36:16 +0000202; CHECK: bl end_small_nonchar
203
204; CHECK: bl get_large_nonchar
205; CHECK: str r0, [sp, #144]
206; CHECK: bl end_large_nonchar
207
208; CHECK: bl get_small_char
209; CHECK: strb r0, [sp, #90]
210; CHECK: bl end_small_char
211
212; CHECK: bl get_large_char
213; CHECK: strb r0, [sp, #136]
214; CHECK: bl end_large_char
215
216; CHECK: bl get_struct_large_char
217; CHECK: strb r0, [sp, #128]
218; CHECK: bl end_struct_large_char
219
220; CHECK: bl get_struct_small_char
221; CHECK: strb r0, [sp, #88]
222; CHECK: bl end_struct_small_char
223
224; CHECK: bl get_struct_large_nonchar
225; CHECK: str r0, [sp, #96]
226; CHECK: bl end_struct_large_nonchar
227
228; CHECK: bl get_struct_small_nonchar
Richard Barton30934c02015-03-17 18:20:47 +0000229; CHECK: strh r0, [sp, #84]
Josh Magee24c7f062014-02-01 01:36:16 +0000230; CHECK: bl end_struct_small_nonchar
231 %x = alloca i32, align 4
232 %y = alloca i32, align 4
233 %z = alloca i32, align 4
234 %ptr = alloca i32, align 4
235 %small2 = alloca [2 x i16], align 2
236 %large2 = alloca [8 x i32], align 16
237 %small = alloca [2 x i8], align 1
238 %large = alloca [8 x i8], align 1
239 %a = alloca %struct.struct_large_char, align 1
240 %b = alloca %struct.struct_small_char, align 1
241 %c = alloca %struct.struct_large_nonchar, align 8
242 %d = alloca %struct.struct_small_nonchar, align 2
243 %call = call i32 @get_scalar1()
244 store i32 %call, i32* %x, align 4
245 call void @end_scalar1()
246 %call1 = call i32 @get_scalar2()
247 store i32 %call1, i32* %y, align 4
248 call void @end_scalar2()
249 %call2 = call i32 @get_scalar3()
250 store i32 %call2, i32* %z, align 4
251 call void @end_scalar3()
252 %call3 = call i32 @get_addrof()
253 store i32 %call3, i32* %ptr, align 4
254 call void @end_addrof()
255 %call4 = call signext i16 @get_small_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000256 %arrayidx = getelementptr inbounds [2 x i16], [2 x i16]* %small2, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000257 store i16 %call4, i16* %arrayidx, align 2
258 call void @end_small_nonchar()
259 %call5 = call i32 @get_large_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000260 %arrayidx6 = getelementptr inbounds [8 x i32], [8 x i32]* %large2, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000261 store i32 %call5, i32* %arrayidx6, align 4
262 call void @end_large_nonchar()
263 %call7 = call signext i8 @get_small_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000264 %arrayidx8 = getelementptr inbounds [2 x i8], [2 x i8]* %small, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000265 store i8 %call7, i8* %arrayidx8, align 1
266 call void @end_small_char()
267 %call9 = call signext i8 @get_large_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000268 %arrayidx10 = getelementptr inbounds [8 x i8], [8 x i8]* %large, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000269 store i8 %call9, i8* %arrayidx10, align 1
270 call void @end_large_char()
271 %call11 = call signext i8 @get_struct_large_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000272 %foo = getelementptr inbounds %struct.struct_large_char, %struct.struct_large_char* %a, i32 0, i32 0
273 %arrayidx12 = getelementptr inbounds [8 x i8], [8 x i8]* %foo, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000274 store i8 %call11, i8* %arrayidx12, align 1
275 call void @end_struct_large_char()
276 %call13 = call signext i8 @get_struct_small_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000277 %foo14 = getelementptr inbounds %struct.struct_small_char, %struct.struct_small_char* %b, i32 0, i32 0
278 %arrayidx15 = getelementptr inbounds [2 x i8], [2 x i8]* %foo14, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000279 store i8 %call13, i8* %arrayidx15, align 1
280 call void @end_struct_small_char()
281 %call16 = call i32 @get_struct_large_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000282 %foo17 = getelementptr inbounds %struct.struct_large_nonchar, %struct.struct_large_nonchar* %c, i32 0, i32 0
283 %arrayidx18 = getelementptr inbounds [8 x i32], [8 x i32]* %foo17, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000284 store i32 %call16, i32* %arrayidx18, align 4
285 call void @end_struct_large_nonchar()
286 %call19 = call signext i16 @get_struct_small_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000287 %foo20 = getelementptr inbounds %struct.struct_small_nonchar, %struct.struct_small_nonchar* %d, i32 0, i32 0
288 %arrayidx21 = getelementptr inbounds [2 x i16], [2 x i16]* %foo20, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000289 store i16 %call19, i16* %arrayidx21, align 2
290 call void @end_struct_small_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000291 %arraydecay = getelementptr inbounds [8 x i8], [8 x i8]* %large, i32 0, i32 0
292 %arraydecay22 = getelementptr inbounds [2 x i8], [2 x i8]* %small, i32 0, i32 0
293 %arraydecay23 = getelementptr inbounds [8 x i32], [8 x i32]* %large2, i32 0, i32 0
294 %arraydecay24 = getelementptr inbounds [2 x i16], [2 x i16]* %small2, i32 0, i32 0
David Blaikiea79ac142015-02-27 21:17:42 +0000295 %0 = load i32, i32* %x, align 4
296 %1 = load i32, i32* %y, align 4
297 %2 = load i32, i32* %z, align 4
David Blaikie79e6c742015-02-27 19:29:02 +0000298 %coerce.dive = getelementptr %struct.struct_large_char, %struct.struct_large_char* %a, i32 0, i32 0
Josh Magee24c7f062014-02-01 01:36:16 +0000299 %3 = bitcast [8 x i8]* %coerce.dive to i64*
David Blaikiea79ac142015-02-27 21:17:42 +0000300 %4 = load i64, i64* %3, align 1
David Blaikie79e6c742015-02-27 19:29:02 +0000301 %coerce.dive25 = getelementptr %struct.struct_small_char, %struct.struct_small_char* %b, i32 0, i32 0
Josh Magee24c7f062014-02-01 01:36:16 +0000302 %5 = bitcast [2 x i8]* %coerce.dive25 to i16*
David Blaikiea79ac142015-02-27 21:17:42 +0000303 %6 = load i16, i16* %5, align 1
David Blaikie79e6c742015-02-27 19:29:02 +0000304 %coerce.dive26 = getelementptr %struct.struct_small_nonchar, %struct.struct_small_nonchar* %d, i32 0, i32 0
Josh Magee24c7f062014-02-01 01:36:16 +0000305 %7 = bitcast [2 x i16]* %coerce.dive26 to i32*
David Blaikiea79ac142015-02-27 21:17:42 +0000306 %8 = load i32, i32* %7, align 1
Tim Northover8cda34f2015-03-11 18:54:22 +0000307 call void @takes_all(i64 %4, i16 %6, %struct.struct_large_nonchar* byval align 4 %c, i32 %8, i8* %arraydecay, i8* %arraydecay22, i32* %arraydecay23, i16* %arraydecay24, i32* %ptr, i32 %0, i32 %1, i32 %2)
Josh Magee24c7f062014-02-01 01:36:16 +0000308 ret void
309}
310
311define void @layout_sspreq() sspreq {
312entry:
313; Expected stack layout for sspreq is the same as sspstrong
314;
315; CHECK: layout_sspreq:
Josh Magee24c7f062014-02-01 01:36:16 +0000316
317; CHECK: bl get_scalar1
318; CHECK: str r0, [sp, #76]
319; CHECK: bl end_scalar1
320
321; CHECK: bl get_scalar2
322; CHECK: str r0, [sp, #72]
323; CHECK: bl end_scalar2
324
325; CHECK: bl get_scalar3
326; CHECK: str r0, [sp, #68]
327; CHECK: bl end_scalar3
328
329; CHECK: bl get_addrof
330; CHECK: str r0, [sp, #80]
331; CHECK: bl end_addrof
332
333; CHECK: get_small_nonchar
Richard Barton30934c02015-03-17 18:20:47 +0000334; CHECK: strh r0, [sp, #92]
Josh Magee24c7f062014-02-01 01:36:16 +0000335; CHECK: bl end_small_nonchar
336
337; CHECK: bl get_large_nonchar
338; CHECK: str r0, [sp, #144]
339; CHECK: bl end_large_nonchar
340
341; CHECK: bl get_small_char
342; CHECK: strb r0, [sp, #90]
343; CHECK: bl end_small_char
344
345; CHECK: bl get_large_char
346; CHECK: strb r0, [sp, #136]
347; CHECK: bl end_large_char
348
349; CHECK: bl get_struct_large_char
350; CHECK: strb r0, [sp, #128]
351; CHECK: bl end_struct_large_char
352
353; CHECK: bl get_struct_small_char
354; CHECK: strb r0, [sp, #88]
355; CHECK: bl end_struct_small_char
356
357; CHECK: bl get_struct_large_nonchar
358; CHECK: str r0, [sp, #96]
359; CHECK: bl end_struct_large_nonchar
360
361; CHECK: bl get_struct_small_nonchar
Richard Barton30934c02015-03-17 18:20:47 +0000362; CHECK: strh r0, [sp, #84]
Josh Magee24c7f062014-02-01 01:36:16 +0000363; CHECK: bl end_struct_small_nonchar
364 %x = alloca i32, align 4
365 %y = alloca i32, align 4
366 %z = alloca i32, align 4
367 %ptr = alloca i32, align 4
368 %small2 = alloca [2 x i16], align 2
369 %large2 = alloca [8 x i32], align 16
370 %small = alloca [2 x i8], align 1
371 %large = alloca [8 x i8], align 1
372 %a = alloca %struct.struct_large_char, align 1
373 %b = alloca %struct.struct_small_char, align 1
374 %c = alloca %struct.struct_large_nonchar, align 8
375 %d = alloca %struct.struct_small_nonchar, align 2
376 %call = call i32 @get_scalar1()
377 store i32 %call, i32* %x, align 4
378 call void @end_scalar1()
379 %call1 = call i32 @get_scalar2()
380 store i32 %call1, i32* %y, align 4
381 call void @end_scalar2()
382 %call2 = call i32 @get_scalar3()
383 store i32 %call2, i32* %z, align 4
384 call void @end_scalar3()
385 %call3 = call i32 @get_addrof()
386 store i32 %call3, i32* %ptr, align 4
387 call void @end_addrof()
388 %call4 = call signext i16 @get_small_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000389 %arrayidx = getelementptr inbounds [2 x i16], [2 x i16]* %small2, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000390 store i16 %call4, i16* %arrayidx, align 2
391 call void @end_small_nonchar()
392 %call5 = call i32 @get_large_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000393 %arrayidx6 = getelementptr inbounds [8 x i32], [8 x i32]* %large2, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000394 store i32 %call5, i32* %arrayidx6, align 4
395 call void @end_large_nonchar()
396 %call7 = call signext i8 @get_small_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000397 %arrayidx8 = getelementptr inbounds [2 x i8], [2 x i8]* %small, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000398 store i8 %call7, i8* %arrayidx8, align 1
399 call void @end_small_char()
400 %call9 = call signext i8 @get_large_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000401 %arrayidx10 = getelementptr inbounds [8 x i8], [8 x i8]* %large, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000402 store i8 %call9, i8* %arrayidx10, align 1
403 call void @end_large_char()
404 %call11 = call signext i8 @get_struct_large_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000405 %foo = getelementptr inbounds %struct.struct_large_char, %struct.struct_large_char* %a, i32 0, i32 0
406 %arrayidx12 = getelementptr inbounds [8 x i8], [8 x i8]* %foo, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000407 store i8 %call11, i8* %arrayidx12, align 1
408 call void @end_struct_large_char()
409 %call13 = call signext i8 @get_struct_small_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000410 %foo14 = getelementptr inbounds %struct.struct_small_char, %struct.struct_small_char* %b, i32 0, i32 0
411 %arrayidx15 = getelementptr inbounds [2 x i8], [2 x i8]* %foo14, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000412 store i8 %call13, i8* %arrayidx15, align 1
413 call void @end_struct_small_char()
414 %call16 = call i32 @get_struct_large_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000415 %foo17 = getelementptr inbounds %struct.struct_large_nonchar, %struct.struct_large_nonchar* %c, i32 0, i32 0
416 %arrayidx18 = getelementptr inbounds [8 x i32], [8 x i32]* %foo17, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000417 store i32 %call16, i32* %arrayidx18, align 4
418 call void @end_struct_large_nonchar()
419 %call19 = call signext i16 @get_struct_small_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000420 %foo20 = getelementptr inbounds %struct.struct_small_nonchar, %struct.struct_small_nonchar* %d, i32 0, i32 0
421 %arrayidx21 = getelementptr inbounds [2 x i16], [2 x i16]* %foo20, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000422 store i16 %call19, i16* %arrayidx21, align 2
423 call void @end_struct_small_nonchar()
David Blaikie79e6c742015-02-27 19:29:02 +0000424 %arraydecay = getelementptr inbounds [8 x i8], [8 x i8]* %large, i32 0, i32 0
425 %arraydecay22 = getelementptr inbounds [2 x i8], [2 x i8]* %small, i32 0, i32 0
426 %arraydecay23 = getelementptr inbounds [8 x i32], [8 x i32]* %large2, i32 0, i32 0
427 %arraydecay24 = getelementptr inbounds [2 x i16], [2 x i16]* %small2, i32 0, i32 0
David Blaikiea79ac142015-02-27 21:17:42 +0000428 %0 = load i32, i32* %x, align 4
429 %1 = load i32, i32* %y, align 4
430 %2 = load i32, i32* %z, align 4
David Blaikie79e6c742015-02-27 19:29:02 +0000431 %coerce.dive = getelementptr %struct.struct_large_char, %struct.struct_large_char* %a, i32 0, i32 0
Josh Magee24c7f062014-02-01 01:36:16 +0000432 %3 = bitcast [8 x i8]* %coerce.dive to i64*
David Blaikiea79ac142015-02-27 21:17:42 +0000433 %4 = load i64, i64* %3, align 1
David Blaikie79e6c742015-02-27 19:29:02 +0000434 %coerce.dive25 = getelementptr %struct.struct_small_char, %struct.struct_small_char* %b, i32 0, i32 0
Josh Magee24c7f062014-02-01 01:36:16 +0000435 %5 = bitcast [2 x i8]* %coerce.dive25 to i16*
David Blaikiea79ac142015-02-27 21:17:42 +0000436 %6 = load i16, i16* %5, align 1
David Blaikie79e6c742015-02-27 19:29:02 +0000437 %coerce.dive26 = getelementptr %struct.struct_small_nonchar, %struct.struct_small_nonchar* %d, i32 0, i32 0
Josh Magee24c7f062014-02-01 01:36:16 +0000438 %7 = bitcast [2 x i16]* %coerce.dive26 to i32*
David Blaikiea79ac142015-02-27 21:17:42 +0000439 %8 = load i32, i32* %7, align 1
Tim Northover8cda34f2015-03-11 18:54:22 +0000440 call void @takes_all(i64 %4, i16 %6, %struct.struct_large_nonchar* byval align 4 %c, i32 %8, i8* %arraydecay, i8* %arraydecay22, i32* %arraydecay23, i16* %arraydecay24, i32* %ptr, i32 %0, i32 %1, i32 %2)
Josh Magee24c7f062014-02-01 01:36:16 +0000441 ret void
442}
443
444define void @struct_with_protectable_arrays() sspstrong {
445entry:
446; Check to ensure that a structure which contains a small array followed by a
447; large array is assigned to the stack properly as a large object.
448; CHECK: struct_with_protectable_arrays:
449; CHECK: bl get_struct_small_char
450; CHECK: strb r0, [sp, #68]
451; CHECK: bl end_struct_small_char
452; CHECK: bl get_struct_large_char2
453; CHECK: strb r0, [sp, #106]
454; CHECK: bl end_struct_large_char2
455 %a = alloca %struct.struct_small_char, align 1
456 %b = alloca %struct.struct_large_char2, align 1
457 %d1 = alloca %struct.struct_large_nonchar, align 8
458 %d2 = alloca %struct.struct_small_nonchar, align 2
459 %call = call signext i8 @get_struct_small_char()
David Blaikie79e6c742015-02-27 19:29:02 +0000460 %foo = getelementptr inbounds %struct.struct_small_char, %struct.struct_small_char* %a, i32 0, i32 0
461 %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %foo, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000462 store i8 %call, i8* %arrayidx, align 1
463 call void @end_struct_small_char()
464 %call1 = call signext i8 @get_struct_large_char2()
David Blaikie79e6c742015-02-27 19:29:02 +0000465 %foo2 = getelementptr inbounds %struct.struct_large_char2, %struct.struct_large_char2* %b, i32 0, i32 1
466 %arrayidx3 = getelementptr inbounds [8 x i8], [8 x i8]* %foo2, i32 0, i64 0
Josh Magee24c7f062014-02-01 01:36:16 +0000467 store i8 %call1, i8* %arrayidx3, align 1
468 call void @end_struct_large_char2()
469 %0 = bitcast %struct.struct_large_char2* %b to %struct.struct_large_char*
David Blaikie79e6c742015-02-27 19:29:02 +0000470 %coerce.dive = getelementptr %struct.struct_large_char, %struct.struct_large_char* %0, i32 0, i32 0
Josh Magee24c7f062014-02-01 01:36:16 +0000471 %1 = bitcast [8 x i8]* %coerce.dive to i64*
David Blaikiea79ac142015-02-27 21:17:42 +0000472 %2 = load i64, i64* %1, align 1
David Blaikie79e6c742015-02-27 19:29:02 +0000473 %coerce.dive4 = getelementptr %struct.struct_small_char, %struct.struct_small_char* %a, i32 0, i32 0
Josh Magee24c7f062014-02-01 01:36:16 +0000474 %3 = bitcast [2 x i8]* %coerce.dive4 to i16*
David Blaikiea79ac142015-02-27 21:17:42 +0000475 %4 = load i16, i16* %3, align 1
David Blaikie79e6c742015-02-27 19:29:02 +0000476 %coerce.dive5 = getelementptr %struct.struct_small_nonchar, %struct.struct_small_nonchar* %d2, i32 0, i32 0
Josh Magee24c7f062014-02-01 01:36:16 +0000477 %5 = bitcast [2 x i16]* %coerce.dive5 to i32*
David Blaikiea79ac142015-02-27 21:17:42 +0000478 %6 = load i32, i32* %5, align 1
Tim Northover8cda34f2015-03-11 18:54:22 +0000479 call void @takes_all(i64 %2, i16 %4, %struct.struct_large_nonchar* byval align 4 %d1, i32 %6, i8* null, i8* null, i32* null, i16* null, i32* null, i32 0, i32 0, i32 0)
Josh Magee24c7f062014-02-01 01:36:16 +0000480 ret void
481}
482
Josh Magee22b8ba22013-12-19 03:17:11 +0000483declare i32 @get_scalar1()
484declare void @end_scalar1()
485
486declare i32 @get_scalar2()
487declare void @end_scalar2()
488
489declare i32 @get_scalar3()
490declare void @end_scalar3()
491
492declare i32 @get_addrof()
493declare void @end_addrof()
494
495declare signext i16 @get_small_nonchar()
496declare void @end_small_nonchar()
497
498declare i32 @get_large_nonchar()
499declare void @end_large_nonchar()
500
501declare signext i8 @get_small_char()
502declare void @end_small_char()
503
504declare signext i8 @get_large_char()
505declare void @end_large_char()
506
507declare signext i8 @get_struct_large_char()
508declare void @end_struct_large_char()
509
510declare signext i8 @get_struct_large_char2()
511declare void @end_struct_large_char2()
512
513declare signext i8 @get_struct_small_char()
514declare void @end_struct_small_char()
515
516declare i32 @get_struct_large_nonchar()
517declare void @end_struct_large_nonchar()
518
519declare signext i16 @get_struct_small_nonchar()
520declare void @end_struct_small_nonchar()
521
522declare void @takes_all(i64, i16, %struct.struct_large_nonchar* byval align 8, i32, i8*, i8*, i32*, i16*, i32*, i32, i32, i32)