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>
test1(float4 V)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>
test2()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>
test3(float4 * out)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>
test4(float4 * out)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>
test5(float4 * out)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
test6(float4 * ap,float4 * bp,float c)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
test7(int4 * ap,int4 * bp,int c)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
test8(float4 * ap,float4 * bp,int c)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>
test9(int4 V)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>
test10(int4 V)225 int test10(int4 V) {
226 return (V+V).x;
227 }
228
229 // CHECK: @test11
230 // CHECK: extractelement <4 x i32>
231 int4 test11a();
test11()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>
test12(int4 V)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>
test13(int4 * V)247 int4 test13(int4 *V) {
248 return V->zyxw;
249 }
250
251 // CHECK: @test14
test14(uint4 * ap,uint4 * bp,unsigned c)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
test15(uint4 V0)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
test16(float2 a,float2 b)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
test17(void)298 void test17(void) {
299 char16 valA;
300 char valB;
301 char valC;
302 char16 destVal = valC ? valA : valB;
303 }
304
305 typedef __attribute__(( ext_vector_type(16) )) float float16;
306
307 float16 vec16, vec16_2;
308
309 // CHECK: @test_rgba
test_rgba()310 void test_rgba() {
311 // CHECK: fadd <4 x float>
312 vec4_2 = vec4.abgr + vec4;
313
314 // CHECK: shufflevector {{.*}} <i32 0, i32 1>
315 vec2 = vec4.rg;
316 // CHECK: shufflevector {{.*}} <i32 2, i32 3>
317 vec2_2 = vec4.ba;
318 // CHECK: extractelement {{.*}} 2
319 f = vec4.b;
320 // CHECK: shufflevector {{.*}} <i32 2, i32 2, i32 2, i32 2>
321 vec4_2 = vec4_2.bbbb;
322
323 // CHECK: insertelement {{.*}} 0
324 vec2.r = f;
325 // CHECK: shufflevector {{.*}} <i32 1, i32 0>
326 vec2.gr = vec2;
327
328 // CHECK: extractelement {{.*}} 0
329 f = vec4_2.rg.r;
330 // CHECK: shufflevector {{.*}} <i32 2, i32 1, i32 0>
331 // CHECK: shufflevector {{.*}} <i32 0, i32 1, i32 2, i32 undef>
332 // CHECK: shufflevector {{.*}} <i32 4, i32 5, i32 6, i32 3>
333 vec4.rgb = vec4.bgr;
334
335 // CHECK: extractelement {{.*}} 11
336 // CHECK: insertelement {{.*}} 2
337 vec4.b = vec16.sb;
338 // CHECK: shufflevector {{.*}} <i32 10, i32 11, i32 12, i32 13>
339 vec4_2 = vec16.sabcd;
340 }
341