16bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -target-abi darwinpcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s
2651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define signext i8 @f0()
4651f13cea278ec967336033dd032faef0e9fc2ecStephen Hineschar f0(void) {
5651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return 0;
6651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
7651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
8651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Struct as return type. Aggregates <= 16 bytes are passed directly and round
9651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// up to multiple of 8 bytes.
10651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f1()
11651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s1 { char f0; };
12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s1 f1(void) {}
13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f2()
15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s2 { short f0; };
16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s2 f2(void) {}
17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f3()
19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s3 { int f0; };
20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s3 f3(void) {}
21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f4()
23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s4 { struct s4_0 { int f0; } f0; };
24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s4 f4(void) {}
25651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f5()
27651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s5 { struct { } f0; int f1; };
28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s5 f5(void) {}
29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f6()
31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s6 { int f0[1]; };
32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s6 f6(void) {}
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f7()
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s7 { struct { int : 0; } f0; };
36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s7 f7(void) {}
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f8()
39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s8 { struct { int : 0; } f0[1]; };
40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s8 f8(void) {}
41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f9()
43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s9 { int f0; int : 0; };
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s9 f9(void) {}
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f10()
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s10 { int f0; int : 0; int : 0; };
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s10 f10(void) {}
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f11()
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s11 { int : 0; int f0; };
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s11 f11(void) {}
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f12()
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunion u12 { char f0; short f1; int f2; };
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunion u12 f12(void) {}
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Homogeneous Aggregate as return type will be passed directly.
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define %struct.s13 @f13()
60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s13 { float f0; };
61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s13 f13(void) {}
62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define %union.u14 @f14()
63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunion u14 { float f0; };
64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunion u14 f14(void) {}
65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f15()
67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f15(struct s7 a0) {}
68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f16()
70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f16(struct s8 a0) {}
71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f17()
73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s17 { short f0 : 13; char f1 : 4; };
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s17 f17(void) {}
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f18()
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s18 { short f0; char f1 : 4; };
78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s18 f18(void) {}
79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f19()
81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s19 { int f0; struct s8 f1; };
82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s19 f19(void) {}
83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f20()
85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s20 { struct s8 f1; int f0; };
86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s20 f20(void) {}
87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f21()
89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s21 { struct {} f1; int f0 : 4; };
90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s21 f21(void) {}
91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f22()
93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f23()
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f24()
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i128 @f25()
96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define { float, float } @f26()
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define { double, double } @f27()
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex char       f22(void) {}
99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex short      f23(void) {}
100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex int        f24(void) {}
101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex long long  f25(void) {}
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex float      f26(void) {}
103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex double     f27(void) {}
104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f28()
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s28 { _Complex char f0; };
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s28 f28() {}
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f29()
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s29 { _Complex short f0; };
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s29 f29() {}
112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f30()
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s30 { _Complex int f0; };
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s30 f30() {}
116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s31 { char x; };
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f31(struct s31 s) { }
119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f31(i64 %s.coerce)
120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s = alloca %struct.s31, align 8
121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: trunc i64 %s.coerce to i8
122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i8 %{{.*}},
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s32 { double x; };
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f32(struct s32 s) { }
1260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: @f32([1 x double] %{{.*}})
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// A composite type larger than 16 bytes should be passed indirectly.
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s33 { char buf[32*32]; };
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f33(struct s33 s) { }
131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f33(%struct.s33* %s)
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s34 { char c; };
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f34(struct s34 s);
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid g34(struct s34 *s) { f34(*s); }
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: @g34(%struct.s34* %s)
1373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i8, i8* %{{.*}}
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: zext i8 %[[a]] to i64
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @f34(i64 %{{.*}})
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/*
142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * Check that va_arg accesses stack according to ABI alignment
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines */
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hineslong long t1(int i, ...) {
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK: t1
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    __builtin_va_list ap;
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    __builtin_va_start(ap, i);
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-NOT: add i32 %{{.*}} 7
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-NOT: and i32 %{{.*}} -8
150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    long long ll = __builtin_va_arg(ap, long long);
151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    __builtin_va_end(ap);
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return ll;
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesdouble t2(int i, ...) {
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK: t2
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    __builtin_va_list ap;
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    __builtin_va_start(ap, i);
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-NOT: add i32 %{{.*}} 7
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // CHECK-NOT: and i32 %{{.*}} -8
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    double ll = __builtin_va_arg(ap, double);
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    __builtin_va_end(ap);
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return ll;
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <arm_neon.h>
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Homogeneous Vector Aggregate as return type and argument type.
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define %struct.int8x16x2_t @f0_0(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint8x16x2_t f0_0(int8x16_t a0, int8x16_t a1) {
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return vzipq_s8(a0, a1);
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Test direct vector passing.
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef float T_float32x2 __attribute__ ((__vector_size__ (8)));
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef float T_float32x4 __attribute__ ((__vector_size__ (16)));
176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef float T_float32x8 __attribute__ ((__vector_size__ (32)));
177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef float T_float32x16 __attribute__ ((__vector_size__ (64)));
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define <2 x float> @f1_0(<2 x float> %{{.*}})
180651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesT_float32x2 f1_0(T_float32x2 a0) { return a0; }
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define <4 x float> @f1_1(<4 x float> %{{.*}})
182651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesT_float32x4 f1_1(T_float32x4 a0) { return a0; }
183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Vector with length bigger than 16-byte is illegal and is passed indirectly.
184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f1_2(<8 x float>* noalias sret  %{{.*}}, <8 x float>*)
185651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesT_float32x8 f1_2(T_float32x8 a0) { return a0; }
186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f1_3(<16 x float>* noalias sret %{{.*}}, <16 x float>*)
187651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesT_float32x16 f1_3(T_float32x16 a0) { return a0; }
188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Testing alignment with aggregates: HFA, aggregates with size <= 16 bytes and
190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// aggregates with size > 16 bytes.
191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s35
192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   float v[4]; //Testing HFA.
194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16)));
195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s35 s35_with_align;
196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef __attribute__((neon_vector_type(4))) float float32x4_t;
198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesfloat32x4_t f35(int i, s35_with_align s1, s35_with_align s2) {
1990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: define <4 x float> @f35(i32 %i, [4 x float] %s1.coerce, [4 x float] %s2.coerce)
200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s35, align 16
201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s35, align 16
202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = bitcast %struct.s35* %s1 to <4 x float>*
2033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x float>, <4 x float>* %[[a]], align 16
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = bitcast %struct.s35* %s2 to <4 x float>*
2053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x float>, <4 x float>* %[[b]], align 16
206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  float32x4_t v = vaddq_f32(*(float32x4_t *)&s1,
207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                            *(float32x4_t *)&s2);
208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return v;
209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s36
212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   int v[4]; //Testing 16-byte aggregate.
214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16)));
215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s36 s36_with_align;
216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef __attribute__((neon_vector_type(4))) int int32x4_t;
218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint32x4_t f36(int i, s36_with_align s1, s36_with_align s2) {
219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define <4 x i32> @f36(i32 %i, i128 %s1.coerce, i128 %s2.coerce)
220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s36, align 16
221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s36, align 16
222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1
223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1
224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = bitcast %struct.s36* %s1 to <4 x i32>*
2253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x i32>, <4 x i32>* %[[a]], align 16
226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = bitcast %struct.s36* %s2 to <4 x i32>*
2273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x i32>, <4 x i32>* %[[b]], align 16
228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int32x4_t v = vaddq_s32(*(int32x4_t *)&s1,
229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          *(int32x4_t *)&s2);
230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return v;
231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s37
234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   int v[18]; //Testing large aggregate.
236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16)));
237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s37 s37_with_align;
238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint32x4_t f37(int i, s37_with_align s1, s37_with_align s2) {
240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define <4 x i32> @f37(i32 %i, %struct.s37* %s1, %struct.s37* %s2)
241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = bitcast %struct.s37* %s1 to <4 x i32>*
2423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x i32>, <4 x i32>* %[[a]], align 16
243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = bitcast %struct.s37* %s2 to <4 x i32>*
2443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x i32>, <4 x i32>* %[[b]], align 16
245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int32x4_t v = vaddq_s32(*(int32x4_t *)&s1,
246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          *(int32x4_t *)&s2);
247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return v;
248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness37_with_align g37;
250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint32x4_t caller37() {
251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: caller37
252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = alloca %struct.s37, align 16
253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = alloca %struct.s37, align 16
254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy
255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy
256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call <4 x i32> @f37(i32 3, %struct.s37* %[[a]], %struct.s37* %[[b]])
257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f37(3, g37, g37);
258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// rdar://problem/12648441
261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Test passing structs with size < 8, < 16 and > 16
262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// with alignment of 16 and without
263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size <= 8 bytes, without alignment attribute
265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passed as i64 regardless of the align attribute
266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s38
267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i;
269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s;
270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s38 s38_no_align;
272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs in registers
273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f38(int i, s38_no_align s1, s38_no_align s2) {
275651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f38(i32 %i, i64 %s1.coerce, i64 %s2.coerce)
276651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s38, align 8
277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s38, align 8
278651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i64 %s1.coerce, i64* %{{.*}}, align 1
279651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i64 %s2.coerce, i64* %{{.*}}, align 1
2803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s1, i32 0, i32 0
2813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s2, i32 0, i32 0
2823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s1, i32 0, i32 1
2833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s2, i32 0, i32 1
284651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + s1.s + s2.s;
285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness38_no_align g38;
287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness38_no_align g38_2;
288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller38() {
289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller38()
2903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i64, i64* bitcast (%struct.s38* @g38 to i64*), align 1
2913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i64, i64* bitcast (%struct.s38* @g38_2 to i64*), align 1
292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f38(i32 3, i64 %[[a]], i64 %[[b]])
293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f38(3, g38, g38_2);
294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs on stack
296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f38_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              int i9, s38_no_align s1, s38_no_align s2) {
299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f38_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i64 %s1.coerce, i64 %s2.coerce)
300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s38, align 8
301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s38, align 8
302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i64 %s1.coerce, i64* %{{.*}}, align 1
303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i64 %s2.coerce, i64* %{{.*}}, align 1
3043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s1, i32 0, i32 0
3053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s2, i32 0, i32 0
3063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s1, i32 0, i32 1
3073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s2, i32 0, i32 1
308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller38_stack() {
311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller38_stack()
3123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i64, i64* bitcast (%struct.s38* @g38 to i64*), align 1
3133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i64, i64* bitcast (%struct.s38* @g38_2 to i64*), align 1
314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f38_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i64 %[[a]], i64 %[[b]])
315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f38_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g38, g38_2);
316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size <= 8 bytes, with alignment attribute
319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s39
320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
321651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i;
322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s;
323651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16)));
324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s39 s39_with_align;
325651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs in registers
326651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
327651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f39(int i, s39_with_align s1, s39_with_align s2) {
328651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f39(i32 %i, i128 %s1.coerce, i128 %s2.coerce)
329651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s39, align 16
330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s39, align 16
331651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1
332651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1
3333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s1, i32 0, i32 0
3343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s2, i32 0, i32 0
3353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s1, i32 0, i32 1
3363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s2, i32 0, i32 1
337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + s1.s + s2.s;
338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness39_with_align g39;
340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness39_with_align g39_2;
341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller39() {
342651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller39()
3433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i128, i128* bitcast (%struct.s39* @g39 to i128*), align 1
3443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i128, i128* bitcast (%struct.s39* @g39_2 to i128*), align 1
345651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f39(i32 3, i128 %[[a]], i128 %[[b]])
346651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f39(3, g39, g39_2);
347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
348651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs on stack
349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f39_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              int i9, s39_with_align s1, s39_with_align s2) {
352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f39_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i128 %s1.coerce, i128 %s2.coerce)
353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s39, align 16
354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s39, align 16
355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1
356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1
3573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s1, i32 0, i32 0
3583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s2, i32 0, i32 0
3593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s1, i32 0, i32 1
3603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s2, i32 0, i32 1
361651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller39_stack() {
364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller39_stack()
3653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i128, i128* bitcast (%struct.s39* @g39 to i128*), align 1
3663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i128, i128* bitcast (%struct.s39* @g39_2 to i128*), align 1
367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f39_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i128 %[[a]], i128 %[[b]])
368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f39_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g39, g39_2);
369651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size <= 16 bytes, without alignment attribute
372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s40
373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i;
375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s;
376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i2;
377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s2;
378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s40 s40_no_align;
380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs in registers
381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f40(int i, s40_no_align s1, s40_no_align s2) {
383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f40(i32 %i, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce)
384651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s40, align 8
385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s40, align 8
386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store [2 x i64] %s1.coerce, [2 x i64]* %{{.*}}, align 1
387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store [2 x i64] %s2.coerce, [2 x i64]* %{{.*}}, align 1
3883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s1, i32 0, i32 0
3893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s2, i32 0, i32 0
3903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s1, i32 0, i32 1
3913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s2, i32 0, i32 1
392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + s1.s + s2.s;
393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness40_no_align g40;
395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness40_no_align g40_2;
396651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller40() {
397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller40()
3983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40 to [2 x i64]*), align 1
3993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40_2 to [2 x i64]*), align 1
400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f40(i32 3, [2 x i64] %[[a]], [2 x i64] %[[b]])
401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f40(3, g40, g40_2);
402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs on stack
404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f40_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              int i9, s40_no_align s1, s40_no_align s2) {
407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f40_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce)
408651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s40, align 8
409651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s40, align 8
410651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store [2 x i64] %s1.coerce, [2 x i64]* %{{.*}}, align 1
411651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store [2 x i64] %s2.coerce, [2 x i64]* %{{.*}}, align 1
4123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s1, i32 0, i32 0
4133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s2, i32 0, i32 0
4143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s1, i32 0, i32 1
4153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s2, i32 0, i32 1
416651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
417651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
418651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller40_stack() {
419651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller40_stack()
4203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40 to [2 x i64]*), align 1
4213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40_2 to [2 x i64]*), align 1
422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f40_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, [2 x i64] %[[a]], [2 x i64] %[[b]])
423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f40_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g40, g40_2);
424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
425651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
426651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size <= 16 bytes, with alignment attribute
427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s41
428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i;
430651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s;
431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i2;
432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s2;
433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16)));
434651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s41 s41_with_align;
435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs in registers
436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f41(int i, s41_with_align s1, s41_with_align s2) {
438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f41(i32 %i, i128 %s1.coerce, i128 %s2.coerce)
439651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s41, align 16
440651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s41, align 16
441651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1
442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1
4433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s1, i32 0, i32 0
4443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s2, i32 0, i32 0
4453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s1, i32 0, i32 1
4463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s2, i32 0, i32 1
447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + s1.s + s2.s;
448651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
449651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness41_with_align g41;
450651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness41_with_align g41_2;
451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller41() {
452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller41()
4533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i128, i128* bitcast (%struct.s41* @g41 to i128*), align 1
4543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i128, i128* bitcast (%struct.s41* @g41_2 to i128*), align 1
455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f41(i32 3, i128 %[[a]], i128 %[[b]])
456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f41(3, g41, g41_2);
457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs on stack
459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f41_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              int i9, s41_with_align s1, s41_with_align s2) {
462651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f41_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i128 %s1.coerce, i128 %s2.coerce)
463651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s41, align 16
464651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s41, align 16
465651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1
466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1
4673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s1, i32 0, i32 0
4683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s2, i32 0, i32 0
4693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s1, i32 0, i32 1
4703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s2, i32 0, i32 1
471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
472651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller41_stack() {
474651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller41_stack()
4753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i128, i128* bitcast (%struct.s41* @g41 to i128*), align 1
4763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i128, i128* bitcast (%struct.s41* @g41_2 to i128*), align 1
477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f41_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i128 %[[a]], i128 %[[b]])
478651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f41_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g41, g41_2);
479651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
481651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size > 16 bytes, without alignment attribute
482651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s42
483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i;
485651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s;
486651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i2;
487651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s2;
488651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i3;
489651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s3;
490651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
491651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s42 s42_no_align;
492651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs in registers
493651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
494651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f42(int i, s42_no_align s1, s42_no_align s2) {
495651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f42(i32 %i, %struct.s42* %s1, %struct.s42* %s2)
4963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s1, i32 0, i32 0
4973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s2, i32 0, i32 0
4983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s1, i32 0, i32 1
4993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s2, i32 0, i32 1
500651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + s1.s + s2.s;
501651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
502651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness42_no_align g42;
503651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness42_no_align g42_2;
504651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller42() {
505651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller42()
506651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = alloca %struct.s42, align 4
507651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = alloca %struct.s42, align 4
508651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[c:.*]] = bitcast %struct.s42* %[[a]] to i8*
509651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
510651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[d:.*]] = bitcast %struct.s42* %[[b]] to i8*
511651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
512651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f42(i32 3, %struct.s42* %[[a]], %struct.s42* %[[b]])
513651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f42(3, g42, g42_2);
514651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs on stack
516651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
517651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f42_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
518651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              int i9, s42_no_align s1, s42_no_align s2) {
519651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f42_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, %struct.s42* %s1, %struct.s42* %s2)
5203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s1, i32 0, i32 0
5213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s2, i32 0, i32 0
5223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s1, i32 0, i32 1
5233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s2, i32 0, i32 1
524651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
525651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
526651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller42_stack() {
527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller42_stack()
528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = alloca %struct.s42, align 4
529651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = alloca %struct.s42, align 4
530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[c:.*]] = bitcast %struct.s42* %[[a]] to i8*
531651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
532651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[d:.*]] = bitcast %struct.s42* %[[b]] to i8*
533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
534651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f42_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, %struct.s42* %[[a]], %struct.s42* %[[b]])
535651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f42_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g42, g42_2);
536651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
537651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size > 16 bytes, with alignment attribute
539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s43
540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i;
542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s;
543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i2;
544651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s2;
545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int i3;
546651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  short s3;
547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16)));
548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s43 s43_with_align;
549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs in registers
550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
551651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f43(int i, s43_with_align s1, s43_with_align s2) {
552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f43(i32 %i, %struct.s43* %s1, %struct.s43* %s2)
5533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s1, i32 0, i32 0
5543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s2, i32 0, i32 0
5553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s1, i32 0, i32 1
5563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s2, i32 0, i32 1
557651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + s1.s + s2.s;
558651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness43_with_align g43;
560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness43_with_align g43_2;
561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller43() {
562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller43()
563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = alloca %struct.s43, align 16
564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = alloca %struct.s43, align 16
565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[c:.*]] = bitcast %struct.s43* %[[a]] to i8*
566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[d:.*]] = bitcast %struct.s43* %[[b]] to i8*
568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f43(i32 3, %struct.s43* %[[a]], %struct.s43* %[[b]])
570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f43(3, g43, g43_2);
571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs on stack
573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f43_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              int i9, s43_with_align s1, s43_with_align s2) {
576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f43_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, %struct.s43* %s1, %struct.s43* %s2)
5773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s1, i32 0, i32 0
5783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s2, i32 0, i32 0
5793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s1, i32 0, i32 1
5803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s2, i32 0, i32 1
581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
583651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller43_stack() {
584651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller43_stack()
585651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = alloca %struct.s43, align 16
586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = alloca %struct.s43, align 16
587651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[c:.*]] = bitcast %struct.s43* %[[a]] to i8*
588651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[d:.*]] = bitcast %struct.s43* %[[b]] to i8*
590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
591651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f43_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, %struct.s43* %[[a]], %struct.s43* %[[b]])
592651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f43_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g43, g43_2);
593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
595651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// rdar://13668927
596651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// We should not split argument s1 between registers and stack.
597651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
598651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f40_split(int i, int i2, int i3, int i4, int i5, int i6, int i7,
599651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              s40_no_align s1, s40_no_align s2) {
6000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: define i32 @f40_split(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce)
601651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + s1.s + s2.s;
602651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
603651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller40_split() {
604651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller40_split()
6050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: call i32 @f40_split(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, [2 x i64] %{{.*}} [2 x i64] %{{.*}})
606651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f40_split(1, 2, 3, 4, 5, 6, 7, g40, g40_2);
607651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
608651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
609651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline))
610651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f41_split(int i, int i2, int i3, int i4, int i5, int i6, int i7,
611651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines              s41_with_align s1, s41_with_align s2) {
6120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: define i32 @f41_split(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i128 %s1.coerce, i128 %s2.coerce)
613651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + s1.s + s2.s;
614651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
615651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller41_split() {
616651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller41_split()
6170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: call i32 @f41_split(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i128 %{{.*}}, i128 %{{.*}})
618651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return f41_split(1, 2, 3, 4, 5, 6, 7, g41, g41_2);
619651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
620651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
621651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Handle homogeneous aggregates properly in variadic functions.
622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct HFA {
623651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  float a, b, c, d;
624651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
625651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesfloat test_hfa(int n, ...) {
627651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: define float @test_hfa(i32 %n, ...)
628651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[THELIST:%.*]] = alloca i8*
6293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[CURLIST:%.*]] = load i8*, i8** [[THELIST]]
630651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
631651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // HFA is not indirect, so occupies its full 16 bytes on the stack.
6323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[NEXTLIST:%.*]] = getelementptr i8, i8* [[CURLIST]], i32 16
633651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]]
634651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
635651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: bitcast i8* [[CURLIST]] to %struct.HFA*
636651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __builtin_va_list thelist;
637651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __builtin_va_start(thelist, n);
638651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct HFA h = __builtin_va_arg(thelist, struct HFA);
639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return h.d;
640651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
6426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesfloat test_hfa_call(struct HFA *a) {
6436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-LABEL: define float @test_hfa_call(%struct.HFA* %a)
64433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar// CHECK: call float (i32, ...) @test_hfa(i32 1, [4 x float] {{.*}})
6456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  test_hfa(1, *a);
6466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
6476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
648651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct TooBigHFA {
649651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  float a, b, c, d, e;
650651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
652651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesfloat test_toobig_hfa(int n, ...) {
653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: define float @test_toobig_hfa(i32 %n, ...)
654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[THELIST:%.*]] = alloca i8*
6553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[CURLIST:%.*]] = load i8*, i8** [[THELIST]]
656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // TooBigHFA is not actually an HFA, so gets passed indirectly. Only 8 bytes
658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // of stack consumed.
6593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[NEXTLIST:%.*]] = getelementptr i8, i8* [[CURLIST]], i32 8
660651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]]
661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[HFAPTRPTR:%.*]] = bitcast i8* [[CURLIST]] to i8**
6633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[HFAPTR:%.*]] = load i8*, i8** [[HFAPTRPTR]]
664651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: bitcast i8* [[HFAPTR]] to %struct.TooBigHFA*
665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __builtin_va_list thelist;
666651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __builtin_va_start(thelist, n);
667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct TooBigHFA h = __builtin_va_arg(thelist, struct TooBigHFA);
668651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return h.d;
669651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
671651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct HVA {
672651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int32x4_t a, b;
673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
674651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
675651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint32x4_t test_hva(int n, ...) {
676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: define <4 x i32> @test_hva(i32 %n, ...)
677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[THELIST:%.*]] = alloca i8*
6783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[CURLIST:%.*]] = load i8*, i8** [[THELIST]]
679651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
680651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // HVA is not indirect, so occupies its full 16 bytes on the stack. but it
681651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // must be properly aligned.
6823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[ALIGN0:%.*]] = getelementptr i8, i8* [[CURLIST]], i32 15
683651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[ALIGN1:%.*]] = ptrtoint i8* [[ALIGN0]] to i64
684651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[ALIGN2:%.*]] = and i64 [[ALIGN1]], -16
685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[ALIGNED_LIST:%.*]] = inttoptr i64 [[ALIGN2]] to i8*
686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
6873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[NEXTLIST:%.*]] = getelementptr i8, i8* [[ALIGNED_LIST]], i32 32
688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]]
689651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
690651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: bitcast i8* [[ALIGNED_LIST]] to %struct.HVA*
691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __builtin_va_list thelist;
692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __builtin_va_start(thelist, n);
693651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct HVA h = __builtin_va_arg(thelist, struct HVA);
694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return h.b;
695651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct TooBigHVA {
698651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int32x4_t a, b, c, d, e;
699651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
700651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
701651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint32x4_t test_toobig_hva(int n, ...) {
702651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: define <4 x i32> @test_toobig_hva(i32 %n, ...)
703651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[THELIST:%.*]] = alloca i8*
7043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[CURLIST:%.*]] = load i8*, i8** [[THELIST]]
705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
706651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // TooBigHVA is not actually an HVA, so gets passed indirectly. Only 8 bytes
707651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // of stack consumed.
7083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[NEXTLIST:%.*]] = getelementptr i8, i8* [[CURLIST]], i32 8
709651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]]
710651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
711651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[HVAPTRPTR:%.*]] = bitcast i8* [[CURLIST]] to i8**
7123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[HVAPTR:%.*]] = load i8*, i8** [[HVAPTRPTR]]
713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: bitcast i8* [[HVAPTR]] to %struct.TooBigHVA*
714651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __builtin_va_list thelist;
715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  __builtin_va_start(thelist, n);
716651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  struct TooBigHVA h = __builtin_va_arg(thelist, struct TooBigHVA);
717651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return h.d;
718651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
719