1; RUN: llc < %s -disable-fp-elim -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.
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
24;  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
31;  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:
38
39; CHECK: bl get_scalar1
40; CHECK: str r0, [sp, #164]
41; CHECK: bl end_scalar1
42
43; CHECK: bl get_scalar2
44; CHECK: str r0, [sp, #160]
45; CHECK: bl end_scalar2
46
47; CHECK: bl get_scalar3
48; CHECK: str r0, [sp, #156]
49; CHECK: bl end_scalar3
50
51; CHECK: bl get_addrof
52; CHECK: str r0, [sp, #152]
53; CHECK: bl end_addrof
54
55; CHECK: get_small_nonchar
56; CHECK: strh r0, [sp, #148]
57; 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
68; CHECK: strb r0, [sp, #176]
69; CHECK: bl end_large_char
70
71; CHECK: bl get_struct_large_char
72; CHECK: strb r0, [sp, #168]
73; 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
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 align 4 %c, i32 %8, i8* %arraydecay, i8* %arraydecay22, i32* %arraydecay23, i16* %arraydecay24, i32* %ptr, i32 %0, i32 %1, i32 %2)
163  ret void
164}
165
166define 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:
183
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
201; CHECK: strh r0, [sp, #92]
202; 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
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 align 4 %c, i32 %8, i8* %arraydecay, i8* %arraydecay22, i32* %arraydecay23, i16* %arraydecay24, i32* %ptr, i32 %0, i32 %1, i32 %2)
308  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:
316
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
334; CHECK: strh r0, [sp, #92]
335; 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
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 align 4 %c, i32 %8, i8* %arraydecay, i8* %arraydecay22, i32* %arraydecay23, i16* %arraydecay24, i32* %ptr, i32 %0, i32 %1, i32 %2)
441  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()
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 align 4 %d1, i32 %6, i8* null, i8* null, i32* null, i16* null, i32* null, i32 0, i32 0, i32 0)
480  ret void
481}
482
483declare 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)
523