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