1*67e74705SXin Li // RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
2*67e74705SXin Li
3*67e74705SXin Li #include <stdarg.h>
4*67e74705SXin Li
5*67e74705SXin Li struct test1 { int x; int y; };
6*67e74705SXin Li struct test2 { int x; int y; } __attribute__((aligned (16)));
7*67e74705SXin Li struct test3 { int x; int y; } __attribute__((aligned (32)));
8*67e74705SXin Li struct test4 { int x; int y; int z; };
9*67e74705SXin Li struct test5 { int x[17]; };
10*67e74705SXin Li struct test6 { int x[17]; } __attribute__((aligned (16)));
11*67e74705SXin Li struct test7 { int x[17]; } __attribute__((aligned (32)));
12*67e74705SXin Li
13*67e74705SXin Li // CHECK: define void @test1(i32 signext %x, i64 %y.coerce)
test1(int x,struct test1 y)14*67e74705SXin Li void test1 (int x, struct test1 y)
15*67e74705SXin Li {
16*67e74705SXin Li }
17*67e74705SXin Li
18*67e74705SXin Li // CHECK: define void @test2(i32 signext %x, [1 x i128] %y.coerce)
test2(int x,struct test2 y)19*67e74705SXin Li void test2 (int x, struct test2 y)
20*67e74705SXin Li {
21*67e74705SXin Li }
22*67e74705SXin Li
23*67e74705SXin Li // CHECK: define void @test3(i32 signext %x, [2 x i128] %y.coerce)
test3(int x,struct test3 y)24*67e74705SXin Li void test3 (int x, struct test3 y)
25*67e74705SXin Li {
26*67e74705SXin Li }
27*67e74705SXin Li
28*67e74705SXin Li // CHECK: define void @test4(i32 signext %x, [2 x i64] %y.coerce)
test4(int x,struct test4 y)29*67e74705SXin Li void test4 (int x, struct test4 y)
30*67e74705SXin Li {
31*67e74705SXin Li }
32*67e74705SXin Li
33*67e74705SXin Li // CHECK: define void @test5(i32 signext %x, %struct.test5* byval align 8 %y)
test5(int x,struct test5 y)34*67e74705SXin Li void test5 (int x, struct test5 y)
35*67e74705SXin Li {
36*67e74705SXin Li }
37*67e74705SXin Li
38*67e74705SXin Li // CHECK: define void @test6(i32 signext %x, %struct.test6* byval align 16 %y)
test6(int x,struct test6 y)39*67e74705SXin Li void test6 (int x, struct test6 y)
40*67e74705SXin Li {
41*67e74705SXin Li }
42*67e74705SXin Li
43*67e74705SXin Li // This case requires run-time realignment of the incoming struct
44*67e74705SXin Li // CHECK-LABEL: define void @test7(i32 signext %x, %struct.test7* byval align 16)
45*67e74705SXin Li // CHECK: %y = alloca %struct.test7, align 32
46*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
test7(int x,struct test7 y)47*67e74705SXin Li void test7 (int x, struct test7 y)
48*67e74705SXin Li {
49*67e74705SXin Li }
50*67e74705SXin Li
51*67e74705SXin Li // CHECK-LABEL: define void @test1va(%struct.test1* noalias sret %agg.result, i32 signext %x, ...)
52*67e74705SXin Li // CHECK: %y = alloca %struct.test1, align 4
53*67e74705SXin Li // CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
54*67e74705SXin Li // CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 8
55*67e74705SXin Li // CHECK: store i8* %[[NEXT]], i8** %ap
56*67e74705SXin Li // CHECK: [[T0:%.*]] = bitcast i8* %[[CUR]] to %struct.test1*
57*67e74705SXin Li // CHECK: [[DEST:%.*]] = bitcast %struct.test1* %y to i8*
58*67e74705SXin Li // CHECK: [[SRC:%.*]] = bitcast %struct.test1* [[T0]] to i8*
59*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 8, i32 4, i1 false)
test1va(int x,...)60*67e74705SXin Li struct test1 test1va (int x, ...)
61*67e74705SXin Li {
62*67e74705SXin Li struct test1 y;
63*67e74705SXin Li va_list ap;
64*67e74705SXin Li va_start(ap, x);
65*67e74705SXin Li y = va_arg (ap, struct test1);
66*67e74705SXin Li va_end(ap);
67*67e74705SXin Li return y;
68*67e74705SXin Li }
69*67e74705SXin Li
70*67e74705SXin Li // CHECK-LABEL: define void @test2va(%struct.test2* noalias sret %agg.result, i32 signext %x, ...)
71*67e74705SXin Li // CHECK: %y = alloca %struct.test2, align 16
72*67e74705SXin Li // CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
73*67e74705SXin Li // CHECK: %[[TMP0:[^ ]+]] = ptrtoint i8* %[[CUR]] to i64
74*67e74705SXin Li // CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
75*67e74705SXin Li // CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
76*67e74705SXin Li // CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to i8*
77*67e74705SXin Li // CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[ALIGN]], i64 16
78*67e74705SXin Li // CHECK: store i8* %[[NEXT]], i8** %ap
79*67e74705SXin Li // CHECK: [[T0:%.*]] = bitcast i8* %[[ALIGN]] to %struct.test2*
80*67e74705SXin Li // CHECK: [[DEST:%.*]] = bitcast %struct.test2* %y to i8*
81*67e74705SXin Li // CHECK: [[SRC:%.*]] = bitcast %struct.test2* [[T0]] to i8*
82*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 16, i32 16, i1 false)
test2va(int x,...)83*67e74705SXin Li struct test2 test2va (int x, ...)
84*67e74705SXin Li {
85*67e74705SXin Li struct test2 y;
86*67e74705SXin Li va_list ap;
87*67e74705SXin Li va_start(ap, x);
88*67e74705SXin Li y = va_arg (ap, struct test2);
89*67e74705SXin Li va_end(ap);
90*67e74705SXin Li return y;
91*67e74705SXin Li }
92*67e74705SXin Li
93*67e74705SXin Li // CHECK-LABEL: define void @test3va(%struct.test3* noalias sret %agg.result, i32 signext %x, ...)
94*67e74705SXin Li // CHECK: %y = alloca %struct.test3, align 32
95*67e74705SXin Li // CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
96*67e74705SXin Li // CHECK: %[[TMP0:[^ ]+]] = ptrtoint i8* %[[CUR]] to i64
97*67e74705SXin Li // CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
98*67e74705SXin Li // CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
99*67e74705SXin Li // CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to i8*
100*67e74705SXin Li // CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[ALIGN]], i64 32
101*67e74705SXin Li // CHECK: store i8* %[[NEXT]], i8** %ap
102*67e74705SXin Li // CHECK: [[T0:%.*]] = bitcast i8* %[[ALIGN]] to %struct.test3*
103*67e74705SXin Li // CHECK: [[DEST:%.*]] = bitcast %struct.test3* %y to i8*
104*67e74705SXin Li // CHECK: [[SRC:%.*]] = bitcast %struct.test3* [[T0]] to i8*
105*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 32, i32 16, i1 false)
test3va(int x,...)106*67e74705SXin Li struct test3 test3va (int x, ...)
107*67e74705SXin Li {
108*67e74705SXin Li struct test3 y;
109*67e74705SXin Li va_list ap;
110*67e74705SXin Li va_start(ap, x);
111*67e74705SXin Li y = va_arg (ap, struct test3);
112*67e74705SXin Li va_end(ap);
113*67e74705SXin Li return y;
114*67e74705SXin Li }
115*67e74705SXin Li
116*67e74705SXin Li // CHECK-LABEL: define void @test4va(%struct.test4* noalias sret %agg.result, i32 signext %x, ...)
117*67e74705SXin Li // CHECK: %y = alloca %struct.test4, align 4
118*67e74705SXin Li // CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
119*67e74705SXin Li // CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 16
120*67e74705SXin Li // CHECK: store i8* %[[NEXT]], i8** %ap
121*67e74705SXin Li // CHECK: [[T0:%.*]] = bitcast i8* %[[CUR]] to %struct.test4*
122*67e74705SXin Li // CHECK: [[DEST:%.*]] = bitcast %struct.test4* %y to i8*
123*67e74705SXin Li // CHECK: [[SRC:%.*]] = bitcast %struct.test4* [[T0]] to i8*
124*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 12, i32 4, i1 false)
test4va(int x,...)125*67e74705SXin Li struct test4 test4va (int x, ...)
126*67e74705SXin Li {
127*67e74705SXin Li struct test4 y;
128*67e74705SXin Li va_list ap;
129*67e74705SXin Li va_start(ap, x);
130*67e74705SXin Li y = va_arg (ap, struct test4);
131*67e74705SXin Li va_end(ap);
132*67e74705SXin Li return y;
133*67e74705SXin Li }
134*67e74705SXin Li
135*67e74705SXin Li // CHECK-LABEL: define void @testva_longdouble(%struct.test_longdouble* noalias sret %agg.result, i32 signext %x, ...)
136*67e74705SXin Li // CHECK: %y = alloca %struct.test_longdouble, align 16
137*67e74705SXin Li // CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
138*67e74705SXin Li // CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 16
139*67e74705SXin Li // CHECK: store i8* %[[NEXT]], i8** %ap
140*67e74705SXin Li // CHECK: [[T0:%.*]] = bitcast i8* %[[CUR]] to %struct.test_longdouble*
141*67e74705SXin Li // CHECK: [[DEST:%.*]] = bitcast %struct.test_longdouble* %y to i8*
142*67e74705SXin Li // CHECK: [[SRC:%.*]] = bitcast %struct.test_longdouble* [[T0]] to i8*
143*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 16, i32 8, i1 false)
144*67e74705SXin Li struct test_longdouble { long double x; };
testva_longdouble(int x,...)145*67e74705SXin Li struct test_longdouble testva_longdouble (int x, ...)
146*67e74705SXin Li {
147*67e74705SXin Li struct test_longdouble y;
148*67e74705SXin Li va_list ap;
149*67e74705SXin Li va_start(ap, x);
150*67e74705SXin Li y = va_arg (ap, struct test_longdouble);
151*67e74705SXin Li va_end(ap);
152*67e74705SXin Li return y;
153*67e74705SXin Li }
154*67e74705SXin Li
155*67e74705SXin Li // CHECK-LABEL: define void @testva_vector(%struct.test_vector* noalias sret %agg.result, i32 signext %x, ...)
156*67e74705SXin Li // CHECK: %y = alloca %struct.test_vector, align 16
157*67e74705SXin Li // CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
158*67e74705SXin Li // CHECK: %[[TMP0:[^ ]+]] = ptrtoint i8* %[[CUR]] to i64
159*67e74705SXin Li // CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
160*67e74705SXin Li // CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
161*67e74705SXin Li // CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to i8*
162*67e74705SXin Li // CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[ALIGN]], i64 16
163*67e74705SXin Li // CHECK: store i8* %[[NEXT]], i8** %ap
164*67e74705SXin Li // CHECK: [[T0:%.*]] = bitcast i8* %[[ALIGN]] to %struct.test_vector*
165*67e74705SXin Li // CHECK: [[DEST:%.*]] = bitcast %struct.test_vector* %y to i8*
166*67e74705SXin Li // CHECK: [[SRC:%.*]] = bitcast %struct.test_vector* [[T0]] to i8*
167*67e74705SXin Li // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 16, i32 16, i1 false)
168*67e74705SXin Li struct test_vector { vector int x; };
testva_vector(int x,...)169*67e74705SXin Li struct test_vector testva_vector (int x, ...)
170*67e74705SXin Li {
171*67e74705SXin Li struct test_vector y;
172*67e74705SXin Li va_list ap;
173*67e74705SXin Li va_start(ap, x);
174*67e74705SXin Li y = va_arg (ap, struct test_vector);
175*67e74705SXin Li va_end(ap);
176*67e74705SXin Li return y;
177*67e74705SXin Li }
178*67e74705SXin Li
179