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