1 // RUN: %clang_cc1 -no-opaque-pointers -std=c++14 -Wno-unused-value %s -disable-llvm-passes -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
2 
3 // FIXME: Unfortunately there is no good way to validate that our values are
4 // correct since Vector types don't have operator [] implemented for constexpr.
5 // Instead, we need to use filecheck to ensure the emitted IR is correct. Once
6 // someone implements array subscript operator for these types as constexpr,
7 // this test should modified to jsut use static asserts.
8 
9 using FourCharsVecSize __attribute__((vector_size(4))) = char;
10 using FourIntsVecSize __attribute__((vector_size(16))) = int;
11 using FourLongLongsVecSize __attribute__((vector_size(32))) = long long;
12 using FourFloatsVecSize __attribute__((vector_size(16))) = float;
13 using FourDoublesVecSize __attribute__((vector_size(32))) = double;
14 using FourI128VecSize __attribute__((vector_size(64))) = __int128;
15 
16 using FourCharsExtVec __attribute__((ext_vector_type(4))) = char;
17 using FourIntsExtVec __attribute__((ext_vector_type(4))) = int;
18 using FourLongLongsExtVec __attribute__((ext_vector_type(4))) = long long;
19 using FourFloatsExtVec __attribute__((ext_vector_type(4))) = float;
20 using FourDoublesExtVec __attribute__((ext_vector_type(4))) = double;
21 using FourI128ExtVec __attribute__((ext_vector_type(4))) = __int128;
22 
23 
24 // Next a series of tests to make sure these operations are usable in
25 // constexpr functions. Template instantiations don't emit Winvalid-constexpr,
26 // so we have to do these as macros.
27 #define MathShiftOps(Type)                            \
28   constexpr auto MathShiftOps##Type(Type a, Type b) { \
29     a = a + b;                                        \
30     a = a - b;                                        \
31     a = a * b;                                        \
32     a = a / b;                                        \
33     b = a + 1;                                        \
34     b = a - 1;                                        \
35     b = a * 1;                                        \
36     b = a / 1;                                        \
37     a += a;                                           \
38     a -= a;                                           \
39     a *= a;                                           \
40     a /= a;                                           \
41     b += a;                                           \
42     b -= a;                                           \
43     b *= a;                                           \
44     b /= a;                                           \
45     a < b;                                            \
46     a > b;                                            \
47     a <= b;                                           \
48     a >= b;                                           \
49     a == b;                                           \
50     a != b;                                           \
51     a &&b;                                            \
52     a || b;                                           \
53     auto c = (a, b);                                  \
54     return c;                                         \
55   }
56 
57 // Ops specific to Integers.
58 #define MathShiftOpsInts(Type)                            \
59   constexpr auto MathShiftopsInts##Type(Type a, Type b) { \
60     a = a << b;                                           \
61     a = a >> b;                                           \
62     a = a << 3;                                           \
63     a = a >> 3;                                           \
64     a = 3 << b;                                           \
65     a = 3 >> b;                                           \
66     a <<= b;                                              \
67     a >>= b;                                              \
68     a <<= 3;                                              \
69     a >>= 3;                                              \
70     a = a % b;                                            \
71     a &b;                                                 \
72     a | b;                                                \
73     a ^ b;                                                \
74     return a;                                             \
75   }
76 
77 MathShiftOps(FourCharsVecSize);
78 MathShiftOps(FourIntsVecSize);
79 MathShiftOps(FourLongLongsVecSize);
80 MathShiftOps(FourFloatsVecSize);
81 MathShiftOps(FourDoublesVecSize);
82 MathShiftOps(FourCharsExtVec);
83 MathShiftOps(FourIntsExtVec);
84 MathShiftOps(FourLongLongsExtVec);
85 MathShiftOps(FourFloatsExtVec);
86 MathShiftOps(FourDoublesExtVec);
87 
88 MathShiftOpsInts(FourCharsVecSize);
89 MathShiftOpsInts(FourIntsVecSize);
90 MathShiftOpsInts(FourLongLongsVecSize);
91 MathShiftOpsInts(FourCharsExtVec);
92 MathShiftOpsInts(FourIntsExtVec);
93 MathShiftOpsInts(FourLongLongsExtVec);
94 
95 template <typename T, typename U>
CmpMul(T t,U u)96 constexpr auto CmpMul(T t, U u) {
97   t *= u;
98   return t;
99 }
100 template <typename T, typename U>
CmpDiv(T t,U u)101 constexpr auto CmpDiv(T t, U u) {
102   t /= u;
103   return t;
104 }
105 template <typename T, typename U>
CmpRem(T t,U u)106 constexpr auto CmpRem(T t, U u) {
107   t %= u;
108   return t;
109 }
110 
111 template <typename T, typename U>
CmpAdd(T t,U u)112 constexpr auto CmpAdd(T t, U u) {
113   t += u;
114   return t;
115 }
116 
117 template <typename T, typename U>
CmpSub(T t,U u)118 constexpr auto CmpSub(T t, U u) {
119   t -= u;
120   return t;
121 }
122 
123 template <typename T, typename U>
CmpLSH(T t,U u)124 constexpr auto CmpLSH(T t, U u) {
125   t <<= u;
126   return t;
127 }
128 
129 template <typename T, typename U>
CmpRSH(T t,U u)130 constexpr auto CmpRSH(T t, U u) {
131   t >>= u;
132   return t;
133 }
134 
135 template <typename T, typename U>
CmpBinAnd(T t,U u)136 constexpr auto CmpBinAnd(T t, U u) {
137   t &= u;
138   return t;
139 }
140 
141 template <typename T, typename U>
CmpBinXOr(T t,U u)142 constexpr auto CmpBinXOr(T t, U u) {
143   t ^= u;
144   return t;
145 }
146 
147 template <typename T, typename U>
CmpBinOr(T t,U u)148 constexpr auto CmpBinOr(T t, U u) {
149   t |= u;
150   return t;
151 }
152 
153 // Only int vs float makes a difference here, so we only need to test 1 of each.
154 // Test Char to make sure the mixed-nature of shifts around char is evident.
CharUsage()155 void CharUsage() {
156   constexpr auto a = FourCharsVecSize{6, 3, 2, 1} +
157                      FourCharsVecSize{12, 15, 5, 7};
158   // CHECK: store <4 x i8> <i8 18, i8 18, i8 7, i8 8>
159   constexpr auto b = FourCharsVecSize{19, 15, 13, 12} -
160                      FourCharsVecSize{13, 14, 5, 3};
161   // CHECK: store <4 x i8> <i8 6, i8 1, i8 8, i8 9>
162   constexpr auto c = FourCharsVecSize{8, 4, 2, 1} *
163                      FourCharsVecSize{3, 4, 5, 6};
164   // CHECK: store <4 x i8> <i8 24, i8 16, i8 10, i8 6>
165   constexpr auto d = FourCharsVecSize{12, 12, 10, 10} /
166                      FourCharsVecSize{6, 4, 5, 2};
167   // CHECK: store <4 x i8> <i8 2, i8 3, i8 2, i8 5>
168   constexpr auto e = FourCharsVecSize{12, 12, 10, 10} %
169                      FourCharsVecSize{6, 4, 4, 3};
170   // CHECK: store <4 x i8> <i8 0, i8 0, i8 2, i8 1>
171 
172   constexpr auto f = FourCharsVecSize{6, 3, 2, 1} + 3;
173   // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4>
174   constexpr auto g = FourCharsVecSize{19, 15, 12, 10} - 3;
175   // CHECK: store <4 x i8> <i8 16, i8 12, i8 9, i8 7>
176   constexpr auto h = FourCharsVecSize{8, 4, 2, 1} * 3;
177   // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3>
178   constexpr auto j = FourCharsVecSize{12, 15, 18, 21} / 3;
179   // CHECK: store <4 x i8> <i8 4, i8 5, i8 6, i8 7>
180   constexpr auto k = FourCharsVecSize{12, 17, 19, 22} % 3;
181   // CHECK: store <4 x i8> <i8 0, i8 2, i8 1, i8 1>
182 
183   constexpr auto l = 3 + FourCharsVecSize{6, 3, 2, 1};
184   // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4>
185   constexpr auto m = 20 - FourCharsVecSize{19, 15, 12, 10};
186   // CHECK: store <4 x i8> <i8 1, i8 5, i8 8, i8 10>
187   constexpr auto n = 3 * FourCharsVecSize{8, 4, 2, 1};
188   // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3>
189   constexpr auto o = 100 / FourCharsVecSize{12, 15, 18, 21};
190   // CHECK: store <4 x i8> <i8 8, i8 6, i8 5, i8 4>
191   constexpr auto p = 100 % FourCharsVecSize{12, 15, 18, 21};
192   // CHECK: store <4 x i8> <i8 4, i8 10, i8 10, i8 16>
193 
194   constexpr auto q = FourCharsVecSize{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2};
195   // CHECK: store <4 x i8> <i8 12, i8 6, i8 8, i8 4>
196   constexpr auto r = FourCharsVecSize{19, 15, 12, 10} >>
197                      FourCharsVecSize{1, 1, 2, 2};
198   // CHECK: store <4 x i8> <i8 9, i8 7, i8 3, i8 2>
199   constexpr auto s = FourCharsVecSize{6, 3, 5, 10} << 1;
200   // CHECK: store <4 x i8> <i8 12, i8 6, i8 10, i8 20>
201   constexpr auto t = FourCharsVecSize{19, 15, 10, 20} >> 1;
202   // CHECK: store <4 x i8> <i8 9, i8 7, i8 5, i8 10>
203   constexpr auto u = 12 << FourCharsVecSize{1, 2, 3, 3};
204   // CHECK: store <4 x i8> <i8 24, i8 48, i8 96, i8 96>
205   constexpr auto v = 12 >> FourCharsVecSize{1, 2, 2, 1};
206   // CHECK: store <4 x i8> <i8 6, i8 3, i8 3, i8 6>
207 
208   constexpr auto w = FourCharsVecSize{1, 2, 3, 4} <
209                      FourCharsVecSize{4, 3, 2, 1};
210   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0>
211   constexpr auto x = FourCharsVecSize{1, 2, 3, 4} >
212                      FourCharsVecSize{4, 3, 2, 1};
213   // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
214   constexpr auto y = FourCharsVecSize{1, 2, 3, 4} <=
215                      FourCharsVecSize{4, 3, 3, 1};
216   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0>
217   constexpr auto z = FourCharsVecSize{1, 2, 3, 4} >=
218                      FourCharsVecSize{4, 3, 3, 1};
219   // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
220   constexpr auto A = FourCharsVecSize{1, 2, 3, 4} ==
221                      FourCharsVecSize{4, 3, 3, 1};
222   // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0>
223   constexpr auto B = FourCharsVecSize{1, 2, 3, 4} !=
224                      FourCharsVecSize{4, 3, 3, 1};
225   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1>
226 
227   constexpr auto C = FourCharsVecSize{1, 2, 3, 4} < 3;
228   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0>
229   constexpr auto D = FourCharsVecSize{1, 2, 3, 4} > 3;
230   // CHECK: store <4 x i8> <i8 0, i8 0, i8 0, i8 -1>
231   constexpr auto E = FourCharsVecSize{1, 2, 3, 4} <= 3;
232   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0>
233   constexpr auto F = FourCharsVecSize{1, 2, 3, 4} >= 3;
234   // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
235   constexpr auto G = FourCharsVecSize{1, 2, 3, 4} == 3;
236   // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0>
237   constexpr auto H = FourCharsVecSize{1, 2, 3, 4} != 3;
238   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1>
239 
240   constexpr auto I = FourCharsVecSize{1, 2, 3, 4} &
241                      FourCharsVecSize{4, 3, 2, 1};
242   // CHECK: store <4 x i8> <i8 0, i8 2, i8 2, i8 0>
243   constexpr auto J = FourCharsVecSize{1, 2, 3, 4} ^
244                      FourCharsVecSize { 4, 3, 2, 1 };
245   // CHECK: store <4 x i8> <i8 5, i8 1, i8 1, i8 5>
246   constexpr auto K = FourCharsVecSize{1, 2, 3, 4} |
247                      FourCharsVecSize{4, 3, 2, 1};
248   // CHECK: store <4 x i8> <i8 5, i8 3, i8 3, i8 5>
249   constexpr auto L = FourCharsVecSize{1, 2, 3, 4} & 3;
250   // CHECK: store <4 x i8> <i8 1, i8 2, i8 3, i8 0>
251   constexpr auto M = FourCharsVecSize{1, 2, 3, 4} ^ 3;
252   // CHECK: store <4 x i8> <i8 2, i8 1, i8 0, i8 7>
253   constexpr auto N = FourCharsVecSize{1, 2, 3, 4} | 3;
254   // CHECK: store <4 x i8> <i8 3, i8 3, i8 3, i8 7>
255 
256   constexpr auto O = FourCharsVecSize{5, 0, 6, 0} &&
257                      FourCharsVecSize{5, 5, 0, 0};
258   // CHECK: store <4 x i8> <i8 1, i8 0, i8 0, i8 0>
259   constexpr auto P = FourCharsVecSize{5, 0, 6, 0} ||
260                      FourCharsVecSize{5, 5, 0, 0};
261   // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
262 
263   constexpr auto Q = FourCharsVecSize{5, 0, 6, 0} && 3;
264   // CHECK: store <4 x i8> <i8 1, i8 0, i8 1, i8 0>
265   constexpr auto R = FourCharsVecSize{5, 0, 6, 0} || 3;
266   // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 1>
267 
268   constexpr auto T = CmpMul(a, b);
269   // CHECK: store <4 x i8> <i8 108, i8 18, i8 56, i8 72>
270 
271   constexpr auto U = CmpDiv(a, b);
272   // CHECK: store <4 x i8> <i8 3, i8 18, i8 0, i8 0>
273 
274   constexpr auto V = CmpRem(a, b);
275   // CHECK: store <4 x i8> <i8 0, i8 0, i8 7, i8 8>
276 
277   constexpr auto X = CmpAdd(a, b);
278   // CHECK: store <4 x i8> <i8 24, i8 19, i8 15, i8 17>
279 
280   constexpr auto Y = CmpSub(a, b);
281   // CHECK: store <4 x i8> <i8 12, i8 17, i8 -1, i8 -1>
282 
283   constexpr auto InvH = -H;
284   // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
285   constexpr auto Z = CmpLSH(a, InvH);
286   // CHECK: store <4 x i8> <i8 36, i8 36, i8 7, i8 16>
287 
288   constexpr auto aa = CmpRSH(a, InvH);
289   // CHECK: store <4 x i8> <i8 9, i8 9, i8 7, i8 4>
290 
291   constexpr auto ab = CmpBinAnd(a, b);
292   // CHECK: store <4 x i8> <i8 2, i8 0, i8 0, i8 8>
293 
294   constexpr auto ac = CmpBinXOr(a, b);
295   // CHECK: store <4 x i8> <i8 20, i8 19, i8 15, i8 1>
296 
297   constexpr auto ad = CmpBinOr(a, b);
298   // CHECK: store <4 x i8> <i8 22, i8 19, i8 15, i8 9>
299 
300   constexpr auto ae = ~FourCharsVecSize{1, 2, 10, 20};
301   // CHECK: store <4 x i8> <i8 -2, i8 -3, i8 -11, i8 -21>
302 
303   constexpr auto af = !FourCharsVecSize{0, 1, 8, -1};
304   // CHECK: store <4 x i8> <i8 -1, i8 0, i8 0, i8 0>
305 }
306 
CharExtVecUsage()307 void CharExtVecUsage() {
308   constexpr auto a = FourCharsExtVec{6, 3, 2, 1} +
309                      FourCharsExtVec{12, 15, 5, 7};
310   // CHECK: store <4 x i8> <i8 18, i8 18, i8 7, i8 8>
311   constexpr auto b = FourCharsExtVec{19, 15, 13, 12} -
312                      FourCharsExtVec{13, 14, 5, 3};
313   // CHECK: store <4 x i8> <i8 6, i8 1, i8 8, i8 9>
314   constexpr auto c = FourCharsExtVec{8, 4, 2, 1} *
315                      FourCharsExtVec{3, 4, 5, 6};
316   // CHECK: store <4 x i8> <i8 24, i8 16, i8 10, i8 6>
317   constexpr auto d = FourCharsExtVec{12, 12, 10, 10} /
318                      FourCharsExtVec{6, 4, 5, 2};
319   // CHECK: store <4 x i8> <i8 2, i8 3, i8 2, i8 5>
320   constexpr auto e = FourCharsExtVec{12, 12, 10, 10} %
321                      FourCharsExtVec{6, 4, 4, 3};
322   // CHECK: store <4 x i8> <i8 0, i8 0, i8 2, i8 1>
323 
324   constexpr auto f = FourCharsExtVec{6, 3, 2, 1} + 3;
325   // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4>
326   constexpr auto g = FourCharsExtVec{19, 15, 12, 10} - 3;
327   // CHECK: store <4 x i8> <i8 16, i8 12, i8 9, i8 7>
328   constexpr auto h = FourCharsExtVec{8, 4, 2, 1} * 3;
329   // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3>
330   constexpr auto j = FourCharsExtVec{12, 15, 18, 21} / 3;
331   // CHECK: store <4 x i8> <i8 4, i8 5, i8 6, i8 7>
332   constexpr auto k = FourCharsExtVec{12, 17, 19, 22} % 3;
333   // CHECK: store <4 x i8> <i8 0, i8 2, i8 1, i8 1>
334 
335   constexpr auto l = 3 + FourCharsExtVec{6, 3, 2, 1};
336   // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4>
337   constexpr auto m = 20 - FourCharsExtVec{19, 15, 12, 10};
338   // CHECK: store <4 x i8> <i8 1, i8 5, i8 8, i8 10>
339   constexpr auto n = 3 * FourCharsExtVec{8, 4, 2, 1};
340   // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3>
341   constexpr auto o = 100 / FourCharsExtVec{12, 15, 18, 21};
342   // CHECK: store <4 x i8> <i8 8, i8 6, i8 5, i8 4>
343   constexpr auto p = 100 % FourCharsExtVec{12, 15, 18, 21};
344   // CHECK: store <4 x i8> <i8 4, i8 10, i8 10, i8 16>
345 
346   constexpr auto q = FourCharsExtVec{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2};
347   // CHECK: store <4 x i8> <i8 12, i8 6, i8 8, i8 4>
348   constexpr auto r = FourCharsExtVec{19, 15, 12, 10} >>
349                      FourCharsExtVec{1, 1, 2, 2};
350   // CHECK: store <4 x i8> <i8 9, i8 7, i8 3, i8 2>
351   constexpr auto s = FourCharsExtVec{6, 3, 5, 10} << 1;
352   // CHECK: store <4 x i8> <i8 12, i8 6, i8 10, i8 20>
353   constexpr auto t = FourCharsExtVec{19, 15, 10, 20} >> 1;
354   // CHECK: store <4 x i8> <i8 9, i8 7, i8 5, i8 10>
355   constexpr auto u = 12 << FourCharsExtVec{1, 2, 3, 3};
356   // CHECK: store <4 x i8> <i8 24, i8 48, i8 96, i8 96>
357   constexpr auto v = 12 >> FourCharsExtVec{1, 2, 2, 1};
358   // CHECK: store <4 x i8> <i8 6, i8 3, i8 3, i8 6>
359 
360   constexpr auto w = FourCharsExtVec{1, 2, 3, 4} <
361                      FourCharsExtVec{4, 3, 2, 1};
362   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0>
363   constexpr auto x = FourCharsExtVec{1, 2, 3, 4} >
364                      FourCharsExtVec{4, 3, 2, 1};
365   // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
366   constexpr auto y = FourCharsExtVec{1, 2, 3, 4} <=
367                      FourCharsExtVec{4, 3, 3, 1};
368   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0>
369   constexpr auto z = FourCharsExtVec{1, 2, 3, 4} >=
370                      FourCharsExtVec{4, 3, 3, 1};
371   // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
372   constexpr auto A = FourCharsExtVec{1, 2, 3, 4} ==
373                      FourCharsExtVec{4, 3, 3, 1};
374   // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0>
375   constexpr auto B = FourCharsExtVec{1, 2, 3, 4} !=
376                      FourCharsExtVec{4, 3, 3, 1};
377   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1>
378 
379   constexpr auto C = FourCharsExtVec{1, 2, 3, 4} < 3;
380   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0>
381   constexpr auto D = FourCharsExtVec{1, 2, 3, 4} > 3;
382   // CHECK: store <4 x i8> <i8 0, i8 0, i8 0, i8 -1>
383   constexpr auto E = FourCharsExtVec{1, 2, 3, 4} <= 3;
384   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0>
385   constexpr auto F = FourCharsExtVec{1, 2, 3, 4} >= 3;
386   // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
387   constexpr auto G = FourCharsExtVec{1, 2, 3, 4} == 3;
388   // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0>
389   constexpr auto H = FourCharsExtVec{1, 2, 3, 4} != 3;
390   // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1>
391 
392   constexpr auto I = FourCharsExtVec{1, 2, 3, 4} &
393                      FourCharsExtVec{4, 3, 2, 1};
394   // CHECK: store <4 x i8> <i8 0, i8 2, i8 2, i8 0>
395   constexpr auto J = FourCharsExtVec{1, 2, 3, 4} ^
396                      FourCharsExtVec { 4, 3, 2, 1 };
397   // CHECK: store <4 x i8> <i8 5, i8 1, i8 1, i8 5>
398   constexpr auto K = FourCharsExtVec{1, 2, 3, 4} |
399                      FourCharsExtVec{4, 3, 2, 1};
400   // CHECK: store <4 x i8> <i8 5, i8 3, i8 3, i8 5>
401   constexpr auto L = FourCharsExtVec{1, 2, 3, 4} & 3;
402   // CHECK: store <4 x i8> <i8 1, i8 2, i8 3, i8 0>
403   constexpr auto M = FourCharsExtVec{1, 2, 3, 4} ^ 3;
404   // CHECK: store <4 x i8> <i8 2, i8 1, i8 0, i8 7>
405   constexpr auto N = FourCharsExtVec{1, 2, 3, 4} | 3;
406   // CHECK: store <4 x i8> <i8 3, i8 3, i8 3, i8 7>
407 
408   constexpr auto O = FourCharsExtVec{5, 0, 6, 0} &&
409                      FourCharsExtVec{5, 5, 0, 0};
410   // CHECK: store <4 x i8> <i8 1, i8 0, i8 0, i8 0>
411   constexpr auto P = FourCharsExtVec{5, 0, 6, 0} ||
412                      FourCharsExtVec{5, 5, 0, 0};
413   // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
414 
415   constexpr auto Q = FourCharsExtVec{5, 0, 6, 0} && 3;
416   // CHECK: store <4 x i8> <i8 1, i8 0, i8 1, i8 0>
417   constexpr auto R = FourCharsExtVec{5, 0, 6, 0} || 3;
418   // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 1>
419 
420   constexpr auto T = CmpMul(a, b);
421   // CHECK: store <4 x i8> <i8 108, i8 18, i8 56, i8 72>
422 
423   constexpr auto U = CmpDiv(a, b);
424   // CHECK: store <4 x i8> <i8 3, i8 18, i8 0, i8 0>
425 
426   constexpr auto V = CmpRem(a, b);
427   // CHECK: store <4 x i8> <i8 0, i8 0, i8 7, i8 8>
428 
429   constexpr auto X = CmpAdd(a, b);
430   // CHECK: store <4 x i8> <i8 24, i8 19, i8 15, i8 17>
431 
432   constexpr auto Y = CmpSub(a, b);
433   // CHECK: store <4 x i8> <i8 12, i8 17, i8 -1, i8 -1>
434 
435   constexpr auto InvH = -H;
436   // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
437 
438   constexpr auto Z = CmpLSH(a, InvH);
439   // CHECK: store <4 x i8> <i8 36, i8 36, i8 7, i8 16>
440 
441   constexpr auto aa = CmpRSH(a, InvH);
442   // CHECK: store <4 x i8> <i8 9, i8 9, i8 7, i8 4>
443 
444   constexpr auto ab = CmpBinAnd(a, b);
445   // CHECK: store <4 x i8> <i8 2, i8 0, i8 0, i8 8>
446 
447   constexpr auto ac = CmpBinXOr(a, b);
448   // CHECK: store <4 x i8> <i8 20, i8 19, i8 15, i8 1>
449 
450   constexpr auto ad = CmpBinOr(a, b);
451   // CHECK: store <4 x i8> <i8 22, i8 19, i8 15, i8 9>
452 
453   constexpr auto ae = ~FourCharsExtVec{1, 2, 10, 20};
454   // CHECK: store <4 x i8> <i8 -2, i8 -3, i8 -11, i8 -21>
455 
456   constexpr auto af = !FourCharsExtVec{0, 1, 8, -1};
457   // CHECK: store <4 x i8> <i8 -1, i8 0, i8 0, i8 0>
458 }
459 
FloatUsage()460 void FloatUsage() {
461   constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} +
462                      FourFloatsVecSize{12, 15, 5, 7};
463   // CHECK: <4 x float> <float 1.800000e+01, float 1.800000e+01, float 7.000000e+00, float 8.000000e+00>
464   constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} -
465                      FourFloatsVecSize{13, 14, 5, 3};
466   // CHECK: store <4 x float> <float 6.000000e+00, float 1.000000e+00, float 8.000000e+00, float 9.000000e+00>
467   constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} *
468                      FourFloatsVecSize{3, 4, 5, 6};
469   // CHECK: store <4 x float> <float 2.400000e+01, float 1.600000e+01, float 1.000000e+01, float 6.000000e+00>
470   constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} /
471                      FourFloatsVecSize{6, 4, 5, 2};
472   // CHECK: store <4 x float> <float 2.000000e+00, float 3.000000e+00, float 2.000000e+00, float 5.000000e+00>
473 
474   constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3;
475   // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00>
476   constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3;
477   // CHECK: store <4 x float> <float 1.600000e+01, float 1.200000e+01, float 9.000000e+00, float 7.000000e+00>
478   constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3;
479   // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00>
480   constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3;
481   // CHECK: store <4 x float> <float 4.000000e+00, float 5.000000e+00, float 6.000000e+00, float 7.000000e+00>
482 
483   constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1};
484   // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00>
485   constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10};
486   // CHECK: store <4 x float> <float 1.000000e+00, float 5.000000e+00, float 8.000000e+00, float 1.000000e+01>
487   constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1};
488   // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00>
489   constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21};
490   // CHECK: store <4 x float> <float 0x4020AAAAA0000000, float 0x401AAAAAA0000000, float 0x401638E380000000, float 0x40130C30C0000000>
491 
492   constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} <
493                      FourFloatsVecSize{4, 3, 2, 1};
494   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0>
495   constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} >
496                      FourFloatsVecSize{4, 3, 2, 1};
497   // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
498   constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <=
499                      FourFloatsVecSize{4, 3, 3, 1};
500   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0>
501   constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >=
502                      FourFloatsVecSize{4, 3, 3, 1};
503   // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
504   constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} ==
505                      FourFloatsVecSize{4, 3, 3, 1};
506   // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0>
507   constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} !=
508                      FourFloatsVecSize{4, 3, 3, 1};
509   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1>
510 
511   constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3;
512   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0>
513   constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3;
514   // CHECK: store <4 x i32> <i32 0, i32 0, i32 0, i32 -1>
515   constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3;
516   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0>
517   constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3;
518   // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
519   constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3;
520   // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0>
521   constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3;
522   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1>
523 
524   constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} &&
525                      FourFloatsVecSize{5, 5, 0, 0};
526   // CHECK: store <4 x i32> <i32 1, i32 0, i32 0, i32 0>
527   constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} ||
528                      FourFloatsVecSize{5, 5, 0, 0};
529   // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
530 
531   constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3;
532   // CHECK: store <4 x i32> <i32 1, i32 0, i32 1, i32 0>
533   constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3;
534   // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 1>
535 
536   constexpr auto T = CmpMul(a, b);
537   // CHECK: store <4 x float> <float 1.080000e+02, float 1.800000e+01, float 5.600000e+01, float 7.200000e+01>
538 
539   constexpr auto U = CmpDiv(a, b);
540   // CHECK: store <4 x float> <float 3.000000e+00, float 1.800000e+01, float 8.750000e-01, float 0x3FEC71C720000000>
541 
542   constexpr auto X = CmpAdd(a, b);
543   // CHECK: store <4 x float> <float 2.400000e+01, float 1.900000e+01, float 1.500000e+01, float 1.700000e+01>
544 
545   constexpr auto Y = CmpSub(a, b);
546   // CHECK: store <4 x float> <float 1.200000e+01, float 1.700000e+01, float -1.000000e+00, float -1.000000e+00>
547 
548   constexpr auto Z = -Y;
549   // CHECK: store <4 x float> <float -1.200000e+01, float -1.700000e+01, float 1.000000e+00, float 1.000000e+00>
550 
551   // Operator ~ is illegal on floats, so no test for that.
552   constexpr auto af = !FourFloatsVecSize{0, 1, 8, -1};
553   // CHECK: store <4 x i32> <i32 -1, i32 0, i32 0, i32 0>
554 }
555 
FloatVecUsage()556 void FloatVecUsage() {
557   constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} +
558                      FourFloatsVecSize{12, 15, 5, 7};
559   // CHECK: <4 x float> <float 1.800000e+01, float 1.800000e+01, float 7.000000e+00, float 8.000000e+00>
560   constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} -
561                      FourFloatsVecSize{13, 14, 5, 3};
562   // CHECK: store <4 x float> <float 6.000000e+00, float 1.000000e+00, float 8.000000e+00, float 9.000000e+00>
563   constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} *
564                      FourFloatsVecSize{3, 4, 5, 6};
565   // CHECK: store <4 x float> <float 2.400000e+01, float 1.600000e+01, float 1.000000e+01, float 6.000000e+00>
566   constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} /
567                      FourFloatsVecSize{6, 4, 5, 2};
568   // CHECK: store <4 x float> <float 2.000000e+00, float 3.000000e+00, float 2.000000e+00, float 5.000000e+00>
569 
570   constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3;
571   // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00>
572   constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3;
573   // CHECK: store <4 x float> <float 1.600000e+01, float 1.200000e+01, float 9.000000e+00, float 7.000000e+00>
574   constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3;
575   // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00>
576   constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3;
577   // CHECK: store <4 x float> <float 4.000000e+00, float 5.000000e+00, float 6.000000e+00, float 7.000000e+00>
578 
579   constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1};
580   // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00>
581   constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10};
582   // CHECK: store <4 x float> <float 1.000000e+00, float 5.000000e+00, float 8.000000e+00, float 1.000000e+01>
583   constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1};
584   // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00>
585   constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21};
586   // CHECK: store <4 x float> <float 0x4020AAAAA0000000, float 0x401AAAAAA0000000, float 0x401638E380000000, float 0x40130C30C0000000>
587 
588   constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} <
589                      FourFloatsVecSize{4, 3, 2, 1};
590   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0>
591   constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} >
592                      FourFloatsVecSize{4, 3, 2, 1};
593   // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
594   constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <=
595                      FourFloatsVecSize{4, 3, 3, 1};
596   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0>
597   constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >=
598                      FourFloatsVecSize{4, 3, 3, 1};
599   // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
600   constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} ==
601                      FourFloatsVecSize{4, 3, 3, 1};
602   // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0>
603   constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} !=
604                      FourFloatsVecSize{4, 3, 3, 1};
605   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1>
606 
607   constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3;
608   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0>
609   constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3;
610   // CHECK: store <4 x i32> <i32 0, i32 0, i32 0, i32 -1>
611   constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3;
612   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0>
613   constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3;
614   // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
615   constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3;
616   // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0>
617   constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3;
618   // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1>
619 
620   constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} &&
621                      FourFloatsVecSize{5, 5, 0, 0};
622   // CHECK: store <4 x i32> <i32 1, i32 0, i32 0, i32 0>
623   constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} ||
624                      FourFloatsVecSize{5, 5, 0, 0};
625   // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
626 
627   constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3;
628   // CHECK: store <4 x i32> <i32 1, i32 0, i32 1, i32 0>
629   constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3;
630   // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 1>
631 
632   constexpr auto T = CmpMul(a, b);
633   // CHECK: store <4 x float> <float 1.080000e+02, float 1.800000e+01, float 5.600000e+01, float 7.200000e+01>
634 
635   constexpr auto U = CmpDiv(a, b);
636   // CHECK: store <4 x float> <float 3.000000e+00, float 1.800000e+01, float 8.750000e-01, float 0x3FEC71C720000000>
637 
638   constexpr auto X = CmpAdd(a, b);
639   // CHECK: store <4 x float> <float 2.400000e+01, float 1.900000e+01, float 1.500000e+01, float 1.700000e+01>
640 
641   constexpr auto Y = CmpSub(a, b);
642   // CHECK: store <4 x float> <float 1.200000e+01, float 1.700000e+01, float -1.000000e+00, float -1.000000e+00>
643 
644   constexpr auto Z = -Y;
645   // CHECK: store <4 x float> <float -1.200000e+01, float -1.700000e+01, float 1.000000e+00, float 1.000000e+00>
646 
647   // Operator ~ is illegal on floats, so no test for that.
648   constexpr auto af = !FourFloatsVecSize{0, 1, 8, -1};
649   // CHECK: store <4 x i32> <i32 -1, i32 0, i32 0, i32 0>
650 }
651 
I128Usage()652 void I128Usage() {
653   constexpr auto a = FourI128VecSize{1, 2, 3, 4};
654   // CHECK: store <4 x i128> <i128 1, i128 2, i128 3, i128 4>
655   constexpr auto b = a < 3;
656   // CHECK: store <4 x i128> <i128 -1, i128 -1, i128 0, i128 0>
657 
658   // Operator ~ is illegal on floats, so no test for that.
659   constexpr auto c = ~FourI128VecSize{1, 2, 10, 20};
660   // CHECK: store <4 x i128> <i128 -2, i128 -3, i128 -11, i128 -21>
661 
662   constexpr auto d = !FourI128VecSize{0, 1, 8, -1};
663   // CHECK: store <4 x i128> <i128 -1, i128 0, i128 0, i128 0>
664 }
665 
I128VecUsage()666 void I128VecUsage() {
667   constexpr auto a = FourI128ExtVec{1, 2, 3, 4};
668   // CHECK: store <4 x i128> <i128 1, i128 2, i128 3, i128 4>
669   constexpr auto b = a < 3;
670   // CHECK: store <4 x i128> <i128 -1, i128 -1, i128 0, i128 0>
671 
672   // Operator ~ is illegal on floats, so no test for that.
673   constexpr auto c = ~FourI128ExtVec{1, 2, 10, 20};
674   // CHECK: store <4 x i128>  <i128 -2, i128 -3, i128 -11, i128 -21>
675 
676   constexpr auto d = !FourI128ExtVec{0, 1, 8, -1};
677   // CHECK: store <4 x i128>  <i128 -1, i128 0, i128 0, i128 0>
678 }
679 
680 using FourBoolsExtVec __attribute__((ext_vector_type(4))) = bool;
BoolVecUsage()681 void BoolVecUsage() {
682   constexpr auto a = FourBoolsExtVec{true, false, true, false} <
683                      FourBoolsExtVec{false, false, true, true};
684   // CHECK: store i8 bitcast (<8 x i1> <i1 false, i1 false, i1 false, i1 true, i1 undef, i1 undef, i1 undef, i1 undef> to i8), i8* %a, align 1
685   constexpr auto b = FourBoolsExtVec{true, false, true, false} <=
686                      FourBoolsExtVec{false, false, true, true};
687   // CHECK: store i8 bitcast (<8 x i1> <i1 false, i1 true, i1 true, i1 true, i1 undef, i1 undef, i1 undef, i1 undef> to i8), i8* %b, align 1
688   constexpr auto c = FourBoolsExtVec{true, false, true, false} ==
689                      FourBoolsExtVec{false, false, true, true};
690   // CHECK: store i8 bitcast (<8 x i1> <i1 false, i1 true, i1 true, i1 false, i1 undef, i1 undef, i1 undef, i1 undef> to i8), i8* %c, align 1
691   constexpr auto d = FourBoolsExtVec{true, false, true, false} !=
692                      FourBoolsExtVec{false, false, true, true};
693   // CHECK: store i8 bitcast (<8 x i1> <i1 true, i1 false, i1 false, i1 true, i1 undef, i1 undef, i1 undef, i1 undef> to i8), i8* %d, align 1
694   constexpr auto e = FourBoolsExtVec{true, false, true, false} >=
695                      FourBoolsExtVec{false, false, true, true};
696   // CHECK: store i8 bitcast (<8 x i1> <i1 true, i1 true, i1 true, i1 false, i1 undef, i1 undef, i1 undef, i1 undef> to i8), i8* %e, align 1
697   constexpr auto f = FourBoolsExtVec{true, false, true, false} >
698                      FourBoolsExtVec{false, false, true, true};
699   // CHECK: store i8 bitcast (<8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 undef, i1 undef, i1 undef, i1 undef> to i8), i8* %f, align 1
700   constexpr auto g = FourBoolsExtVec{true, false, true, false} &
701                      FourBoolsExtVec{false, false, true, true};
702   // CHECK: store i8 bitcast (<8 x i1> <i1 false, i1 false, i1 true, i1 false, i1 undef, i1 undef, i1 undef, i1 undef> to i8), i8* %g, align 1
703   constexpr auto h = FourBoolsExtVec{true, false, true, false} |
704                      FourBoolsExtVec{false, false, true, true};
705   // CHECK: store i8 bitcast (<8 x i1> <i1 true, i1 false, i1 true, i1 true, i1 undef, i1 undef, i1 undef, i1 undef> to i8), i8* %h, align 1
706   constexpr auto i = FourBoolsExtVec{true, false, true, false} ^
707                      FourBoolsExtVec { false, false, true, true };
708   // CHECK: store i8 bitcast (<8 x i1> <i1 true, i1 false, i1 false, i1 true, i1 undef, i1 undef, i1 undef, i1 undef> to i8), i8* %i, align 1
709   constexpr auto j = !FourBoolsExtVec{true, false, true, false};
710   // CHECK: store i8 bitcast (<8 x i1> <i1 false, i1 true, i1 false, i1 true, i1 undef, i1 undef, i1 undef, i1 undef> to i8), i8* %j, align 1
711   constexpr auto k = ~FourBoolsExtVec{true, false, true, false};
712   // CHECK: store i8 bitcast (<8 x i1> <i1 false, i1 true, i1 false, i1 true, i1 undef, i1 undef, i1 undef, i1 undef> to i8), i8* %k, align 1
713 }
714