xref: /llvm-project/clang/test/AST/ByteCode/constexpr-vectors.cpp (revision f5a65d8752f26245744ae3e1365cc3ac283c2638)
1 // RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++14 -fsyntax-only -verify
2 // RUN: %clang_cc1 %s -triple x86_64-linux-gnu -fexperimental-new-constant-interpreter -std=c++14 -fsyntax-only -verify
3 
4 using FourCharsVecSize __attribute__((vector_size(4))) = char;
5 using FourIntsVecSize __attribute__((vector_size(16))) = int;
6 using FourLongLongsVecSize __attribute__((vector_size(32))) = long long;
7 using FourFloatsVecSize __attribute__((vector_size(16))) = float;
8 using FourDoublesVecSize __attribute__((vector_size(32))) = double;
9 using FourI128VecSize __attribute__((vector_size(64))) = __int128;
10 
11 using FourCharsExtVec __attribute__((ext_vector_type(4))) = char;
12 using FourIntsExtVec __attribute__((ext_vector_type(4))) = int;
13 using FourLongLongsExtVec __attribute__((ext_vector_type(4))) = long long;
14 using FourFloatsExtVec __attribute__((ext_vector_type(4))) = float;
15 using FourDoublesExtVec __attribute__((ext_vector_type(4))) = double;
16 using FourI128ExtVec __attribute__((ext_vector_type(4))) = __int128;
17 
18 
19 // Next a series of tests to make sure these operations are usable in
20 // constexpr functions. Template instantiations don't emit Winvalid-constexpr,
21 // so we have to do these as macros.
22 #define MathShiftOps(Type)                            \
23   constexpr auto MathShiftOps##Type(Type a, Type b) { \
24     a = a + b;                                        \
25     a = a - b;                                        \
26     a = a * b;                                        \
27     a = a / b;                                        \
28     b = a + 1;                                        \
29     b = a - 1;                                        \
30     b = a * 1;                                        \
31     b = a / 1;                                        \
32     a += a;                                           \
33     a -= a;                                           \
34     a *= a;                                           \
35     a /= a;                                           \
36     b += a;                                           \
37     b -= a;                                           \
38     b *= a;                                           \
39     b /= a;                                           \
40     b = (a += a);                                     \
41     b = (a -= a);                                     \
42     b = (a *= a);                                     \
43     b = (a /= a);                                     \
44     b = (b += a);                                     \
45     b = (b -= a);                                     \
46     b = (b *= a);                                     \
47     b = (b /= a);                                     \
48     a < b;                                            \
49     a > b;                                            \
50     a <= b;                                           \
51     a >= b;                                           \
52     a == b;                                           \
53     a != b;                                           \
54     a &&b;                                            \
55     a || b;                                           \
56     auto c = (a, b);                                  \
57     return c;                                         \
58   }
59 
60 // Ops specific to Integers.
61 #define MathShiftOpsInts(Type)                            \
62   constexpr auto MathShiftopsInts##Type(Type a, Type b) { \
63     a = a << b;                                           \
64     a = a >> b;                                           \
65     a = a << 3;                                           \
66     a = a >> 3;                                           \
67     a = 3 << b;                                           \
68     a = 3 >> b;                                           \
69     a <<= b;                                              \
70     a >>= b;                                              \
71     a <<= 3;                                              \
72     a >>= 3;                                              \
73     b = (a <<= b);                                        \
74     b = (a >>= b);                                        \
75     b = (a <<= 3);                                        \
76     b = (a >>= 3);                                        \
77     a = a % b;                                            \
78     a &b;                                                 \
79     a | b;                                                \
80     a ^ b;                                                \
81     return a;                                             \
82   }
83 
84 MathShiftOps(FourCharsVecSize);
85 MathShiftOps(FourIntsVecSize);
86 MathShiftOps(FourLongLongsVecSize);
87 MathShiftOps(FourI128VecSize);
88 MathShiftOps(FourFloatsVecSize);
89 MathShiftOps(FourDoublesVecSize);
90 MathShiftOps(FourCharsExtVec);
91 MathShiftOps(FourIntsExtVec);
92 MathShiftOps(FourLongLongsExtVec);
93 MathShiftOps(FourI128ExtVec);
94 MathShiftOps(FourFloatsExtVec);
95 MathShiftOps(FourDoublesExtVec);
96 
97 MathShiftOpsInts(FourCharsVecSize);
98 MathShiftOpsInts(FourIntsVecSize);
99 MathShiftOpsInts(FourLongLongsVecSize);
100 MathShiftOpsInts(FourI128VecSize);
101 MathShiftOpsInts(FourCharsExtVec);
102 MathShiftOpsInts(FourIntsExtVec);
103 MathShiftOpsInts(FourLongLongsExtVec);
104 MathShiftOpsInts(FourI128ExtVec);
105 
106 template <typename T, typename U>
107 constexpr auto CmpMul(T t, U u) {
108   t *= u;
109   return t;
110 }
111 template <typename T, typename U>
112 constexpr auto CmpDiv(T t, U u) {
113   t /= u;
114   return t;
115 }
116 template <typename T, typename U>
117 constexpr auto CmpRem(T t, U u) {
118   t %= u;
119   return t;
120 }
121 
122 template <typename T, typename U>
123 constexpr auto CmpAdd(T t, U u) {
124   t += u;
125   return t;
126 }
127 
128 template <typename T, typename U>
129 constexpr auto CmpSub(T t, U u) {
130   t -= u;
131   return t;
132 }
133 
134 template <typename T, typename U>
135 constexpr auto CmpLSH(T t, U u) {
136   t <<= u;
137   return t;
138 }
139 
140 template <typename T, typename U>
141 constexpr auto CmpRSH(T t, U u) {
142   t >>= u;
143   return t;
144 }
145 
146 template <typename T, typename U>
147 constexpr auto CmpBinAnd(T t, U u) {
148   t &= u;
149   return t;
150 }
151 
152 template <typename T, typename U>
153 constexpr auto CmpBinXOr(T t, U u) {
154   t ^= u;
155   return t;
156 }
157 
158 template <typename T, typename U>
159 constexpr auto CmpBinOr(T t, U u) {
160   t |= u;
161   return t;
162 }
163 
164 constexpr auto CmpF(float t, float u) {
165   return __builtin_fabs(t - u) < 0.0001;
166 }
167 
168 // Only int vs float makes a difference here, so we only need to test 1 of each.
169 // Test Char to make sure the mixed-nature of shifts around char is evident.
170 void CharUsage() {
171   constexpr auto a = FourCharsVecSize{6, 3, 2, 1} +
172             FourCharsVecSize{12, 15, 5, 7};
173   static_assert(a[0] == 18 && a[1] == 18 && a[2] == 7 && a[3] == 8, "");
174 
175   constexpr auto b = FourCharsVecSize{19, 15, 13, 12} -
176                      FourCharsVecSize{13, 14, 5, 3};
177   static_assert(b[0] == 6 && b[1] == 1 && b[2] == 8 && b[3] == 9, "");
178 
179   constexpr auto c = FourCharsVecSize{8, 4, 2, 1} *
180                      FourCharsVecSize{3, 4, 5, 6};
181   static_assert(c[0] == 24 && c[1] == 16 && c[2] == 10 && c[3] == 6, "");
182 
183   constexpr auto d = FourCharsVecSize{12, 12, 10, 10} /
184                      FourCharsVecSize{6, 4, 5, 2};
185   static_assert(d[0] == 2 && d[1] == 3 && d[2] == 2 && d[3] == 5, "");
186 
187   constexpr auto e = FourCharsVecSize{12, 12, 10, 10} %
188                      FourCharsVecSize{6, 4, 4, 3};
189   static_assert(e[0] == 0 && e[1] == 0 && e[2] == 2 && e[3] == 1, "");
190 
191   constexpr auto f = FourCharsVecSize{6, 3, 2, 1} + 3;
192   static_assert(f[0] == 9 && f[1] == 6 && f[2] == 5 && f[3] == 4, "");
193 
194   constexpr auto g = FourCharsVecSize{19, 15, 12, 10} - 3;
195   static_assert(g[0] == 16 && g[1] == 12 && g[2] == 9 && g[3] == 7, "");
196 
197   constexpr auto h = FourCharsVecSize{8, 4, 2, 1} * 3;
198   static_assert(h[0] == 24 && h[1] == 12 && h[2] == 6 && h[3] == 3, "");
199 
200   constexpr auto j = FourCharsVecSize{12, 15, 18, 21} / 3;
201   static_assert(j[0] == 4 && j[1] == 5 && j[2] == 6 && j[3] == 7, "");
202 
203   constexpr auto k = FourCharsVecSize{12, 17, 19, 22} % 3;
204   static_assert(k[0] == 0 && k[1] == 2 && k[2] == 1 && k[3] == 1, "");
205 
206   constexpr auto l = 3 + FourCharsVecSize{6, 3, 2, 1};
207   static_assert(l[0] == 9 && l[1] == 6 && l[2] == 5 && l[3] == 4, "");
208 
209   constexpr auto m = 20 - FourCharsVecSize{19, 15, 12, 10};
210   static_assert(m[0] == 1 && m[1] == 5 && m[2] == 8 && m[3] == 10, "");
211 
212   constexpr auto n = 3 * FourCharsVecSize{8, 4, 2, 1};
213   static_assert(n[0] == 24 && n[1] == 12 && n[2] == 6 && n[3] == 3, "");
214 
215   constexpr auto o = 100 / FourCharsVecSize{12, 15, 18, 21};
216   static_assert(o[0] == 8 && o[1] == 6 && o[2] == 5 && o[3] == 4, "");
217 
218   constexpr auto p = 100 % FourCharsVecSize{12, 15, 18, 21};
219   static_assert(p[0] == 4 && p[1] == 10 && p[2] == 10 && p[3] == 16, "");
220 
221   constexpr auto q = FourCharsVecSize{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2};
222   static_assert(q[0] == 12 && q[1] == 6 && q[2] == 8 && q[3] == 4, "");
223 
224   constexpr auto r = FourCharsVecSize{19, 15, 12, 10} >>
225                      FourCharsVecSize{1, 1, 2, 2};
226   static_assert(r[0] == 9 && r[1] == 7 && r[2] == 3 && r[3] == 2, "");
227 
228   constexpr auto s = FourCharsVecSize{6, 3, 5, 10} << 1;
229   static_assert(s[0] == 12 && s[1] == 6 && s[2] == 10 && s[3] == 20, "");
230 
231   constexpr auto t = FourCharsVecSize{19, 15, 10, 20} >> 1;
232   static_assert(t[0] == 9 && t[1] == 7 && t[2] == 5 && t[3] == 10, "");
233 
234   constexpr auto u = 12 << FourCharsVecSize{1, 2, 3, 3};
235   static_assert(u[0] == 24 && u[1] == 48 && u[2] == 96 && u[3] == 96, "");
236 
237   constexpr auto v = 12 >> FourCharsVecSize{1, 2, 2, 1};
238   static_assert(v[0] == 6 && v[1] == 3 && v[2] == 3 && v[3] == 6, "");
239 
240   constexpr auto w = FourCharsVecSize{1, 2, 3, 4} <
241                      FourCharsVecSize{4, 3, 2, 1};
242   static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, "");
243 
244   constexpr auto x = FourCharsVecSize{1, 2, 3, 4} >
245                      FourCharsVecSize{4, 3, 2, 1};
246   static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[3] == -1, "");
247 
248   constexpr auto y = FourCharsVecSize{1, 2, 3, 4} <=
249                      FourCharsVecSize{4, 3, 3, 1};
250   static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, "");
251 
252   constexpr auto z = FourCharsVecSize{1, 2, 3, 4} >=
253                      FourCharsVecSize{4, 3, 3, 1};
254   static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, "");
255 
256   constexpr auto A = FourCharsVecSize{1, 2, 3, 4} ==
257                      FourCharsVecSize{4, 3, 3, 1};
258   static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, "");
259 
260   constexpr auto B = FourCharsVecSize{1, 2, 3, 4} !=
261                      FourCharsVecSize{4, 3, 3, 1};
262   static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, "");
263 
264   constexpr auto C = FourCharsVecSize{1, 2, 3, 4} < 3;
265   static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, "");
266 
267   constexpr auto D = FourCharsVecSize{1, 2, 3, 4} > 3;
268   static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, "");
269 
270   constexpr auto E = FourCharsVecSize{1, 2, 3, 4} <= 3;
271   static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, "");
272 
273   constexpr auto F = FourCharsVecSize{1, 2, 3, 4} >= 3;
274   static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, "");
275 
276   constexpr auto G = FourCharsVecSize{1, 2, 3, 4} == 3;
277   static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, "");
278 
279   constexpr auto H = FourCharsVecSize{1, 2, 3, 4} != 3;
280   static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, "");
281 
282   constexpr auto I = FourCharsVecSize{1, 2, 3, 4} &
283                      FourCharsVecSize{4, 3, 2, 1};
284   static_assert(I[0] == 0 && I[1] == 2 && I[2] == 2 && I[3] == 0, "");
285 
286   constexpr auto J = FourCharsVecSize{1, 2, 3, 4} ^
287                      FourCharsVecSize { 4, 3, 2, 1 };
288   static_assert(J[0] == 5 && J[1] == 1 && J[2] == 1 && J[3] == 5, "");
289 
290   constexpr auto K = FourCharsVecSize{1, 2, 3, 4} |
291                      FourCharsVecSize{4, 3, 2, 1};
292   static_assert(K[0] == 5 && K[1] == 3 && K[2] == 3 && K[3] == 5, "");
293 
294   constexpr auto L = FourCharsVecSize{1, 2, 3, 4} & 3;
295   static_assert(L[0] == 1 && L[1] == 2 && L[2] == 3 && L[3] == 0, "");
296 
297   constexpr auto M = FourCharsVecSize{1, 2, 3, 4} ^ 3;
298   static_assert(M[0] == 2 && M[1] == 1 && M[2] == 0 && M[3] == 7, "");
299 
300   constexpr auto N = FourCharsVecSize{1, 2, 3, 4} | 3;
301   static_assert(N[0] == 3 && N[1] == 3 && N[2] == 3 && N[3] == 7, "");
302 
303   constexpr auto O = FourCharsVecSize{5, 0, 6, 0} &&
304                      FourCharsVecSize{5, 5, 0, 0};
305   static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, "");
306 
307   constexpr auto P = FourCharsVecSize{5, 0, 6, 0} ||
308                      FourCharsVecSize{5, 5, 0, 0};
309   static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, "");
310 
311   constexpr auto Q = FourCharsVecSize{5, 0, 6, 0} && 3;
312   static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
313 
314   constexpr auto R = FourCharsVecSize{5, 0, 6, 0} || 3;
315   static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
316 
317   constexpr auto T = CmpMul(a, b);
318   static_assert(T[0] == 108 && T[1] == 18 && T[2] == 56 && T[3] == 72, "");
319 
320   constexpr auto U = CmpDiv(a, b);
321   static_assert(U[0] == 3 && U[1] == 18 && U[2] == 0 && U[3] == 0, "");
322 
323   constexpr auto V = CmpRem(a, b);
324   static_assert(V[0] == 0 && V[1] == 0 && V[2] == 7 && V[3] == 8, "");
325 
326   constexpr auto X = CmpAdd(a, b);
327   static_assert(X[0] == 24 && X[1] == 19 && X[2] == 15 && X[3] == 17, "");
328 
329   constexpr auto Y = CmpSub(a, b);
330   static_assert(Y[0] == 12 && Y[1] == 17 && Y[2] == -1 && Y[3] == -1, "");
331 
332   constexpr auto InvH = -H;
333   static_assert(InvH[0] == 1 && InvH[1] == 1 && InvH[2] == 0 && InvH[3] == 1, "");
334 
335   constexpr auto Z = CmpLSH(a, InvH);
336   static_assert(Z[0] == 36 && Z[1] == 36 && Z[2] == 7 && Z[3] == 16, "");
337 
338   constexpr auto aa = CmpRSH(a, InvH);
339   static_assert(aa[0] == 9 && aa[1] == 9 && aa[2] == 7 && aa[3] == 4, "");
340 
341   constexpr auto ab = CmpBinAnd(a, b);
342   static_assert(ab[0] == 2 && ab[1] == 0 && ab[2] == 0 && ab[3] == 8, "");
343 
344   constexpr auto ac = CmpBinXOr(a, b);
345   static_assert(ac[0] == 20 && ac[1] == 19 && ac[2] == 15 && ac[3] == 1, "");
346 
347   constexpr auto ad = CmpBinOr(a, b);
348   static_assert(ad[0] == 22 && ad[1] == 19 && ad[2] == 15 && ad[3] == 9, "");
349 
350   constexpr auto ae = ~FourCharsVecSize{1, 2, 10, 20};
351   static_assert(ae[0] == -2 && ae[1] == -3 && ae[2] == -11 && ae[3] == -21, "");
352 
353   constexpr auto af = !FourCharsVecSize{0, 1, 8, -1};
354   static_assert(af[0] == -1 && af[1] == 0 && af[2] == 0 && af[3] == 0, "");
355 }
356 
357 void CharExtVecUsage() {
358   constexpr auto a = FourCharsExtVec{6, 3, 2, 1} +
359                      FourCharsExtVec{12, 15, 5, 7};
360   static_assert(a[0] == 18 && a[1] == 18 && a[2] == 7 && a[3] == 8, "");
361 
362   constexpr auto b = FourCharsExtVec{19, 15, 13, 12} -
363                      FourCharsExtVec{13, 14, 5, 3};
364   static_assert(b[0] == 6 && b[1] == 1 && b[2] == 8 && b[3] == 9, "");
365 
366   constexpr auto c = FourCharsExtVec{8, 4, 2, 1} *
367                      FourCharsExtVec{3, 4, 5, 6};
368   static_assert(c[0] == 24 && c[1] == 16 && c[2] == 10 && c[3] == 6, "");
369 
370   constexpr auto d = FourCharsExtVec{12, 12, 10, 10} /
371                      FourCharsExtVec{6, 4, 5, 2};
372   static_assert(d[0] == 2 && d[1] == 3 && d[2] == 2 && d[3] == 5, "");
373 
374   constexpr auto e = FourCharsExtVec{12, 12, 10, 10} %
375                      FourCharsExtVec{6, 4, 4, 3};
376   static_assert(e[0] == 0 && e[1] == 0 && e[2] == 2 && e[3] == 1, "");
377 
378   constexpr auto f = FourCharsExtVec{6, 3, 2, 1} + 3;
379   static_assert(f[0] == 9 && f[1] == 6 && f[2] == 5 && f[3] == 4, "");
380 
381   constexpr auto g = FourCharsExtVec{19, 15, 12, 10} - 3;
382   static_assert(g[0] == 16 && g[1] == 12 && g[2] == 9 && g[3] == 7, "");
383 
384   constexpr auto h = FourCharsExtVec{8, 4, 2, 1} * 3;
385   static_assert(h[0] == 24 && h[1] == 12 && h[2] == 6 && h[3] == 3, "");
386 
387   constexpr auto j = FourCharsExtVec{12, 15, 18, 21} / 3;
388   static_assert(j[0] == 4 && j[1] == 5 && j[2] == 6 && j[3] == 7, "");
389 
390   constexpr auto k = FourCharsExtVec{12, 17, 19, 22} % 3;
391   static_assert(k[0] == 0 && k[1] == 2 && k[2] == 1 && k[3] == 1, "");
392 
393   constexpr auto l = 3 + FourCharsExtVec{6, 3, 2, 1};
394   static_assert(l[0] == 9 && l[1] == 6 && l[2] == 5 && l[3] == 4, "");
395 
396   constexpr auto m = 20 - FourCharsExtVec{19, 15, 12, 10};
397   static_assert(m[0] == 1 && m[1] == 5 && m[2] == 8 && m[3] == 10, "");
398 
399   constexpr auto n = 3 * FourCharsExtVec{8, 4, 2, 1};
400   static_assert(n[0] == 24 && n[1] == 12 && n[2] == 6 && n[3] == 3, "");
401 
402   constexpr auto o = 100 / FourCharsExtVec{12, 15, 18, 21};
403   static_assert(o[0] == 8 && o[1] == 6 && o[2] == 5 && o[3] == 4, "");
404 
405   constexpr auto p = 100 % FourCharsExtVec{12, 15, 18, 21};
406   static_assert(p[0] == 4 && p[1] == 10 && p[2] == 10 && p[3] == 16, "");
407 
408   constexpr auto q = FourCharsExtVec{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2};
409   static_assert(q[0] == 12 && q[1] == 6 && q[2] == 8 && q[3] == 4, "");
410 
411   constexpr auto r = FourCharsExtVec{19, 15, 12, 10} >>
412                      FourCharsExtVec{1, 1, 2, 2};
413   static_assert(r[0] == 9 && r[1] == 7 && r[2] == 3 && r[3] == 2, "");
414 
415   constexpr auto s = FourCharsExtVec{6, 3, 5, 10} << 1;
416   static_assert(s[0] == 12 && s[1] == 6 && s[2] == 10 && s[3] == 20, "");
417 
418   constexpr auto t = FourCharsExtVec{19, 15, 10, 20} >> 1;
419   static_assert(t[0] == 9 && t[1] == 7 && t[2] == 5 && t[3] == 10, "");
420 
421   constexpr auto u = 12 << FourCharsExtVec{1, 2, 3, 3};
422   static_assert(u[0] == 24 && u[1] == 48 && u[2] == 96 && u[3] == 96, "");
423 
424   constexpr auto v = 12 >> FourCharsExtVec{1, 2, 2, 1};
425   static_assert(v[0] == 6 && v[1] == 3 && v[2] == 3 && v[3] == 6, "");
426 
427   constexpr auto w = FourCharsExtVec{1, 2, 3, 4} <
428                      FourCharsExtVec{4, 3, 2, 1};
429   static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, "");
430 
431   constexpr auto x = FourCharsExtVec{1, 2, 3, 4} >
432                      FourCharsExtVec{4, 3, 2, 1};
433   static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[3] == -1, "");
434 
435   constexpr auto y = FourCharsExtVec{1, 2, 3, 4} <=
436                      FourCharsExtVec{4, 3, 3, 1};
437   static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, "");
438 
439   constexpr auto z = FourCharsExtVec{1, 2, 3, 4} >=
440                      FourCharsExtVec{4, 3, 3, 1};
441   static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, "");
442 
443   constexpr auto A = FourCharsExtVec{1, 2, 3, 4} ==
444                      FourCharsExtVec{4, 3, 3, 1};
445   static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, "");
446 
447   constexpr auto B = FourCharsExtVec{1, 2, 3, 4} !=
448                      FourCharsExtVec{4, 3, 3, 1};
449   static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, "");
450 
451   constexpr auto C = FourCharsExtVec{1, 2, 3, 4} < 3;
452   static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, "");
453 
454   constexpr auto D = FourCharsExtVec{1, 2, 3, 4} > 3;
455   static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, "");
456 
457   constexpr auto E = FourCharsExtVec{1, 2, 3, 4} <= 3;
458   static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, "");
459 
460   constexpr auto F = FourCharsExtVec{1, 2, 3, 4} >= 3;
461   static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, "");
462 
463   constexpr auto G = FourCharsExtVec{1, 2, 3, 4} == 3;
464   static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, "");
465 
466   constexpr auto H = FourCharsExtVec{1, 2, 3, 4} != 3;
467   static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, "");
468 
469   constexpr auto I = FourCharsExtVec{1, 2, 3, 4} &
470                      FourCharsExtVec{4, 3, 2, 1};
471   static_assert(I[0] == 0 && I[1] == 2 && I[2] == 2 && I[3] == 0, "");
472 
473   constexpr auto J = FourCharsExtVec{1, 2, 3, 4} ^
474                      FourCharsExtVec { 4, 3, 2, 1 };
475   static_assert(J[0] == 5 && J[1] == 1 && J[2] == 1 && J[3] == 5, "");
476 
477   constexpr auto K = FourCharsExtVec{1, 2, 3, 4} |
478                      FourCharsExtVec{4, 3, 2, 1};
479   static_assert(K[0] == 5 && K[1] == 3 && K[2] == 3 && K[3] == 5, "");
480 
481   constexpr auto L = FourCharsExtVec{1, 2, 3, 4} & 3;
482   static_assert(L[0] == 1 && L[1] == 2 && L[2] == 3 && L[3] == 0, "");
483 
484   constexpr auto M = FourCharsExtVec{1, 2, 3, 4} ^ 3;
485   static_assert(M[0] == 2 && M[1] == 1 && M[2] == 0 && M[3] == 7, "");
486 
487   constexpr auto N = FourCharsExtVec{1, 2, 3, 4} | 3;
488   static_assert(N[0] == 3 && N[1] == 3 && N[2] == 3 && N[3] == 7, "");
489 
490   constexpr auto O = FourCharsExtVec{5, 0, 6, 0} &&
491                      FourCharsExtVec{5, 5, 0, 0};
492   static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, "");
493 
494   constexpr auto P = FourCharsExtVec{5, 0, 6, 0} ||
495                      FourCharsExtVec{5, 5, 0, 0};
496   static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, "");
497 
498   constexpr auto Q = FourCharsExtVec{5, 0, 6, 0} && 3;
499   static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
500 
501   constexpr auto R = FourCharsExtVec{5, 0, 6, 0} || 3;
502   static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
503 
504   constexpr auto T = CmpMul(a, b);
505   static_assert(T[0] == 108 && T[1] == 18 && T[2] == 56 && T[3] == 72, "");
506 
507   constexpr auto U = CmpDiv(a, b);
508   static_assert(U[0] == 3 && U[1] == 18 && U[2] == 0 && U[3] == 0, "");
509 
510   constexpr auto V = CmpRem(a, b);
511   static_assert(V[0] == 0 && V[1] == 0 && V[2] == 7 && V[3] == 8, "");
512 
513   constexpr auto X = CmpAdd(a, b);
514   static_assert(X[0] == 24 && X[1] == 19 && X[2] == 15 && X[3] == 17, "");
515 
516   constexpr auto Y = CmpSub(a, b);
517   static_assert(Y[0] == 12 && Y[1] == 17 && Y[2] == -1 && Y[3] == -1, "");
518 
519   constexpr auto InvH = -H;
520   static_assert(InvH[0] == 1 && InvH[1] == 1 && InvH[2] == 0 && InvH[3] == 1, "");
521 
522   constexpr auto Z = CmpLSH(a, InvH);
523   static_assert(Z[0] == 36 && Z[1] == 36 && Z[2] == 7 && Z[3] == 16, "");
524 
525   constexpr auto aa = CmpRSH(a, InvH);
526   static_assert(aa[0] == 9 && aa[1] == 9 && aa[2] == 7 && aa[3] == 4, "");
527 
528   constexpr auto ab = CmpBinAnd(a, b);
529   static_assert(ab[0] == 2 && ab[1] == 0 && ab[2] == 0 && ab[3] == 8, "");
530 
531   constexpr auto ac = CmpBinXOr(a, b);
532   static_assert(ac[0] == 20 && ac[1] == 19 && ac[2] == 15 && ac[3] == 1, "");
533 
534   constexpr auto ad = CmpBinOr(a, b);
535   static_assert(ad[0] == 22 && ad[1] == 19 && ad[2] == 15 && ad[3] == 9, "");
536 
537   constexpr auto ae = ~FourCharsExtVec{1, 2, 10, 20};
538   static_assert(ae[0] == -2 && ae[1] == -3 && ae[2] == -11 && ae[3] == -21, "");
539 
540   constexpr auto af = !FourCharsExtVec{0, 1, 8, -1};
541   static_assert(af[0] == -1 && af[1] == 0 && af[2] == 0 && af[3] == 0, "");
542 }
543 
544 void FloatUsage() {
545   constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} +
546                      FourFloatsVecSize{12, 15, 5, 7};
547   static_assert(a[0] == 1.800000e+01 && a[1] == 1.800000e+01 && a[2] == 7.000000e+00 && a[3] == 8.000000e+00, "");
548 
549   constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} -
550                      FourFloatsVecSize{13, 14, 5, 3};
551   static_assert(b[0] == 6.000000e+00 && b[1] == 1.000000e+00 && b[2] == 8.000000e+00 && b[3] == 9.000000e+00, "");
552 
553   constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} *
554                      FourFloatsVecSize{3, 4, 5, 6};
555   static_assert(c[0] == 2.400000e+01 && c[1] == 1.600000e+01 && c[2] == 1.000000e+01 && c[3] == 6.000000e+00, "");
556 
557   constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} /
558                      FourFloatsVecSize{6, 4, 5, 2};
559   static_assert(d[0] == 2.000000e+00 && d[1] == 3.000000e+00 && d[2] == 2.000000e+00 && d[3] == 5.000000e+00, "");
560 
561   constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3;
562   static_assert(f[0] == 9.000000e+00 && f[1] == 6.000000e+00 && f[2] == 5.000000e+00 && f[3] == 4.000000e+00, "");
563 
564   constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3;
565   static_assert(g[0] == 1.600000e+01 && g[1] == 1.200000e+01 && g[2] == 9.000000e+00 && g[3] == 7.000000e+00, "");
566 
567   constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3;
568   static_assert(h[0] == 2.400000e+01 && h[1] == 1.200000e+01 && h[2] == 6.000000e+00 && h[3] == 3.000000e+00, "");
569 
570   constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3;
571   static_assert(j[0] == 4.000000e+00 && j[1] == 5.000000e+00 && j[2] == 6.000000e+00 && j[3] == 7.000000e+00, "");
572 
573   constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1};
574   static_assert(l[0] == 9.000000e+00 && l[1] == 6.000000e+00 && l[2] == 5.000000e+00 && l[3] == 4.000000e+00, "");
575 
576   constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10};
577   static_assert(m[0] == 1.000000e+00 && m[1] == 5.000000e+00 && m[2] == 8.000000e+00 && m[3] == 1.000000e+01, "");
578 
579   constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1};
580   static_assert(n[0] == 2.400000e+01 && n[1] == 1.200000e+01 && n[2] == 6.000000e+00 && n[3] == 3.000000e+00, "");
581 
582   constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21};
583   static_assert(CmpF(o[0], 100.0 / 12) && CmpF(o[1], 100.0 / 15) && CmpF(o[2], 100.0 / 18) && CmpF(o[3], 100.0 / 21), "");
584 
585   constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} <
586                      FourFloatsVecSize{4, 3, 2, 1};
587   static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, "");
588 
589   constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} >
590                      FourFloatsVecSize{4, 3, 2, 1};
591   static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[3] == -1, "");
592 
593   constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <=
594                      FourFloatsVecSize{4, 3, 3, 1};
595   static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, "");
596 
597   constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >=
598                      FourFloatsVecSize{4, 3, 3, 1};
599   static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, "");
600 
601   constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} ==
602                      FourFloatsVecSize{4, 3, 3, 1};
603   static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, "");
604 
605   constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} !=
606                      FourFloatsVecSize{4, 3, 3, 1};
607   static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, "");
608 
609   constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3;
610   static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, "");
611 
612   constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3;
613   static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, "");
614 
615   constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3;
616   static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, "");
617 
618   constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3;
619   static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, "");
620 
621   constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3;
622   static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, "");
623 
624   constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3;
625   static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, "");
626 
627   constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} &&
628                      FourFloatsVecSize{5, 5, 0, 0};
629   static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, "");
630 
631   constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} ||
632                      FourFloatsVecSize{5, 5, 0, 0};
633   static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, "");
634 
635   constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3;
636   static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
637 
638   constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3;
639   static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
640 
641   constexpr auto T = CmpMul(a, b);
642   static_assert(T[0] == 1.080000e+02 && T[1] == 1.800000e+01 && T[2] == 5.600000e+01 && T[3] == 7.200000e+01, "");
643 
644   constexpr auto U = CmpDiv(a, b);
645   static_assert(CmpF(U[0], a[0] / b[0]) && CmpF(U[1], a[1] / b[1]) && CmpF(U[2], a[2] / b[2]) && CmpF(U[3], a[3] / b[3]), "");
646 
647   constexpr auto X = CmpAdd(a, b);
648   static_assert(X[0] == 2.400000e+01 && X[1] == 1.900000e+01 && X[2] == 1.500000e+01 && X[3] == 1.700000e+01, "");
649 
650   constexpr auto Y = CmpSub(a, b);
651   static_assert(Y[0] == 1.200000e+01 && Y[1] == 1.700000e+01 && Y[2] == -1.000000e+00 && Y[3] == -1.000000e+00, "");
652 
653   constexpr auto Z = -Y;
654   static_assert(Z[0] == -1.200000e+01 && Z[1] == -1.700000e+01 && Z[2] == 1.000000e+00 && Z[3] == 1.000000e+00, "");
655 
656   // Operator ~ is illegal on floats.
657   constexpr auto ae = ~FourFloatsVecSize{0, 1, 8, -1}; // expected-error {{invalid argument type}}
658 
659   constexpr auto af = !FourFloatsVecSize{0, 1, 8, -1};
660   static_assert(af[0] == -1 && af[1] == 0 && af[2] == 0 && af[3] == 0, "");
661 }
662 
663 void FloatVecUsage() {
664   constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} +
665                      FourFloatsVecSize{12, 15, 5, 7};
666   static_assert(a[0] == 1.800000e+01 && a[1] == 1.800000e+01 && a[2] == 7.000000e+00 && a[3] == 8.000000e+00, "");
667 
668   constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} -
669                      FourFloatsVecSize{13, 14, 5, 3};
670   static_assert(b[0] == 6.000000e+00 && b[1] == 1.000000e+00 && b[2] == 8.000000e+00 && b[3] == 9.000000e+00, "");
671 
672   constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} *
673                      FourFloatsVecSize{3, 4, 5, 6};
674   static_assert(c[0] == 2.400000e+01 && c[1] == 1.600000e+01 && c[2] == 1.000000e+01 && c[3] == 6.000000e+00, "");
675 
676   constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} /
677                      FourFloatsVecSize{6, 4, 5, 2};
678   static_assert(d[0] == 2.000000e+00 && d[1] == 3.000000e+00 && d[2] == 2.000000e+00 && d[3] == 5.000000e+00, "");
679 
680   constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3;
681   static_assert(f[0] == 9.000000e+00 && f[1] == 6.000000e+00 && f[2] == 5.000000e+00 && f[3] == 4.000000e+00, "");
682 
683   constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3;
684   static_assert(g[0] == 1.600000e+01 && g[1] == 1.200000e+01 && g[2] == 9.000000e+00 && g[3] == 7.000000e+00, "");
685 
686   constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3;
687   static_assert(h[0] == 2.400000e+01 && h[1] == 1.200000e+01 && h[2] == 6.000000e+00 && h[3] == 3.000000e+00, "");
688 
689   constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3;
690   static_assert(j[0] == 4.000000e+00 && j[1] == 5.000000e+00 && j[2] == 6.000000e+00 && j[3] == 7.000000e+00, "");
691 
692   constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1};
693   static_assert(l[0] == 9.000000e+00 && l[1] == 6.000000e+00 && l[2] == 5.000000e+00 && l[3] == 4.000000e+00, "");
694 
695   constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10};
696   static_assert(m[0] == 1.000000e+00 && m[1] == 5.000000e+00 && m[2] == 8.000000e+00 && m[3] == 1.000000e+01, "");
697 
698   constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1};
699   static_assert(n[0] == 2.400000e+01 && n[1] == 1.200000e+01 && n[2] == 6.000000e+00 && n[3] == 3.000000e+00, "");
700 
701   constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21};
702   static_assert(CmpF(o[0], 100.0 / 12) && CmpF(o[1], 100.0 / 15) && CmpF(o[2], 100.0 / 18) && CmpF(o[3], 100.0 / 21), "");
703 
704   constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} <
705                      FourFloatsVecSize{4, 3, 2, 1};
706   static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, "");
707 
708   constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} >
709                      FourFloatsVecSize{4, 3, 2, 1};
710   static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[2] == -1, "");
711 
712   constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <=
713                      FourFloatsVecSize{4, 3, 3, 1};
714   static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, "");
715 
716   constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >=
717                      FourFloatsVecSize{4, 3, 3, 1};
718   static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, "");
719 
720   constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} ==
721                      FourFloatsVecSize{4, 3, 3, 1};
722   static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, "");
723 
724   constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} !=
725                      FourFloatsVecSize{4, 3, 3, 1};
726   static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, "");
727 
728   constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3;
729   static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, "");
730 
731   constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3;
732   static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, "");
733 
734   constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3;
735   static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, "");
736 
737   constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3;
738   static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, "");
739 
740   constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3;
741   static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, "");
742 
743   constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3;
744   static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, "");
745 
746   constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} &&
747                      FourFloatsVecSize{5, 5, 0, 0};
748   static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, "");
749 
750   constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} ||
751                      FourFloatsVecSize{5, 5, 0, 0};
752   static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, "");
753 
754   constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3;
755   static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
756 
757   constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3;
758   static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
759 
760   constexpr auto T = CmpMul(a, b);
761   static_assert(T[0] == 1.080000e+02 && T[1] == 1.800000e+01 && T[2] == 5.600000e+01 && T[3] == 7.200000e+01, "");
762 
763   constexpr auto U = CmpDiv(a, b);
764   static_assert(CmpF(U[0], a[0] / b[0]) && CmpF(U[1], a[1] / b[1]) && CmpF(U[2], a[2] / b[2]) && CmpF(U[3], a[3] / b[3]), "");
765 
766   constexpr auto X = CmpAdd(a, b);
767   static_assert(X[0] == 2.400000e+01 && X[1] == 1.900000e+01 && X[2] == 1.500000e+01 && X[3] == 1.700000e+01, "");
768 
769   constexpr auto Y = CmpSub(a, b);
770   static_assert(Y[0] == 1.200000e+01 && Y[1] == 1.700000e+01 && Y[2] == -1.000000e+00 && Y[3] == -1.000000e+00, "");
771 
772   constexpr auto Z = -Y;
773   static_assert(Z[0] == -1.200000e+01 && Z[1] == -1.700000e+01 && Z[2] == 1.000000e+00 && Z[3] == 1.000000e+00, "");
774 
775   // Operator ~ is illegal on floats.
776   constexpr auto ae = ~FourFloatsVecSize{0, 1, 8, -1}; // expected-error {{invalid argument type}}
777 
778   constexpr auto af = !FourFloatsVecSize{0, 1, 8, -1};
779   static_assert(af[0] == -1 && af[1] == 0 && af[2] == 0 && af[3] == 0, "");
780 }
781 
782 void I128Usage() {
783   constexpr auto a = FourI128VecSize{1, 2, 3, 4};
784   static_assert(a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4, "");
785 
786   constexpr auto a1 = FourI128VecSize{5, 0, 6, 0} && FourI128VecSize{5, 5, 0, 0};
787   static_assert(a1[0] == 1 && a1[1] == 0 && a1[2] == 0 && a1[3] == 0, "");
788 
789   constexpr auto a2 = FourI128VecSize{5, 0, 6, 0} || FourI128VecSize{5, 5, 0, 0};
790   static_assert(a2[0] == 1 && a2[1] == 1 && a2[2] == 1 && a2[3] == 0, "");
791 
792   constexpr auto Q = FourI128VecSize{5, 0, 6, 0} && 3;
793   static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
794 
795   constexpr auto R = FourI128VecSize{5, 0, 6, 0} || 3;
796   static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
797 
798   constexpr auto b = a < 3;
799   static_assert(b[0] == -1 && b[1] == -1 && b[2] == 0 && b[3] == 0, "");
800 
801   constexpr auto c = ~FourI128VecSize{1, 2, 10, 20};
802   static_assert(c[0] == -2 && c[1] == -3 && c[2] == -11 && c[3] == -21, "");
803 
804   constexpr auto d = !FourI128VecSize{0, 1, 8, -1};
805   static_assert(d[0] == -1 && d[1] == 0 && d[2] == 0 && d[3] == 0, "");
806 }
807 
808 void I128VecUsage() {
809   constexpr auto a = FourI128ExtVec{1, 2, 3, 4};
810   static_assert(a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4, "");
811 
812   constexpr auto a1 = FourI128ExtVec{5, 0, 6, 0} && FourI128ExtVec{5, 5, 0, 0};
813   static_assert(a1[0] == 1 && a1[1] == 0 && a1[2] == 0 && a1[3] == 0, "");
814 
815   constexpr auto a2 = FourI128ExtVec{5, 0, 6, 0} || FourI128ExtVec{5, 5, 0, 0};
816   static_assert(a2[0] == 1 && a2[1] == 1 && a2[2] == 1 && a2[3] == 0, "");
817 
818   constexpr auto Q = FourI128ExtVec{5, 0, 6, 0} && 3;
819   static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
820 
821   constexpr auto R = FourI128ExtVec{5, 0, 6, 0} || 3;
822   static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
823 
824   constexpr auto b = a < 3;
825   static_assert(b[0] == -1 && b[1] == -1 && b[2] == 0 && b[3] == 0, "");
826 
827   constexpr auto c = ~FourI128ExtVec{1, 2, 10, 20};
828   static_assert(c[0] == -2 && c[1] == -3 && c[2] == -11 && c[3] == -21, "");
829 
830   constexpr auto d = !FourI128ExtVec{0, 1, 8, -1};
831   static_assert(d[0] == -1 && d[1] == 0 && d[2] == 0 && d[3] == 0, "");
832 }
833 
834 using FourBoolsExtVec __attribute__((ext_vector_type(4))) = bool;
835 void BoolVecUsage() {
836   constexpr auto a = FourBoolsExtVec{true, false, true, false} <
837                      FourBoolsExtVec{false, false, true, true};
838   static_assert(a[0] == false && a[1] == false && a[2] == false && a[3] == true, "");
839 
840   constexpr auto b = FourBoolsExtVec{true, false, true, false} <=
841                      FourBoolsExtVec{false, false, true, true};
842   static_assert(b[0] == false && b[1] == true && b[2] == true && b[3] == true, "");
843 
844   constexpr auto c = FourBoolsExtVec{true, false, true, false} ==
845                      FourBoolsExtVec{false, false, true, true};
846   static_assert(c[0] == false && c[1] == true && c[2] == true && c[3] == false, "");
847 
848   constexpr auto d = FourBoolsExtVec{true, false, true, false} !=
849                      FourBoolsExtVec{false, false, true, true};
850   static_assert(d[0] == true && d[1] == false && d[2] == false && d[3] == true, "");
851 
852   constexpr auto e = FourBoolsExtVec{true, false, true, false} >=
853                      FourBoolsExtVec{false, false, true, true};
854   static_assert(e[0] == true && e[1] == true && e[2] == true && e[3] == false, "");
855 
856   constexpr auto f = FourBoolsExtVec{true, false, true, false} >
857                      FourBoolsExtVec{false, false, true, true};
858   static_assert(f[0] == true && f[1] == false && f[2] == false && f[3] == false, "");
859 
860   constexpr auto g = FourBoolsExtVec{true, false, true, false} &
861                      FourBoolsExtVec{false, false, true, true};
862   static_assert(g[0] == false && g[1] == false && g[2] == true && g[3] == false, "");
863 
864   constexpr auto h = FourBoolsExtVec{true, false, true, false} |
865                      FourBoolsExtVec{false, false, true, true};
866   static_assert(h[0] == true && h[1] == false && h[2] == true && h[3] == true, "");
867 
868   constexpr auto i = FourBoolsExtVec{true, false, true, false} ^
869                      FourBoolsExtVec { false, false, true, true };
870   static_assert(i[0] == true && i[1] == false && i[2] == false && i[3] == true, "");
871 
872   constexpr auto j = !FourBoolsExtVec{true, false, true, false};
873   static_assert(j[0] == false && j[1] == true && j[2] == false && j[3] == true, "");
874 
875   constexpr auto k = ~FourBoolsExtVec{true, false, true, false};
876   static_assert(k[0] == false && k[1] == true && k[2] == false && k[3] == true, "");
877 }
878