1 ; RUN: llc < %s -frame-pointer=all -mcpu=cortex-a8 -mtriple arm-linux-gnu -target-abi=apcs -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.
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] }
21 define void @layout_ssp() ssp {
23 ; Expected stack layout for ssp is
24 ; 180 large_char . Group 1, nested arrays, arrays >= ssp-buffer-size
25 ; 172 struct_large_char .
26 ; 168 scalar1 | Everything else
33 ; 108 struct_small_char
34 ; 72 struct_large_nonchar
35 ; 68 struct_small_nonchar
39 ; CHECK: bl get_scalar1
40 ; CHECK: str r0, [sp, #168]
41 ; CHECK: bl end_scalar1
43 ; CHECK: bl get_scalar2
44 ; CHECK: str r0, [sp, #164]
45 ; CHECK: bl end_scalar
47 ; CHECK: bl get_scalar3
48 ; CHECK: str r0, [sp, #160]
49 ; CHECK: bl end_scalar3
51 ; CHECK: bl get_addrof
52 ; CHECK: str r0, [sp, #156]
53 ; CHECK: bl end_addrof
55 ; CHECK: get_small_nonchar
56 ; CHECK: strh r0, [sp, #152]
57 ; CHECK: bl end_small_nonchar
59 ; CHECK: bl get_large_nonchar
60 ; CHECK: str r0, [sp, #112]
61 ; CHECK: bl end_large_nonchar
63 ; CHECK: bl get_small_char
64 ; CHECK: strb r0, [sp, #110]
65 ; CHECK: bl end_small_char
67 ; CHECK: bl get_large_char
68 ; CHECK: strb r0, [sp, #180]
69 ; CHECK: bl end_large_char
71 ; CHECK: bl get_struct_large_char
72 ; CHECK: strb r0, [sp, #172]
73 ; CHECK: bl end_struct_large_char
75 ; CHECK: bl get_struct_small_char
76 ; CHECK: strb r0, [sp, #108]
77 ; CHECK: bl end_struct_small_char
79 ; CHECK: bl get_struct_large_nonchar
80 ; CHECK:str r0, [sp, #72]
81 ; CHECK: bl end_struct_large_nonchar
83 ; CHECK: bl get_struct_small_nonchar
84 ; CHECK: strh r0, [sp, #68]
85 ; 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()
111 %arrayidx = getelementptr inbounds [2 x i16], [2 x i16]* %small2, i32 0, i64 0
112 store i16 %call4, i16* %arrayidx, align 2
113 call void @end_small_nonchar()
114 %call5 = call i32 @get_large_nonchar()
115 %arrayidx6 = getelementptr inbounds [8 x i32], [8 x i32]* %large2, i32 0, i64 0
116 store i32 %call5, i32* %arrayidx6, align 4
117 call void @end_large_nonchar()
118 %call7 = call signext i8 @get_small_char()
119 %arrayidx8 = getelementptr inbounds [2 x i8], [2 x i8]* %small, i32 0, i64 0
120 store i8 %call7, i8* %arrayidx8, align 1
121 call void @end_small_char()
122 %call9 = call signext i8 @get_large_char()
123 %arrayidx10 = getelementptr inbounds [8 x i8], [8 x i8]* %large, i32 0, i64 0
124 store i8 %call9, i8* %arrayidx10, align 1
125 call void @end_large_char()
126 %call11 = call signext i8 @get_struct_large_char()
127 %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
129 store i8 %call11, i8* %arrayidx12, align 1
130 call void @end_struct_large_char()
131 %call13 = call signext i8 @get_struct_small_char()
132 %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
134 store i8 %call13, i8* %arrayidx15, align 1
135 call void @end_struct_small_char()
136 %call16 = call i32 @get_struct_large_nonchar()
137 %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
139 store i32 %call16, i32* %arrayidx18, align 4
140 call void @end_struct_large_nonchar()
141 %call19 = call signext i16 @get_struct_small_nonchar()
142 %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
144 store i16 %call19, i16* %arrayidx21, align 2
145 call void @end_struct_small_nonchar()
146 %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
150 %0 = load i32, i32* %x, align 4
151 %1 = load i32, i32* %y, align 4
152 %2 = load i32, i32* %z, align 4
153 %coerce.dive = getelementptr %struct.struct_large_char, %struct.struct_large_char* %a, i32 0, i32 0
154 %3 = bitcast [8 x i8]* %coerce.dive to i64*
155 %4 = load i64, i64* %3, align 1
156 %coerce.dive25 = getelementptr %struct.struct_small_char, %struct.struct_small_char* %b, i32 0, i32 0
157 %5 = bitcast [2 x i8]* %coerce.dive25 to i16*
158 %6 = load i16, i16* %5, align 1
159 %coerce.dive26 = getelementptr %struct.struct_small_nonchar, %struct.struct_small_nonchar* %d, i32 0, i32 0
160 %7 = bitcast [2 x i16]* %coerce.dive26 to i32*
161 %8 = load i32, i32* %7, align 1
162 call void @takes_all(i64 %4, i16 %6, %struct.struct_large_nonchar* byval(%struct.struct_large_nonchar) align 4 %c, i32 %8, i8* %arraydecay, i8* %arraydecay22, i32* %arraydecay23, i16* %arraydecay24, i32* %ptr, i32 %0, i32 %1, i32 %2)
166 define void @layout_sspstrong() sspstrong {
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
182 ; CHECK: layout_sspstrong:
184 ; CHECK: bl get_scalar1
185 ; CHECK: str r0, [sp, #76]
186 ; CHECK: bl end_scalar1
188 ; CHECK: bl get_scalar2
189 ; CHECK: str r0, [sp, #72]
190 ; CHECK: bl end_scalar2
192 ; CHECK: bl get_scalar3
193 ; CHECK: str r0, [sp, #68]
194 ; CHECK: bl end_scalar3
196 ; CHECK: bl get_addrof
197 ; CHECK: str r0, [sp, #80]
198 ; CHECK: bl end_addrof
200 ; CHECK: get_small_nonchar
201 ; CHECK: strh r0, [sp, #92]
202 ; CHECK: bl end_small_nonchar
204 ; CHECK: bl get_large_nonchar
205 ; CHECK: str r0, [sp, #144]
206 ; CHECK: bl end_large_nonchar
208 ; CHECK: bl get_small_char
209 ; CHECK: strb r0, [sp, #90]
210 ; CHECK: bl end_small_char
212 ; CHECK: bl get_large_char
213 ; CHECK: strb r0, [sp, #136]
214 ; CHECK: bl end_large_char
216 ; CHECK: bl get_struct_large_char
217 ; CHECK: strb r0, [sp, #128]
218 ; CHECK: bl end_struct_large_char
220 ; CHECK: bl get_struct_small_char
221 ; CHECK: strb r0, [sp, #88]
222 ; CHECK: bl end_struct_small_char
224 ; CHECK: bl get_struct_large_nonchar
225 ; CHECK: str r0, [sp, #96]
226 ; CHECK: bl end_struct_large_nonchar
228 ; CHECK: bl get_struct_small_nonchar
229 ; CHECK: strh r0, [sp, #84]
230 ; 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()
256 %arrayidx = getelementptr inbounds [2 x i16], [2 x i16]* %small2, i32 0, i64 0
257 store i16 %call4, i16* %arrayidx, align 2
258 call void @end_small_nonchar()
259 %call5 = call i32 @get_large_nonchar()
260 %arrayidx6 = getelementptr inbounds [8 x i32], [8 x i32]* %large2, i32 0, i64 0
261 store i32 %call5, i32* %arrayidx6, align 4
262 call void @end_large_nonchar()
263 %call7 = call signext i8 @get_small_char()
264 %arrayidx8 = getelementptr inbounds [2 x i8], [2 x i8]* %small, i32 0, i64 0
265 store i8 %call7, i8* %arrayidx8, align 1
266 call void @end_small_char()
267 %call9 = call signext i8 @get_large_char()
268 %arrayidx10 = getelementptr inbounds [8 x i8], [8 x i8]* %large, i32 0, i64 0
269 store i8 %call9, i8* %arrayidx10, align 1
270 call void @end_large_char()
271 %call11 = call signext i8 @get_struct_large_char()
272 %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
274 store i8 %call11, i8* %arrayidx12, align 1
275 call void @end_struct_large_char()
276 %call13 = call signext i8 @get_struct_small_char()
277 %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
279 store i8 %call13, i8* %arrayidx15, align 1
280 call void @end_struct_small_char()
281 %call16 = call i32 @get_struct_large_nonchar()
282 %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
284 store i32 %call16, i32* %arrayidx18, align 4
285 call void @end_struct_large_nonchar()
286 %call19 = call signext i16 @get_struct_small_nonchar()
287 %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
289 store i16 %call19, i16* %arrayidx21, align 2
290 call void @end_struct_small_nonchar()
291 %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
295 %0 = load i32, i32* %x, align 4
296 %1 = load i32, i32* %y, align 4
297 %2 = load i32, i32* %z, align 4
298 %coerce.dive = getelementptr %struct.struct_large_char, %struct.struct_large_char* %a, i32 0, i32 0
299 %3 = bitcast [8 x i8]* %coerce.dive to i64*
300 %4 = load i64, i64* %3, align 1
301 %coerce.dive25 = getelementptr %struct.struct_small_char, %struct.struct_small_char* %b, i32 0, i32 0
302 %5 = bitcast [2 x i8]* %coerce.dive25 to i16*
303 %6 = load i16, i16* %5, align 1
304 %coerce.dive26 = getelementptr %struct.struct_small_nonchar, %struct.struct_small_nonchar* %d, i32 0, i32 0
305 %7 = bitcast [2 x i16]* %coerce.dive26 to i32*
306 %8 = load i32, i32* %7, align 1
307 call void @takes_all(i64 %4, i16 %6, %struct.struct_large_nonchar* byval(%struct.struct_large_nonchar) align 4 %c, i32 %8, i8* %arraydecay, i8* %arraydecay22, i32* %arraydecay23, i16* %arraydecay24, i32* %ptr, i32 %0, i32 %1, i32 %2)
311 define void @layout_sspreq() sspreq {
313 ; Expected stack layout for sspreq is the same as sspstrong
315 ; CHECK: layout_sspreq:
317 ; CHECK: bl get_scalar1
318 ; CHECK: str r0, [sp, #76]
319 ; CHECK: bl end_scalar1
321 ; CHECK: bl get_scalar2
322 ; CHECK: str r0, [sp, #72]
323 ; CHECK: bl end_scalar2
325 ; CHECK: bl get_scalar3
326 ; CHECK: str r0, [sp, #68]
327 ; CHECK: bl end_scalar3
329 ; CHECK: bl get_addrof
330 ; CHECK: str r0, [sp, #80]
331 ; CHECK: bl end_addrof
333 ; CHECK: get_small_nonchar
334 ; CHECK: strh r0, [sp, #92]
335 ; CHECK: bl end_small_nonchar
337 ; CHECK: bl get_large_nonchar
338 ; CHECK: str r0, [sp, #144]
339 ; CHECK: bl end_large_nonchar
341 ; CHECK: bl get_small_char
342 ; CHECK: strb r0, [sp, #90]
343 ; CHECK: bl end_small_char
345 ; CHECK: bl get_large_char
346 ; CHECK: strb r0, [sp, #136]
347 ; CHECK: bl end_large_char
349 ; CHECK: bl get_struct_large_char
350 ; CHECK: strb r0, [sp, #128]
351 ; CHECK: bl end_struct_large_char
353 ; CHECK: bl get_struct_small_char
354 ; CHECK: strb r0, [sp, #88]
355 ; CHECK: bl end_struct_small_char
357 ; CHECK: bl get_struct_large_nonchar
358 ; CHECK: str r0, [sp, #96]
359 ; CHECK: bl end_struct_large_nonchar
361 ; CHECK: bl get_struct_small_nonchar
362 ; CHECK: strh r0, [sp, #84]
363 ; 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()
389 %arrayidx = getelementptr inbounds [2 x i16], [2 x i16]* %small2, i32 0, i64 0
390 store i16 %call4, i16* %arrayidx, align 2
391 call void @end_small_nonchar()
392 %call5 = call i32 @get_large_nonchar()
393 %arrayidx6 = getelementptr inbounds [8 x i32], [8 x i32]* %large2, i32 0, i64 0
394 store i32 %call5, i32* %arrayidx6, align 4
395 call void @end_large_nonchar()
396 %call7 = call signext i8 @get_small_char()
397 %arrayidx8 = getelementptr inbounds [2 x i8], [2 x i8]* %small, i32 0, i64 0
398 store i8 %call7, i8* %arrayidx8, align 1
399 call void @end_small_char()
400 %call9 = call signext i8 @get_large_char()
401 %arrayidx10 = getelementptr inbounds [8 x i8], [8 x i8]* %large, i32 0, i64 0
402 store i8 %call9, i8* %arrayidx10, align 1
403 call void @end_large_char()
404 %call11 = call signext i8 @get_struct_large_char()
405 %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
407 store i8 %call11, i8* %arrayidx12, align 1
408 call void @end_struct_large_char()
409 %call13 = call signext i8 @get_struct_small_char()
410 %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
412 store i8 %call13, i8* %arrayidx15, align 1
413 call void @end_struct_small_char()
414 %call16 = call i32 @get_struct_large_nonchar()
415 %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
417 store i32 %call16, i32* %arrayidx18, align 4
418 call void @end_struct_large_nonchar()
419 %call19 = call signext i16 @get_struct_small_nonchar()
420 %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
422 store i16 %call19, i16* %arrayidx21, align 2
423 call void @end_struct_small_nonchar()
424 %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
428 %0 = load i32, i32* %x, align 4
429 %1 = load i32, i32* %y, align 4
430 %2 = load i32, i32* %z, align 4
431 %coerce.dive = getelementptr %struct.struct_large_char, %struct.struct_large_char* %a, i32 0, i32 0
432 %3 = bitcast [8 x i8]* %coerce.dive to i64*
433 %4 = load i64, i64* %3, align 1
434 %coerce.dive25 = getelementptr %struct.struct_small_char, %struct.struct_small_char* %b, i32 0, i32 0
435 %5 = bitcast [2 x i8]* %coerce.dive25 to i16*
436 %6 = load i16, i16* %5, align 1
437 %coerce.dive26 = getelementptr %struct.struct_small_nonchar, %struct.struct_small_nonchar* %d, i32 0, i32 0
438 %7 = bitcast [2 x i16]* %coerce.dive26 to i32*
439 %8 = load i32, i32* %7, align 1
440 call void @takes_all(i64 %4, i16 %6, %struct.struct_large_nonchar* byval(%struct.struct_large_nonchar) align 4 %c, i32 %8, i8* %arraydecay, i8* %arraydecay22, i32* %arraydecay23, i16* %arraydecay24, i32* %ptr, i32 %0, i32 %1, i32 %2)
444 define void @struct_with_protectable_arrays() sspstrong {
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()
460 %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
462 store i8 %call, i8* %arrayidx, align 1
463 call void @end_struct_small_char()
464 %call1 = call signext i8 @get_struct_large_char2()
465 %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
467 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*
470 %coerce.dive = getelementptr %struct.struct_large_char, %struct.struct_large_char* %0, i32 0, i32 0
471 %1 = bitcast [8 x i8]* %coerce.dive to i64*
472 %2 = load i64, i64* %1, align 1
473 %coerce.dive4 = getelementptr %struct.struct_small_char, %struct.struct_small_char* %a, i32 0, i32 0
474 %3 = bitcast [2 x i8]* %coerce.dive4 to i16*
475 %4 = load i16, i16* %3, align 1
476 %coerce.dive5 = getelementptr %struct.struct_small_nonchar, %struct.struct_small_nonchar* %d2, i32 0, i32 0
477 %5 = bitcast [2 x i16]* %coerce.dive5 to i32*
478 %6 = load i32, i32* %5, align 1
479 call void @takes_all(i64 %2, i16 %4, %struct.struct_large_nonchar* byval(%struct.struct_large_nonchar) align 4 %d1, i32 %6, i8* null, i8* null, i32* null, i16* null, i32* null, i32 0, i32 0, i32 0)
483 declare i32 @get_scalar1()
484 declare void @end_scalar1()
486 declare i32 @get_scalar2()
487 declare void @end_scalar2()
489 declare i32 @get_scalar3()
490 declare void @end_scalar3()
492 declare i32 @get_addrof()
493 declare void @end_addrof()
495 declare signext i16 @get_small_nonchar()
496 declare void @end_small_nonchar()
498 declare i32 @get_large_nonchar()
499 declare void @end_large_nonchar()
501 declare signext i8 @get_small_char()
502 declare void @end_small_char()
504 declare signext i8 @get_large_char()
505 declare void @end_large_char()
507 declare signext i8 @get_struct_large_char()
508 declare void @end_struct_large_char()
510 declare signext i8 @get_struct_large_char2()
511 declare void @end_struct_large_char2()
513 declare signext i8 @get_struct_small_char()
514 declare void @end_struct_small_char()
516 declare i32 @get_struct_large_nonchar()
517 declare void @end_struct_large_nonchar()
519 declare signext i16 @get_struct_small_nonchar()
520 declare void @end_struct_small_nonchar()
522 declare void @takes_all(i64, i16, %struct.struct_large_nonchar* byval(%struct.struct_large_nonchar) align 8, i32, i8*, i8*, i32*, i16*, i32*, i32, i32, i32)