1*67e74705SXin Li // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
2*67e74705SXin Li
3*67e74705SXin Li typedef __attribute__(( ext_vector_type(4) )) float float4;
4*67e74705SXin Li typedef __attribute__(( ext_vector_type(2) )) float float2;
5*67e74705SXin Li typedef __attribute__(( ext_vector_type(4) )) int int4;
6*67e74705SXin Li typedef __attribute__(( ext_vector_type(4) )) unsigned int uint4;
7*67e74705SXin Li
8*67e74705SXin Li // CHECK: @foo = global <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>
9*67e74705SXin Li float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 };
10*67e74705SXin Li
11*67e74705SXin Li // CHECK: @bar = constant <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 0x7FF0000000000000>
12*67e74705SXin Li const float4 bar = (float4){ 1.0, 2.0, 3.0, __builtin_inff() };
13*67e74705SXin Li
14*67e74705SXin Li // CHECK: @test1
15*67e74705SXin Li // CHECK: fadd <4 x float>
test1(float4 V)16*67e74705SXin Li float4 test1(float4 V) {
17*67e74705SXin Li return V.wzyx+V;
18*67e74705SXin Li }
19*67e74705SXin Li
20*67e74705SXin Li float2 vec2, vec2_2;
21*67e74705SXin Li float4 vec4, vec4_2;
22*67e74705SXin Li float f;
23*67e74705SXin Li
24*67e74705SXin Li // CHECK: @test2
25*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 0, i32 1>
26*67e74705SXin Li // CHECK: extractelement
27*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 1, i32 1, i32 1, i32 1>
28*67e74705SXin Li // CHECK: insertelement
29*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 1, i32 0>
test2()30*67e74705SXin Li void test2() {
31*67e74705SXin Li vec2 = vec4.xy; // shorten
32*67e74705SXin Li f = vec2.x; // extract elt
33*67e74705SXin Li vec4 = vec4.yyyy; // splat
34*67e74705SXin Li
35*67e74705SXin Li vec2.x = f; // insert one.
36*67e74705SXin Li vec2.yx = vec2; // reverse
37*67e74705SXin Li }
38*67e74705SXin Li
39*67e74705SXin Li // CHECK: @test3
40*67e74705SXin Li // CHECK: store <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>
test3(float4 * out)41*67e74705SXin Li void test3(float4 *out) {
42*67e74705SXin Li *out = ((float4) {1.0f, 2.0f, 3.0f, 4.0f });
43*67e74705SXin Li }
44*67e74705SXin Li
45*67e74705SXin Li // CHECK: @test4
46*67e74705SXin Li // CHECK: store <4 x float>
47*67e74705SXin Li // CHECK: store <4 x float>
test4(float4 * out)48*67e74705SXin Li void test4(float4 *out) {
49*67e74705SXin Li float a = 1.0f;
50*67e74705SXin Li float b = 2.0f;
51*67e74705SXin Li float c = 3.0f;
52*67e74705SXin Li float d = 4.0f;
53*67e74705SXin Li *out = ((float4) {a,b,c,d});
54*67e74705SXin Li }
55*67e74705SXin Li
56*67e74705SXin Li // CHECK: @test5
57*67e74705SXin Li // CHECK: shufflevector {{.*}} <4 x i32> zeroinitializer
58*67e74705SXin Li // CHECK: fmul <4 x float>
59*67e74705SXin Li // CHECK: fmul <4 x float>
60*67e74705SXin Li // CHECK: shufflevector {{.*}} <4 x i32> zeroinitializer
61*67e74705SXin Li // CHECK: fmul <4 x float>
test5(float4 * out)62*67e74705SXin Li void test5(float4 *out) {
63*67e74705SXin Li float a;
64*67e74705SXin Li float4 b;
65*67e74705SXin Li
66*67e74705SXin Li a = 1.0f;
67*67e74705SXin Li b = a;
68*67e74705SXin Li b = b * 5.0f;
69*67e74705SXin Li b = 5.0f * b;
70*67e74705SXin Li b *= a;
71*67e74705SXin Li
72*67e74705SXin Li *out = b;
73*67e74705SXin Li }
74*67e74705SXin Li
75*67e74705SXin Li // CHECK: @test6
test6(float4 * ap,float4 * bp,float c)76*67e74705SXin Li void test6(float4 *ap, float4 *bp, float c) {
77*67e74705SXin Li float4 a = *ap;
78*67e74705SXin Li float4 b = *bp;
79*67e74705SXin Li
80*67e74705SXin Li // CHECK: fadd <4 x float>
81*67e74705SXin Li // CHECK: fsub <4 x float>
82*67e74705SXin Li // CHECK: fmul <4 x float>
83*67e74705SXin Li // CHECK: fdiv <4 x float>
84*67e74705SXin Li a = a + b;
85*67e74705SXin Li a = a - b;
86*67e74705SXin Li a = a * b;
87*67e74705SXin Li a = a / b;
88*67e74705SXin Li
89*67e74705SXin Li // CHECK: fadd <4 x float>
90*67e74705SXin Li // CHECK: fsub <4 x float>
91*67e74705SXin Li // CHECK: fmul <4 x float>
92*67e74705SXin Li // CHECK: fdiv <4 x float>
93*67e74705SXin Li a = a + c;
94*67e74705SXin Li a = a - c;
95*67e74705SXin Li a = a * c;
96*67e74705SXin Li a = a / c;
97*67e74705SXin Li
98*67e74705SXin Li // CHECK: fadd <4 x float>
99*67e74705SXin Li // CHECK: fsub <4 x float>
100*67e74705SXin Li // CHECK: fmul <4 x float>
101*67e74705SXin Li // CHECK: fdiv <4 x float>
102*67e74705SXin Li a += b;
103*67e74705SXin Li a -= b;
104*67e74705SXin Li a *= b;
105*67e74705SXin Li a /= b;
106*67e74705SXin Li
107*67e74705SXin Li // CHECK: fadd <4 x float>
108*67e74705SXin Li // CHECK: fsub <4 x float>
109*67e74705SXin Li // CHECK: fmul <4 x float>
110*67e74705SXin Li // CHECK: fdiv <4 x float>
111*67e74705SXin Li a += c;
112*67e74705SXin Li a -= c;
113*67e74705SXin Li a *= c;
114*67e74705SXin Li a /= c;
115*67e74705SXin Li
116*67e74705SXin Li // Vector comparisons can sometimes crash the x86 backend: rdar://6326239,
117*67e74705SXin Li // reject them until the implementation is stable.
118*67e74705SXin Li #if 0
119*67e74705SXin Li int4 cmp;
120*67e74705SXin Li cmp = a < b;
121*67e74705SXin Li cmp = a <= b;
122*67e74705SXin Li cmp = a < b;
123*67e74705SXin Li cmp = a >= b;
124*67e74705SXin Li cmp = a == b;
125*67e74705SXin Li cmp = a != b;
126*67e74705SXin Li #endif
127*67e74705SXin Li }
128*67e74705SXin Li
129*67e74705SXin Li // CHECK: @test7
test7(int4 * ap,int4 * bp,int c)130*67e74705SXin Li void test7(int4 *ap, int4 *bp, int c) {
131*67e74705SXin Li int4 a = *ap;
132*67e74705SXin Li int4 b = *bp;
133*67e74705SXin Li
134*67e74705SXin Li // CHECK: add <4 x i32>
135*67e74705SXin Li // CHECK: sub <4 x i32>
136*67e74705SXin Li // CHECK: mul <4 x i32>
137*67e74705SXin Li // CHECK: sdiv <4 x i32>
138*67e74705SXin Li // CHECK: srem <4 x i32>
139*67e74705SXin Li a = a + b;
140*67e74705SXin Li a = a - b;
141*67e74705SXin Li a = a * b;
142*67e74705SXin Li a = a / b;
143*67e74705SXin Li a = a % b;
144*67e74705SXin Li
145*67e74705SXin Li // CHECK: add <4 x i32>
146*67e74705SXin Li // CHECK: sub <4 x i32>
147*67e74705SXin Li // CHECK: mul <4 x i32>
148*67e74705SXin Li // CHECK: sdiv <4 x i32>
149*67e74705SXin Li // CHECK: srem <4 x i32>
150*67e74705SXin Li a = a + c;
151*67e74705SXin Li a = a - c;
152*67e74705SXin Li a = a * c;
153*67e74705SXin Li a = a / c;
154*67e74705SXin Li a = a % c;
155*67e74705SXin Li
156*67e74705SXin Li // CHECK: add <4 x i32>
157*67e74705SXin Li // CHECK: sub <4 x i32>
158*67e74705SXin Li // CHECK: mul <4 x i32>
159*67e74705SXin Li // CHECK: sdiv <4 x i32>
160*67e74705SXin Li // CHECK: srem <4 x i32>
161*67e74705SXin Li a += b;
162*67e74705SXin Li a -= b;
163*67e74705SXin Li a *= b;
164*67e74705SXin Li a /= b;
165*67e74705SXin Li a %= b;
166*67e74705SXin Li
167*67e74705SXin Li // CHECK: add <4 x i32>
168*67e74705SXin Li // CHECK: sub <4 x i32>
169*67e74705SXin Li // CHECK: mul <4 x i32>
170*67e74705SXin Li // CHECK: sdiv <4 x i32>
171*67e74705SXin Li // CHECK: srem <4 x i32>
172*67e74705SXin Li a += c;
173*67e74705SXin Li a -= c;
174*67e74705SXin Li a *= c;
175*67e74705SXin Li a /= c;
176*67e74705SXin Li a %= c;
177*67e74705SXin Li
178*67e74705SXin Li
179*67e74705SXin Li // Vector comparisons.
180*67e74705SXin Li // CHECK: icmp slt
181*67e74705SXin Li // CHECK: icmp sle
182*67e74705SXin Li // CHECK: icmp sgt
183*67e74705SXin Li // CHECK: icmp sge
184*67e74705SXin Li // CHECK: icmp eq
185*67e74705SXin Li // CHECK: icmp ne
186*67e74705SXin Li int4 cmp;
187*67e74705SXin Li cmp = a < b;
188*67e74705SXin Li cmp = a <= b;
189*67e74705SXin Li cmp = a > b;
190*67e74705SXin Li cmp = a >= b;
191*67e74705SXin Li cmp = a == b;
192*67e74705SXin Li cmp = a != b;
193*67e74705SXin Li }
194*67e74705SXin Li
195*67e74705SXin Li // CHECK: @test8
test8(float4 * ap,float4 * bp,int c)196*67e74705SXin Li void test8(float4 *ap, float4 *bp, int c) {
197*67e74705SXin Li float4 a = *ap;
198*67e74705SXin Li float4 b = *bp;
199*67e74705SXin Li
200*67e74705SXin Li // Vector comparisons.
201*67e74705SXin Li // CHECK: fcmp olt
202*67e74705SXin Li // CHECK: fcmp ole
203*67e74705SXin Li // CHECK: fcmp ogt
204*67e74705SXin Li // CHECK: fcmp oge
205*67e74705SXin Li // CHECK: fcmp oeq
206*67e74705SXin Li // CHECK: fcmp une
207*67e74705SXin Li int4 cmp;
208*67e74705SXin Li cmp = a < b;
209*67e74705SXin Li cmp = a <= b;
210*67e74705SXin Li cmp = a > b;
211*67e74705SXin Li cmp = a >= b;
212*67e74705SXin Li cmp = a == b;
213*67e74705SXin Li cmp = a != b;
214*67e74705SXin Li }
215*67e74705SXin Li
216*67e74705SXin Li // CHECK: @test9
217*67e74705SXin Li // CHECK: extractelement <4 x i32>
test9(int4 V)218*67e74705SXin Li int test9(int4 V) {
219*67e74705SXin Li return V.xy.x;
220*67e74705SXin Li }
221*67e74705SXin Li
222*67e74705SXin Li // CHECK: @test10
223*67e74705SXin Li // CHECK: add <4 x i32>
224*67e74705SXin Li // CHECK: extractelement <4 x i32>
test10(int4 V)225*67e74705SXin Li int test10(int4 V) {
226*67e74705SXin Li return (V+V).x;
227*67e74705SXin Li }
228*67e74705SXin Li
229*67e74705SXin Li // CHECK: @test11
230*67e74705SXin Li // CHECK: extractelement <4 x i32>
231*67e74705SXin Li int4 test11a();
test11()232*67e74705SXin Li int test11() {
233*67e74705SXin Li return test11a().x;
234*67e74705SXin Li }
235*67e74705SXin Li
236*67e74705SXin Li // CHECK: @test12
237*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 2, i32 1, i32 0>
238*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 0, i32 1, i32 2, i32 undef>
239*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 4, i32 5, i32 6, i32 3>
test12(int4 V)240*67e74705SXin Li int4 test12(int4 V) {
241*67e74705SXin Li V.xyz = V.zyx;
242*67e74705SXin Li return V;
243*67e74705SXin Li }
244*67e74705SXin Li
245*67e74705SXin Li // CHECK: @test13
246*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 2, i32 1, i32 0, i32 3>
test13(int4 * V)247*67e74705SXin Li int4 test13(int4 *V) {
248*67e74705SXin Li return V->zyxw;
249*67e74705SXin Li }
250*67e74705SXin Li
251*67e74705SXin Li // CHECK: @test14
test14(uint4 * ap,uint4 * bp,unsigned c)252*67e74705SXin Li void test14(uint4 *ap, uint4 *bp, unsigned c) {
253*67e74705SXin Li uint4 a = *ap;
254*67e74705SXin Li uint4 b = *bp;
255*67e74705SXin Li int4 d;
256*67e74705SXin Li
257*67e74705SXin Li // CHECK: udiv <4 x i32>
258*67e74705SXin Li // CHECK: urem <4 x i32>
259*67e74705SXin Li a = a / b;
260*67e74705SXin Li a = a % b;
261*67e74705SXin Li
262*67e74705SXin Li // CHECK: udiv <4 x i32>
263*67e74705SXin Li // CHECK: urem <4 x i32>
264*67e74705SXin Li a = a / c;
265*67e74705SXin Li a = a % c;
266*67e74705SXin Li
267*67e74705SXin Li // CHECK: icmp ult
268*67e74705SXin Li // CHECK: icmp ule
269*67e74705SXin Li // CHECK: icmp ugt
270*67e74705SXin Li // CHECK: icmp uge
271*67e74705SXin Li // CHECK: icmp eq
272*67e74705SXin Li // CHECK: icmp ne
273*67e74705SXin Li d = a < b;
274*67e74705SXin Li d = a <= b;
275*67e74705SXin Li d = a > b;
276*67e74705SXin Li d = a >= b;
277*67e74705SXin Li d = a == b;
278*67e74705SXin Li d = a != b;
279*67e74705SXin Li }
280*67e74705SXin Li
281*67e74705SXin Li // CHECK: @test15
test15(uint4 V0)282*67e74705SXin Li int4 test15(uint4 V0) {
283*67e74705SXin Li // CHECK: icmp eq <4 x i32>
284*67e74705SXin Li int4 V = !V0;
285*67e74705SXin Li V = V && V;
286*67e74705SXin Li V = V || V;
287*67e74705SXin Li return V;
288*67e74705SXin Li }
289*67e74705SXin Li
290*67e74705SXin Li // CHECK: @test16
test16(float2 a,float2 b)291*67e74705SXin Li void test16(float2 a, float2 b) {
292*67e74705SXin Li float2 t0 = (a + b) / 2;
293*67e74705SXin Li }
294*67e74705SXin Li
295*67e74705SXin Li typedef char char16 __attribute__((ext_vector_type(16)));
296*67e74705SXin Li
297*67e74705SXin Li // CHECK: @test17
test17(void)298*67e74705SXin Li void test17(void) {
299*67e74705SXin Li char16 valA;
300*67e74705SXin Li char valB;
301*67e74705SXin Li char valC;
302*67e74705SXin Li char16 destVal = valC ? valA : valB;
303*67e74705SXin Li }
304*67e74705SXin Li
305*67e74705SXin Li typedef __attribute__(( ext_vector_type(16) )) float float16;
306*67e74705SXin Li
307*67e74705SXin Li float16 vec16, vec16_2;
308*67e74705SXin Li
309*67e74705SXin Li // CHECK: @test_rgba
test_rgba()310*67e74705SXin Li void test_rgba() {
311*67e74705SXin Li // CHECK: fadd <4 x float>
312*67e74705SXin Li vec4_2 = vec4.abgr + vec4;
313*67e74705SXin Li
314*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 0, i32 1>
315*67e74705SXin Li vec2 = vec4.rg;
316*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 2, i32 3>
317*67e74705SXin Li vec2_2 = vec4.ba;
318*67e74705SXin Li // CHECK: extractelement {{.*}} 2
319*67e74705SXin Li f = vec4.b;
320*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 2, i32 2, i32 2, i32 2>
321*67e74705SXin Li vec4_2 = vec4_2.bbbb;
322*67e74705SXin Li
323*67e74705SXin Li // CHECK: insertelement {{.*}} 0
324*67e74705SXin Li vec2.r = f;
325*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 1, i32 0>
326*67e74705SXin Li vec2.gr = vec2;
327*67e74705SXin Li
328*67e74705SXin Li // CHECK: extractelement {{.*}} 0
329*67e74705SXin Li f = vec4_2.rg.r;
330*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 2, i32 1, i32 0>
331*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 0, i32 1, i32 2, i32 undef>
332*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 4, i32 5, i32 6, i32 3>
333*67e74705SXin Li vec4.rgb = vec4.bgr;
334*67e74705SXin Li
335*67e74705SXin Li // CHECK: extractelement {{.*}} 11
336*67e74705SXin Li // CHECK: insertelement {{.*}} 2
337*67e74705SXin Li vec4.b = vec16.sb;
338*67e74705SXin Li // CHECK: shufflevector {{.*}} <i32 10, i32 11, i32 12, i32 13>
339*67e74705SXin Li vec4_2 = vec16.sabcd;
340*67e74705SXin Li }
341