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