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