xref: /aosp_15_r20/external/clang/test/CodeGen/ppc64le-aggregates.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -faltivec -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
2*67e74705SXin Li 
3*67e74705SXin Li // Test homogeneous float aggregate passing and returning.
4*67e74705SXin Li 
5*67e74705SXin Li struct f1 { float f[1]; };
6*67e74705SXin Li struct f2 { float f[2]; };
7*67e74705SXin Li struct f3 { float f[3]; };
8*67e74705SXin Li struct f4 { float f[4]; };
9*67e74705SXin Li struct f5 { float f[5]; };
10*67e74705SXin Li struct f6 { float f[6]; };
11*67e74705SXin Li struct f7 { float f[7]; };
12*67e74705SXin Li struct f8 { float f[8]; };
13*67e74705SXin Li struct f9 { float f[9]; };
14*67e74705SXin Li 
15*67e74705SXin Li struct fab { float a; float b; };
16*67e74705SXin Li struct fabc { float a; float b; float c; };
17*67e74705SXin Li 
18*67e74705SXin Li struct f2a2b { float a[2]; float b[2]; };
19*67e74705SXin Li 
20*67e74705SXin Li // CHECK: define [1 x float] @func_f1(float inreg %x.coerce)
func_f1(struct f1 x)21*67e74705SXin Li struct f1 func_f1(struct f1 x) { return x; }
22*67e74705SXin Li 
23*67e74705SXin Li // CHECK: define [2 x float] @func_f2([2 x float] %x.coerce)
func_f2(struct f2 x)24*67e74705SXin Li struct f2 func_f2(struct f2 x) { return x; }
25*67e74705SXin Li 
26*67e74705SXin Li // CHECK: define [3 x float] @func_f3([3 x float] %x.coerce)
func_f3(struct f3 x)27*67e74705SXin Li struct f3 func_f3(struct f3 x) { return x; }
28*67e74705SXin Li 
29*67e74705SXin Li // CHECK: define [4 x float] @func_f4([4 x float] %x.coerce)
func_f4(struct f4 x)30*67e74705SXin Li struct f4 func_f4(struct f4 x) { return x; }
31*67e74705SXin Li 
32*67e74705SXin Li // CHECK: define [5 x float] @func_f5([5 x float] %x.coerce)
func_f5(struct f5 x)33*67e74705SXin Li struct f5 func_f5(struct f5 x) { return x; }
34*67e74705SXin Li 
35*67e74705SXin Li // CHECK: define [6 x float] @func_f6([6 x float] %x.coerce)
func_f6(struct f6 x)36*67e74705SXin Li struct f6 func_f6(struct f6 x) { return x; }
37*67e74705SXin Li 
38*67e74705SXin Li // CHECK: define [7 x float] @func_f7([7 x float] %x.coerce)
func_f7(struct f7 x)39*67e74705SXin Li struct f7 func_f7(struct f7 x) { return x; }
40*67e74705SXin Li 
41*67e74705SXin Li // CHECK: define [8 x float] @func_f8([8 x float] %x.coerce)
func_f8(struct f8 x)42*67e74705SXin Li struct f8 func_f8(struct f8 x) { return x; }
43*67e74705SXin Li 
44*67e74705SXin Li // CHECK: define void @func_f9(%struct.f9* noalias sret %agg.result, [5 x i64] %x.coerce)
func_f9(struct f9 x)45*67e74705SXin Li struct f9 func_f9(struct f9 x) { return x; }
46*67e74705SXin Li 
47*67e74705SXin Li // CHECK: define [2 x float] @func_fab([2 x float] %x.coerce)
func_fab(struct fab x)48*67e74705SXin Li struct fab func_fab(struct fab x) { return x; }
49*67e74705SXin Li 
50*67e74705SXin Li // CHECK: define [3 x float] @func_fabc([3 x float] %x.coerce)
func_fabc(struct fabc x)51*67e74705SXin Li struct fabc func_fabc(struct fabc x) { return x; }
52*67e74705SXin Li 
53*67e74705SXin Li // CHECK: define [4 x float] @func_f2a2b([4 x float] %x.coerce)
func_f2a2b(struct f2a2b x)54*67e74705SXin Li struct f2a2b func_f2a2b(struct f2a2b x) { return x; }
55*67e74705SXin Li 
56*67e74705SXin Li // CHECK-LABEL: @call_f1
57*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load float, float* getelementptr inbounds (%struct.f1, %struct.f1* @global_f1, i32 0, i32 0, i32 0), align 4
58*67e74705SXin Li // CHECK: call [1 x float] @func_f1(float inreg %[[TMP]])
59*67e74705SXin Li struct f1 global_f1;
call_f1(void)60*67e74705SXin Li void call_f1(void) { global_f1 = func_f1(global_f1); }
61*67e74705SXin Li 
62*67e74705SXin Li // CHECK-LABEL: @call_f2
63*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [2 x float], [2 x float]* getelementptr inbounds (%struct.f2, %struct.f2* @global_f2, i32 0, i32 0), align 4
64*67e74705SXin Li // CHECK: call [2 x float] @func_f2([2 x float] %[[TMP]])
65*67e74705SXin Li struct f2 global_f2;
call_f2(void)66*67e74705SXin Li void call_f2(void) { global_f2 = func_f2(global_f2); }
67*67e74705SXin Li 
68*67e74705SXin Li // CHECK-LABEL: @call_f3
69*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [3 x float], [3 x float]* getelementptr inbounds (%struct.f3, %struct.f3* @global_f3, i32 0, i32 0), align 4
70*67e74705SXin Li // CHECK: call [3 x float] @func_f3([3 x float] %[[TMP]])
71*67e74705SXin Li struct f3 global_f3;
call_f3(void)72*67e74705SXin Li void call_f3(void) { global_f3 = func_f3(global_f3); }
73*67e74705SXin Li 
74*67e74705SXin Li // CHECK-LABEL: @call_f4
75*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [4 x float], [4 x float]* getelementptr inbounds (%struct.f4, %struct.f4* @global_f4, i32 0, i32 0), align 4
76*67e74705SXin Li // CHECK: call [4 x float] @func_f4([4 x float] %[[TMP]])
77*67e74705SXin Li struct f4 global_f4;
call_f4(void)78*67e74705SXin Li void call_f4(void) { global_f4 = func_f4(global_f4); }
79*67e74705SXin Li 
80*67e74705SXin Li // CHECK-LABEL: @call_f5
81*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [5 x float], [5 x float]* getelementptr inbounds (%struct.f5, %struct.f5* @global_f5, i32 0, i32 0), align 4
82*67e74705SXin Li // CHECK: call [5 x float] @func_f5([5 x float] %[[TMP]])
83*67e74705SXin Li struct f5 global_f5;
call_f5(void)84*67e74705SXin Li void call_f5(void) { global_f5 = func_f5(global_f5); }
85*67e74705SXin Li 
86*67e74705SXin Li // CHECK-LABEL: @call_f6
87*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [6 x float], [6 x float]* getelementptr inbounds (%struct.f6, %struct.f6* @global_f6, i32 0, i32 0), align 4
88*67e74705SXin Li // CHECK: call [6 x float] @func_f6([6 x float] %[[TMP]])
89*67e74705SXin Li struct f6 global_f6;
call_f6(void)90*67e74705SXin Li void call_f6(void) { global_f6 = func_f6(global_f6); }
91*67e74705SXin Li 
92*67e74705SXin Li // CHECK-LABEL: @call_f7
93*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [7 x float], [7 x float]* getelementptr inbounds (%struct.f7, %struct.f7* @global_f7, i32 0, i32 0), align 4
94*67e74705SXin Li // CHECK: call [7 x float] @func_f7([7 x float] %[[TMP]])
95*67e74705SXin Li struct f7 global_f7;
call_f7(void)96*67e74705SXin Li void call_f7(void) { global_f7 = func_f7(global_f7); }
97*67e74705SXin Li 
98*67e74705SXin Li // CHECK-LABEL: @call_f8
99*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [8 x float], [8 x float]* getelementptr inbounds (%struct.f8, %struct.f8* @global_f8, i32 0, i32 0), align 4
100*67e74705SXin Li // CHECK: call [8 x float] @func_f8([8 x float] %[[TMP]])
101*67e74705SXin Li struct f8 global_f8;
call_f8(void)102*67e74705SXin Li void call_f8(void) { global_f8 = func_f8(global_f8); }
103*67e74705SXin Li 
104*67e74705SXin Li // CHECK-LABEL: @call_f9
105*67e74705SXin Li // CHECK: %[[TMP1:[^ ]+]] = alloca [5 x i64]
106*67e74705SXin Li // CHECK: %[[TMP2:[^ ]+]] = bitcast [5 x i64]* %[[TMP1]] to i8*
107*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %[[TMP2]], i8* bitcast (%struct.f9* @global_f9 to i8*), i64 36, i32 4, i1 false)
108*67e74705SXin Li // CHECK: %[[TMP3:[^ ]+]] = load [5 x i64], [5 x i64]* %[[TMP1]]
109*67e74705SXin Li // CHECK: call void @func_f9(%struct.f9* sret %{{[^ ]+}}, [5 x i64] %[[TMP3]])
110*67e74705SXin Li struct f9 global_f9;
call_f9(void)111*67e74705SXin Li void call_f9(void) { global_f9 = func_f9(global_f9); }
112*67e74705SXin Li 
113*67e74705SXin Li // CHECK-LABEL: @call_fab
114*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [2 x float], [2 x float]* bitcast (%struct.fab* @global_fab to [2 x float]*)
115*67e74705SXin Li // CHECK: call [2 x float] @func_fab([2 x float] %[[TMP]])
116*67e74705SXin Li struct fab global_fab;
call_fab(void)117*67e74705SXin Li void call_fab(void) { global_fab = func_fab(global_fab); }
118*67e74705SXin Li 
119*67e74705SXin Li // CHECK-LABEL: @call_fabc
120*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [3 x float], [3 x float]* bitcast (%struct.fabc* @global_fabc to [3 x float]*)
121*67e74705SXin Li // CHECK: call [3 x float] @func_fabc([3 x float] %[[TMP]])
122*67e74705SXin Li struct fabc global_fabc;
call_fabc(void)123*67e74705SXin Li void call_fabc(void) { global_fabc = func_fabc(global_fabc); }
124*67e74705SXin Li 
125*67e74705SXin Li 
126*67e74705SXin Li // Test homogeneous vector aggregate passing and returning.
127*67e74705SXin Li 
128*67e74705SXin Li struct v1 { vector int v[1]; };
129*67e74705SXin Li struct v2 { vector int v[2]; };
130*67e74705SXin Li struct v3 { vector int v[3]; };
131*67e74705SXin Li struct v4 { vector int v[4]; };
132*67e74705SXin Li struct v5 { vector int v[5]; };
133*67e74705SXin Li struct v6 { vector int v[6]; };
134*67e74705SXin Li struct v7 { vector int v[7]; };
135*67e74705SXin Li struct v8 { vector int v[8]; };
136*67e74705SXin Li struct v9 { vector int v[9]; };
137*67e74705SXin Li 
138*67e74705SXin Li struct vab { vector int a; vector int b; };
139*67e74705SXin Li struct vabc { vector int a; vector int b; vector int c; };
140*67e74705SXin Li 
141*67e74705SXin Li // CHECK: define [1 x <4 x i32>] @func_v1(<4 x i32> inreg %x.coerce)
func_v1(struct v1 x)142*67e74705SXin Li struct v1 func_v1(struct v1 x) { return x; }
143*67e74705SXin Li 
144*67e74705SXin Li // CHECK: define [2 x <4 x i32>] @func_v2([2 x <4 x i32>] %x.coerce)
func_v2(struct v2 x)145*67e74705SXin Li struct v2 func_v2(struct v2 x) { return x; }
146*67e74705SXin Li 
147*67e74705SXin Li // CHECK: define [3 x <4 x i32>] @func_v3([3 x <4 x i32>] %x.coerce)
func_v3(struct v3 x)148*67e74705SXin Li struct v3 func_v3(struct v3 x) { return x; }
149*67e74705SXin Li 
150*67e74705SXin Li // CHECK: define [4 x <4 x i32>] @func_v4([4 x <4 x i32>] %x.coerce)
func_v4(struct v4 x)151*67e74705SXin Li struct v4 func_v4(struct v4 x) { return x; }
152*67e74705SXin Li 
153*67e74705SXin Li // CHECK: define [5 x <4 x i32>] @func_v5([5 x <4 x i32>] %x.coerce)
func_v5(struct v5 x)154*67e74705SXin Li struct v5 func_v5(struct v5 x) { return x; }
155*67e74705SXin Li 
156*67e74705SXin Li // CHECK: define [6 x <4 x i32>] @func_v6([6 x <4 x i32>] %x.coerce)
func_v6(struct v6 x)157*67e74705SXin Li struct v6 func_v6(struct v6 x) { return x; }
158*67e74705SXin Li 
159*67e74705SXin Li // CHECK: define [7 x <4 x i32>] @func_v7([7 x <4 x i32>] %x.coerce)
func_v7(struct v7 x)160*67e74705SXin Li struct v7 func_v7(struct v7 x) { return x; }
161*67e74705SXin Li 
162*67e74705SXin Li // CHECK: define [8 x <4 x i32>] @func_v8([8 x <4 x i32>] %x.coerce)
func_v8(struct v8 x)163*67e74705SXin Li struct v8 func_v8(struct v8 x) { return x; }
164*67e74705SXin Li 
165*67e74705SXin Li // CHECK: define void @func_v9(%struct.v9* noalias sret %agg.result, %struct.v9* byval align 16 %x)
func_v9(struct v9 x)166*67e74705SXin Li struct v9 func_v9(struct v9 x) { return x; }
167*67e74705SXin Li 
168*67e74705SXin Li // CHECK: define [2 x <4 x i32>] @func_vab([2 x <4 x i32>] %x.coerce)
func_vab(struct vab x)169*67e74705SXin Li struct vab func_vab(struct vab x) { return x; }
170*67e74705SXin Li 
171*67e74705SXin Li // CHECK: define [3 x <4 x i32>] @func_vabc([3 x <4 x i32>] %x.coerce)
func_vabc(struct vabc x)172*67e74705SXin Li struct vabc func_vabc(struct vabc x) { return x; }
173*67e74705SXin Li 
174*67e74705SXin Li // CHECK-LABEL: @call_v1
175*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load <4 x i32>, <4 x i32>* getelementptr inbounds (%struct.v1, %struct.v1* @global_v1, i32 0, i32 0, i32 0), align 1
176*67e74705SXin Li // CHECK: call [1 x <4 x i32>] @func_v1(<4 x i32> inreg %[[TMP]])
177*67e74705SXin Li struct v1 global_v1;
call_v1(void)178*67e74705SXin Li void call_v1(void) { global_v1 = func_v1(global_v1); }
179*67e74705SXin Li 
180*67e74705SXin Li // CHECK-LABEL: @call_v2
181*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [2 x <4 x i32>], [2 x <4 x i32>]* getelementptr inbounds (%struct.v2, %struct.v2* @global_v2, i32 0, i32 0), align 1
182*67e74705SXin Li // CHECK: call [2 x <4 x i32>] @func_v2([2 x <4 x i32>] %[[TMP]])
183*67e74705SXin Li struct v2 global_v2;
call_v2(void)184*67e74705SXin Li void call_v2(void) { global_v2 = func_v2(global_v2); }
185*67e74705SXin Li 
186*67e74705SXin Li // CHECK-LABEL: @call_v3
187*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [3 x <4 x i32>], [3 x <4 x i32>]* getelementptr inbounds (%struct.v3, %struct.v3* @global_v3, i32 0, i32 0), align 1
188*67e74705SXin Li // CHECK: call [3 x <4 x i32>] @func_v3([3 x <4 x i32>] %[[TMP]])
189*67e74705SXin Li struct v3 global_v3;
call_v3(void)190*67e74705SXin Li void call_v3(void) { global_v3 = func_v3(global_v3); }
191*67e74705SXin Li 
192*67e74705SXin Li // CHECK-LABEL: @call_v4
193*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [4 x <4 x i32>], [4 x <4 x i32>]* getelementptr inbounds (%struct.v4, %struct.v4* @global_v4, i32 0, i32 0), align 1
194*67e74705SXin Li // CHECK: call [4 x <4 x i32>] @func_v4([4 x <4 x i32>] %[[TMP]])
195*67e74705SXin Li struct v4 global_v4;
call_v4(void)196*67e74705SXin Li void call_v4(void) { global_v4 = func_v4(global_v4); }
197*67e74705SXin Li 
198*67e74705SXin Li // CHECK-LABEL: @call_v5
199*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [5 x <4 x i32>], [5 x <4 x i32>]* getelementptr inbounds (%struct.v5, %struct.v5* @global_v5, i32 0, i32 0), align 1
200*67e74705SXin Li // CHECK: call [5 x <4 x i32>] @func_v5([5 x <4 x i32>] %[[TMP]])
201*67e74705SXin Li struct v5 global_v5;
call_v5(void)202*67e74705SXin Li void call_v5(void) { global_v5 = func_v5(global_v5); }
203*67e74705SXin Li 
204*67e74705SXin Li // CHECK-LABEL: @call_v6
205*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [6 x <4 x i32>], [6 x <4 x i32>]* getelementptr inbounds (%struct.v6, %struct.v6* @global_v6, i32 0, i32 0), align 1
206*67e74705SXin Li // CHECK: call [6 x <4 x i32>] @func_v6([6 x <4 x i32>] %[[TMP]])
207*67e74705SXin Li struct v6 global_v6;
call_v6(void)208*67e74705SXin Li void call_v6(void) { global_v6 = func_v6(global_v6); }
209*67e74705SXin Li 
210*67e74705SXin Li // CHECK-LABEL: @call_v7
211*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [7 x <4 x i32>], [7 x <4 x i32>]* getelementptr inbounds (%struct.v7, %struct.v7* @global_v7, i32 0, i32 0), align 1
212*67e74705SXin Li // CHECK: call [7 x <4 x i32>] @func_v7([7 x <4 x i32>] %[[TMP]])
213*67e74705SXin Li struct v7 global_v7;
call_v7(void)214*67e74705SXin Li void call_v7(void) { global_v7 = func_v7(global_v7); }
215*67e74705SXin Li 
216*67e74705SXin Li // CHECK-LABEL: @call_v8
217*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [8 x <4 x i32>], [8 x <4 x i32>]* getelementptr inbounds (%struct.v8, %struct.v8* @global_v8, i32 0, i32 0), align 1
218*67e74705SXin Li // CHECK: call [8 x <4 x i32>] @func_v8([8 x <4 x i32>] %[[TMP]])
219*67e74705SXin Li struct v8 global_v8;
call_v8(void)220*67e74705SXin Li void call_v8(void) { global_v8 = func_v8(global_v8); }
221*67e74705SXin Li 
222*67e74705SXin Li // CHECK-LABEL: @call_v9
223*67e74705SXin Li // CHECK: call void @func_v9(%struct.v9* sret %{{[^ ]+}}, %struct.v9* byval align 16 @global_v9)
224*67e74705SXin Li struct v9 global_v9;
call_v9(void)225*67e74705SXin Li void call_v9(void) { global_v9 = func_v9(global_v9); }
226*67e74705SXin Li 
227*67e74705SXin Li // CHECK-LABEL: @call_vab
228*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [2 x <4 x i32>], [2 x <4 x i32>]* bitcast (%struct.vab* @global_vab to [2 x <4 x i32>]*)
229*67e74705SXin Li // CHECK: call [2 x <4 x i32>] @func_vab([2 x <4 x i32>] %[[TMP]])
230*67e74705SXin Li struct vab global_vab;
call_vab(void)231*67e74705SXin Li void call_vab(void) { global_vab = func_vab(global_vab); }
232*67e74705SXin Li 
233*67e74705SXin Li // CHECK-LABEL: @call_vabc
234*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [3 x <4 x i32>], [3 x <4 x i32>]* bitcast (%struct.vabc* @global_vabc to [3 x <4 x i32>]*)
235*67e74705SXin Li // CHECK: call [3 x <4 x i32>] @func_vabc([3 x <4 x i32>] %[[TMP]])
236*67e74705SXin Li struct vabc global_vabc;
call_vabc(void)237*67e74705SXin Li void call_vabc(void) { global_vabc = func_vabc(global_vabc); }
238*67e74705SXin Li 
239*67e74705SXin Li 
240*67e74705SXin Li // As clang extension, non-power-of-two vectors may also be part of
241*67e74705SXin Li // homogeneous aggregates.
242*67e74705SXin Li 
243*67e74705SXin Li typedef float float3 __attribute__((vector_size (12)));
244*67e74705SXin Li 
245*67e74705SXin Li struct v3f1 { float3 v[1]; };
246*67e74705SXin Li struct v3f2 { float3 v[2]; };
247*67e74705SXin Li struct v3f3 { float3 v[3]; };
248*67e74705SXin Li struct v3f4 { float3 v[4]; };
249*67e74705SXin Li struct v3f5 { float3 v[5]; };
250*67e74705SXin Li struct v3f6 { float3 v[6]; };
251*67e74705SXin Li struct v3f7 { float3 v[7]; };
252*67e74705SXin Li struct v3f8 { float3 v[8]; };
253*67e74705SXin Li struct v3f9 { float3 v[9]; };
254*67e74705SXin Li 
255*67e74705SXin Li struct v3fab { float3 a; float3 b; };
256*67e74705SXin Li struct v3fabc { float3 a; float3 b; float3 c; };
257*67e74705SXin Li 
258*67e74705SXin Li // CHECK: define [1 x <4 x float>] @func_v3f1(<3 x float> inreg %x.coerce)
func_v3f1(struct v3f1 x)259*67e74705SXin Li struct v3f1 func_v3f1(struct v3f1 x) { return x; }
260*67e74705SXin Li 
261*67e74705SXin Li // CHECK: define [2 x <4 x float>] @func_v3f2([2 x <4 x float>] %x.coerce)
func_v3f2(struct v3f2 x)262*67e74705SXin Li struct v3f2 func_v3f2(struct v3f2 x) { return x; }
263*67e74705SXin Li 
264*67e74705SXin Li // CHECK: define [3 x <4 x float>] @func_v3f3([3 x <4 x float>] %x.coerce)
func_v3f3(struct v3f3 x)265*67e74705SXin Li struct v3f3 func_v3f3(struct v3f3 x) { return x; }
266*67e74705SXin Li 
267*67e74705SXin Li // CHECK: define [4 x <4 x float>] @func_v3f4([4 x <4 x float>] %x.coerce)
func_v3f4(struct v3f4 x)268*67e74705SXin Li struct v3f4 func_v3f4(struct v3f4 x) { return x; }
269*67e74705SXin Li 
270*67e74705SXin Li // CHECK: define [5 x <4 x float>] @func_v3f5([5 x <4 x float>] %x.coerce)
func_v3f5(struct v3f5 x)271*67e74705SXin Li struct v3f5 func_v3f5(struct v3f5 x) { return x; }
272*67e74705SXin Li 
273*67e74705SXin Li // CHECK: define [6 x <4 x float>] @func_v3f6([6 x <4 x float>] %x.coerce)
func_v3f6(struct v3f6 x)274*67e74705SXin Li struct v3f6 func_v3f6(struct v3f6 x) { return x; }
275*67e74705SXin Li 
276*67e74705SXin Li // CHECK: define [7 x <4 x float>] @func_v3f7([7 x <4 x float>] %x.coerce)
func_v3f7(struct v3f7 x)277*67e74705SXin Li struct v3f7 func_v3f7(struct v3f7 x) { return x; }
278*67e74705SXin Li 
279*67e74705SXin Li // CHECK: define [8 x <4 x float>] @func_v3f8([8 x <4 x float>] %x.coerce)
func_v3f8(struct v3f8 x)280*67e74705SXin Li struct v3f8 func_v3f8(struct v3f8 x) { return x; }
281*67e74705SXin Li 
282*67e74705SXin Li // CHECK: define void @func_v3f9(%struct.v3f9* noalias sret %agg.result, %struct.v3f9* byval align 16 %x)
func_v3f9(struct v3f9 x)283*67e74705SXin Li struct v3f9 func_v3f9(struct v3f9 x) { return x; }
284*67e74705SXin Li 
285*67e74705SXin Li // CHECK: define [2 x <4 x float>] @func_v3fab([2 x <4 x float>] %x.coerce)
func_v3fab(struct v3fab x)286*67e74705SXin Li struct v3fab func_v3fab(struct v3fab x) { return x; }
287*67e74705SXin Li 
288*67e74705SXin Li // CHECK: define [3 x <4 x float>] @func_v3fabc([3 x <4 x float>] %x.coerce)
func_v3fabc(struct v3fabc x)289*67e74705SXin Li struct v3fabc func_v3fabc(struct v3fabc x) { return x; }
290*67e74705SXin Li 
291*67e74705SXin Li // CHECK-LABEL: @call_v3f1
292*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load <3 x float>, <3 x float>* getelementptr inbounds (%struct.v3f1, %struct.v3f1* @global_v3f1, i32 0, i32 0, i32 0), align 1
293*67e74705SXin Li // CHECK: call [1 x <4 x float>] @func_v3f1(<3 x float> inreg %[[TMP]])
294*67e74705SXin Li struct v3f1 global_v3f1;
call_v3f1(void)295*67e74705SXin Li void call_v3f1(void) { global_v3f1 = func_v3f1(global_v3f1); }
296*67e74705SXin Li 
297*67e74705SXin Li // CHECK-LABEL: @call_v3f2
298*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [2 x <4 x float>], [2 x <4 x float>]* bitcast (%struct.v3f2* @global_v3f2 to [2 x <4 x float>]*), align 16
299*67e74705SXin Li // CHECK: call [2 x <4 x float>] @func_v3f2([2 x <4 x float>] %[[TMP]])
300*67e74705SXin Li struct v3f2 global_v3f2;
call_v3f2(void)301*67e74705SXin Li void call_v3f2(void) { global_v3f2 = func_v3f2(global_v3f2); }
302*67e74705SXin Li 
303*67e74705SXin Li // CHECK-LABEL: @call_v3f3
304*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [3 x <4 x float>], [3 x <4 x float>]* bitcast (%struct.v3f3* @global_v3f3 to [3 x <4 x float>]*), align 16
305*67e74705SXin Li // CHECK: call [3 x <4 x float>] @func_v3f3([3 x <4 x float>] %[[TMP]])
306*67e74705SXin Li struct v3f3 global_v3f3;
call_v3f3(void)307*67e74705SXin Li void call_v3f3(void) { global_v3f3 = func_v3f3(global_v3f3); }
308*67e74705SXin Li 
309*67e74705SXin Li // CHECK-LABEL: @call_v3f4
310*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [4 x <4 x float>], [4 x <4 x float>]* bitcast (%struct.v3f4* @global_v3f4 to [4 x <4 x float>]*), align 16
311*67e74705SXin Li // CHECK: call [4 x <4 x float>] @func_v3f4([4 x <4 x float>] %[[TMP]])
312*67e74705SXin Li struct v3f4 global_v3f4;
call_v3f4(void)313*67e74705SXin Li void call_v3f4(void) { global_v3f4 = func_v3f4(global_v3f4); }
314*67e74705SXin Li 
315*67e74705SXin Li // CHECK-LABEL: @call_v3f5
316*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [5 x <4 x float>], [5 x <4 x float>]* bitcast (%struct.v3f5* @global_v3f5 to [5 x <4 x float>]*), align 16
317*67e74705SXin Li // CHECK: call [5 x <4 x float>] @func_v3f5([5 x <4 x float>] %[[TMP]])
318*67e74705SXin Li struct v3f5 global_v3f5;
call_v3f5(void)319*67e74705SXin Li void call_v3f5(void) { global_v3f5 = func_v3f5(global_v3f5); }
320*67e74705SXin Li 
321*67e74705SXin Li // CHECK-LABEL: @call_v3f6
322*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [6 x <4 x float>], [6 x <4 x float>]* bitcast (%struct.v3f6* @global_v3f6 to [6 x <4 x float>]*), align 16
323*67e74705SXin Li // CHECK: call [6 x <4 x float>] @func_v3f6([6 x <4 x float>] %[[TMP]])
324*67e74705SXin Li struct v3f6 global_v3f6;
call_v3f6(void)325*67e74705SXin Li void call_v3f6(void) { global_v3f6 = func_v3f6(global_v3f6); }
326*67e74705SXin Li 
327*67e74705SXin Li // CHECK-LABEL: @call_v3f7
328*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [7 x <4 x float>], [7 x <4 x float>]* bitcast (%struct.v3f7* @global_v3f7 to [7 x <4 x float>]*), align 16
329*67e74705SXin Li // CHECK: call [7 x <4 x float>] @func_v3f7([7 x <4 x float>] %[[TMP]])
330*67e74705SXin Li struct v3f7 global_v3f7;
call_v3f7(void)331*67e74705SXin Li void call_v3f7(void) { global_v3f7 = func_v3f7(global_v3f7); }
332*67e74705SXin Li 
333*67e74705SXin Li // CHECK-LABEL: @call_v3f8
334*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [8 x <4 x float>], [8 x <4 x float>]* bitcast (%struct.v3f8* @global_v3f8 to [8 x <4 x float>]*), align 16
335*67e74705SXin Li // CHECK: call [8 x <4 x float>] @func_v3f8([8 x <4 x float>] %[[TMP]])
336*67e74705SXin Li struct v3f8 global_v3f8;
call_v3f8(void)337*67e74705SXin Li void call_v3f8(void) { global_v3f8 = func_v3f8(global_v3f8); }
338*67e74705SXin Li 
339*67e74705SXin Li // CHECK-LABEL: @call_v3f9
340*67e74705SXin Li // CHECK: call void @func_v3f9(%struct.v3f9* sret %{{[^ ]+}}, %struct.v3f9* byval align 16 @global_v3f9)
341*67e74705SXin Li struct v3f9 global_v3f9;
call_v3f9(void)342*67e74705SXin Li void call_v3f9(void) { global_v3f9 = func_v3f9(global_v3f9); }
343*67e74705SXin Li 
344*67e74705SXin Li // CHECK-LABEL: @call_v3fab
345*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [2 x <4 x float>], [2 x <4 x float>]* bitcast (%struct.v3fab* @global_v3fab to [2 x <4 x float>]*), align 16
346*67e74705SXin Li // CHECK: call [2 x <4 x float>] @func_v3fab([2 x <4 x float>] %[[TMP]])
347*67e74705SXin Li struct v3fab global_v3fab;
call_v3fab(void)348*67e74705SXin Li void call_v3fab(void) { global_v3fab = func_v3fab(global_v3fab); }
349*67e74705SXin Li 
350*67e74705SXin Li // CHECK-LABEL: @call_v3fabc
351*67e74705SXin Li // CHECK: %[[TMP:[^ ]+]] = load [3 x <4 x float>], [3 x <4 x float>]* bitcast (%struct.v3fabc* @global_v3fabc to [3 x <4 x float>]*), align 16
352*67e74705SXin Li // CHECK: call [3 x <4 x float>] @func_v3fabc([3 x <4 x float>] %[[TMP]])
353*67e74705SXin Li struct v3fabc global_v3fabc;
call_v3fabc(void)354*67e74705SXin Li void call_v3fabc(void) { global_v3fabc = func_v3fabc(global_v3fabc); }
355*67e74705SXin Li 
356*67e74705SXin Li 
357*67e74705SXin Li // Test returning small aggregates.
358*67e74705SXin Li 
359*67e74705SXin Li struct s1 { char c[1]; };
360*67e74705SXin Li struct s2 { char c[2]; };
361*67e74705SXin Li struct s3 { char c[3]; };
362*67e74705SXin Li struct s4 { char c[4]; };
363*67e74705SXin Li struct s5 { char c[5]; };
364*67e74705SXin Li struct s6 { char c[6]; };
365*67e74705SXin Li struct s7 { char c[7]; };
366*67e74705SXin Li struct s8 { char c[8]; };
367*67e74705SXin Li struct s9 { char c[9]; };
368*67e74705SXin Li struct s16 { char c[16]; };
369*67e74705SXin Li struct s17 { char c[17]; };
370*67e74705SXin Li 
371*67e74705SXin Li // CHECK: define i8 @ret_s1()
ret_s1()372*67e74705SXin Li struct s1 ret_s1() {
373*67e74705SXin Li   return (struct s1) { 17 };
374*67e74705SXin Li }
375*67e74705SXin Li 
376*67e74705SXin Li // CHECK: define i16 @ret_s2()
ret_s2()377*67e74705SXin Li struct s2 ret_s2() {
378*67e74705SXin Li   return (struct s2) { 17, 18 };
379*67e74705SXin Li }
380*67e74705SXin Li 
381*67e74705SXin Li // CHECK: define i24 @ret_s3()
ret_s3()382*67e74705SXin Li struct s3 ret_s3() {
383*67e74705SXin Li   return (struct s3) { 17, 18, 19 };
384*67e74705SXin Li }
385*67e74705SXin Li 
386*67e74705SXin Li // CHECK: define i32 @ret_s4()
ret_s4()387*67e74705SXin Li struct s4 ret_s4() {
388*67e74705SXin Li   return (struct s4) { 17, 18, 19, 20 };
389*67e74705SXin Li }
390*67e74705SXin Li 
391*67e74705SXin Li // CHECK: define i40 @ret_s5()
ret_s5()392*67e74705SXin Li struct s5 ret_s5() {
393*67e74705SXin Li   return (struct s5) { 17, 18, 19, 20, 21 };
394*67e74705SXin Li }
395*67e74705SXin Li 
396*67e74705SXin Li // CHECK: define i48 @ret_s6()
ret_s6()397*67e74705SXin Li struct s6 ret_s6() {
398*67e74705SXin Li   return (struct s6) { 17, 18, 19, 20, 21, 22 };
399*67e74705SXin Li }
400*67e74705SXin Li 
401*67e74705SXin Li // CHECK: define i56 @ret_s7()
ret_s7()402*67e74705SXin Li struct s7 ret_s7() {
403*67e74705SXin Li   return (struct s7) { 17, 18, 19, 20, 21, 22, 23 };
404*67e74705SXin Li }
405*67e74705SXin Li 
406*67e74705SXin Li // CHECK: define i64 @ret_s8()
ret_s8()407*67e74705SXin Li struct s8 ret_s8() {
408*67e74705SXin Li   return (struct s8) { 17, 18, 19, 20, 21, 22, 23, 24 };
409*67e74705SXin Li }
410*67e74705SXin Li 
411*67e74705SXin Li // CHECK: define { i64, i64 } @ret_s9()
ret_s9()412*67e74705SXin Li struct s9 ret_s9() {
413*67e74705SXin Li   return (struct s9) { 17, 18, 19, 20, 21, 22, 23, 24, 25 };
414*67e74705SXin Li }
415*67e74705SXin Li 
416*67e74705SXin Li // CHECK: define { i64, i64 } @ret_s16()
ret_s16()417*67e74705SXin Li struct s16 ret_s16() {
418*67e74705SXin Li   return (struct s16) { 17, 18, 19, 20, 21, 22, 23, 24,
419*67e74705SXin Li                         25, 26, 27, 28, 29, 30, 31, 32 };
420*67e74705SXin Li }
421*67e74705SXin Li 
422*67e74705SXin Li // CHECK: define void @ret_s17(%struct.s17*
ret_s17()423*67e74705SXin Li struct s17 ret_s17() {
424*67e74705SXin Li   return (struct s17) { 17, 18, 19, 20, 21, 22, 23, 24,
425*67e74705SXin Li                         25, 26, 27, 28, 29, 30, 31, 32, 33 };
426*67e74705SXin Li }
427*67e74705SXin Li 
428