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 = {{(dso_local )?}}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 = {{(dso_local )?}}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 | |
305 | typedef __attribute__(( ext_vector_type(16) )) float float16; |
306 | |
307 | float16 vec16, vec16_2; |
308 | |
309 | // CHECK: @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 | |