1// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
2
3typedef __attribute__(( ext_vector_type(4) )) float float4;
4typedef __attribute__(( ext_vector_type(2) )) float float2;
5typedef __attribute__(( ext_vector_type(4) )) int int4;
6typedef __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>
9float4 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>
12const float4 bar = (float4){ 1.0, 2.0, 3.0, __builtin_inff() };
13
14// CHECK: @test1
15// CHECK: fadd <4 x float>
16float4 test1(float4 V) {
17  return V.wzyx+V;
18}
19
20float2 vec2, vec2_2;
21float4 vec4, vec4_2;
22float 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>
30void 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>
41void 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>
48void 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>
62void 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
76void 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
130void 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
196void 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>
218int 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>
225int test10(int4 V) {
226  return (V+V).x;
227}
228
229// CHECK: @test11
230// CHECK: extractelement <4 x i32>
231int4 test11a();
232int 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>
240int4 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>
247int4 test13(int4 *V) {
248  return V->zyxw;
249}
250
251// CHECK: @test14
252void 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
282int4 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
291void test16(float2 a, float2 b) {
292  float2 t0 = (a + b) / 2;
293}
294
295typedef char char16 __attribute__((ext_vector_type(16)));
296
297// CHECK: @test17
298void test17(void) {
299  char16 valA;
300  char valB;
301  char valC;
302  char16 destVal = valC ? valA : valB;
303}
304