--- /dev/null
+// RUN: %clang_cc1 -std=c++14 -Wno-unused-value %s -disable-llvm-passes -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
+
+// FIXME: Unfortunately there is no good way to validate that our values are
+// correct since Vector types don't have operator [] implemented for constexpr.
+// Instead, we need to use filecheck to ensure the emitted IR is correct. Once
+// someone implements array subscript operator for these types as constexpr,
+// this test should modified to jsut use static asserts.
+
+using FourCharsVecSize __attribute__((vector_size(4))) = char;
+using FourIntsVecSize __attribute__((vector_size(16))) = int;
+using FourLongLongsVecSize __attribute__((vector_size(32))) = long long;
+using FourFloatsVecSize __attribute__((vector_size(16))) = float;
+using FourDoublesVecSize __attribute__((vector_size(32))) = double;
+
+using FourCharsExtVec __attribute__((ext_vector_type(4))) = char;
+using FourIntsExtVec __attribute__((ext_vector_type(4))) = int;
+using FourLongLongsExtVec __attribute__((ext_vector_type(4))) = long long;
+using FourFloatsExtVec __attribute__((ext_vector_type(4))) = float;
+using FourDoublesExtVec __attribute__((ext_vector_type(4))) = double;
+
+// Next a series of tests to make sure these operations are usable in
+// constexpr functions. Template instantiations don't emit Winvalid-constexpr,
+// so we have to do these as macros.
+#define MathShiftOps(Type) \
+ constexpr auto MathShiftOps##Type(Type a, Type b) { \
+ a = a + b; \
+ a = a - b; \
+ a = a * b; \
+ a = a / b; \
+ b = a + 1; \
+ b = a - 1; \
+ b = a * 1; \
+ b = a / 1; \
+ a += a; \
+ a -= a; \
+ a *= a; \
+ a /= a; \
+ b += a; \
+ b -= a; \
+ b *= a; \
+ b /= a; \
+ a < b; \
+ a > b; \
+ a <= b; \
+ a >= b; \
+ a == b; \
+ a != b; \
+ a &&b; \
+ a || b; \
+ auto c = (a, b); \
+ return c; \
+ }
+
+// Ops specific to Integers.
+#define MathShiftOpsInts(Type) \
+ constexpr auto MathShiftopsInts##Type(Type a, Type b) { \
+ a = a << b; \
+ a = a >> b; \
+ a = a << 3; \
+ a = a >> 3; \
+ a = 3 << b; \
+ a = 3 >> b; \
+ a <<= b; \
+ a >>= b; \
+ a <<= 3; \
+ a >>= 3; \
+ a = a % b; \
+ a &b; \
+ a | b; \
+ a ^ b; \
+ return a; \
+ }
+
+MathShiftOps(FourCharsVecSize);
+MathShiftOps(FourIntsVecSize);
+MathShiftOps(FourLongLongsVecSize);
+MathShiftOps(FourFloatsVecSize);
+MathShiftOps(FourDoublesVecSize);
+MathShiftOps(FourCharsExtVec);
+MathShiftOps(FourIntsExtVec);
+MathShiftOps(FourLongLongsExtVec);
+MathShiftOps(FourFloatsExtVec);
+MathShiftOps(FourDoublesExtVec);
+
+MathShiftOpsInts(FourCharsVecSize);
+MathShiftOpsInts(FourIntsVecSize);
+MathShiftOpsInts(FourLongLongsVecSize);
+MathShiftOpsInts(FourCharsExtVec);
+MathShiftOpsInts(FourIntsExtVec);
+MathShiftOpsInts(FourLongLongsExtVec);
+
+template <typename T, typename U>
+constexpr auto CmpMul(T t, U u) {
+ t *= u;
+ return t;
+}
+template <typename T, typename U>
+constexpr auto CmpDiv(T t, U u) {
+ t /= u;
+ return t;
+}
+template <typename T, typename U>
+constexpr auto CmpRem(T t, U u) {
+ t %= u;
+ return t;
+}
+
+template <typename T, typename U>
+constexpr auto CmpAdd(T t, U u) {
+ t += u;
+ return t;
+}
+
+template <typename T, typename U>
+constexpr auto CmpSub(T t, U u) {
+ t -= u;
+ return t;
+}
+
+template <typename T, typename U>
+constexpr auto CmpLSH(T t, U u) {
+ t <<= u;
+ return t;
+}
+
+template <typename T, typename U>
+constexpr auto CmpRSH(T t, U u) {
+ t >>= u;
+ return t;
+}
+
+template <typename T, typename U>
+constexpr auto CmpBinAnd(T t, U u) {
+ t &= u;
+ return t;
+}
+
+template <typename T, typename U>
+constexpr auto CmpBinXOr(T t, U u) {
+ t ^= u;
+ return t;
+}
+
+template <typename T, typename U>
+constexpr auto CmpBinOr(T t, U u) {
+ t |= u;
+ return t;
+}
+
+// Only int vs float makes a difference here, so we only need to test 1 of each.
+// Test Char to make sure the mixed-nature of shifts around char is evident.
+void CharUsage() {
+ constexpr auto a = FourCharsVecSize{6, 3, 2, 1} +
+ FourCharsVecSize{12, 15, 5, 7};
+ // CHECK: store <4 x i8> <i8 18, i8 18, i8 7, i8 8>
+ constexpr auto b = FourCharsVecSize{19, 15, 13, 12} -
+ FourCharsVecSize{13, 14, 5, 3};
+ // CHECK: store <4 x i8> <i8 6, i8 1, i8 8, i8 9>
+ constexpr auto c = FourCharsVecSize{8, 4, 2, 1} *
+ FourCharsVecSize{3, 4, 5, 6};
+ // CHECK: store <4 x i8> <i8 24, i8 16, i8 10, i8 6>
+ constexpr auto d = FourCharsVecSize{12, 12, 10, 10} /
+ FourCharsVecSize{6, 4, 5, 2};
+ // CHECK: store <4 x i8> <i8 2, i8 3, i8 2, i8 5>
+ constexpr auto e = FourCharsVecSize{12, 12, 10, 10} %
+ FourCharsVecSize{6, 4, 4, 3};
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 2, i8 1>
+
+ constexpr auto f = FourCharsVecSize{6, 3, 2, 1} + 3;
+ // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4>
+ constexpr auto g = FourCharsVecSize{19, 15, 12, 10} - 3;
+ // CHECK: store <4 x i8> <i8 16, i8 12, i8 9, i8 7>
+ constexpr auto h = FourCharsVecSize{8, 4, 2, 1} * 3;
+ // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3>
+ constexpr auto j = FourCharsVecSize{12, 15, 18, 21} / 3;
+ // CHECK: store <4 x i8> <i8 4, i8 5, i8 6, i8 7>
+ constexpr auto k = FourCharsVecSize{12, 17, 19, 22} % 3;
+ // CHECK: store <4 x i8> <i8 0, i8 2, i8 1, i8 1>
+
+ constexpr auto l = 3 + FourCharsVecSize{6, 3, 2, 1};
+ // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4>
+ constexpr auto m = 20 - FourCharsVecSize{19, 15, 12, 10};
+ // CHECK: store <4 x i8> <i8 1, i8 5, i8 8, i8 10>
+ constexpr auto n = 3 * FourCharsVecSize{8, 4, 2, 1};
+ // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3>
+ constexpr auto o = 100 / FourCharsVecSize{12, 15, 18, 21};
+ // CHECK: store <4 x i8> <i8 8, i8 6, i8 5, i8 4>
+ constexpr auto p = 100 % FourCharsVecSize{12, 15, 18, 21};
+ // CHECK: store <4 x i8> <i8 4, i8 10, i8 10, i8 16>
+
+ constexpr auto q = FourCharsVecSize{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2};
+ // CHECK: store <4 x i8> <i8 12, i8 6, i8 8, i8 4>
+ constexpr auto r = FourCharsVecSize{19, 15, 12, 10} >>
+ FourCharsVecSize{1, 1, 2, 2};
+ // CHECK: store <4 x i8> <i8 9, i8 7, i8 3, i8 2>
+ constexpr auto s = FourCharsVecSize{6, 3, 5, 10} << 1;
+ // CHECK: store <4 x i8> <i8 12, i8 6, i8 10, i8 20>
+ constexpr auto t = FourCharsVecSize{19, 15, 10, 20} >> 1;
+ // CHECK: store <4 x i8> <i8 9, i8 7, i8 5, i8 10>
+ constexpr auto u = 12 << FourCharsVecSize{1, 2, 3, 3};
+ // CHECK: store <4 x i8> <i8 24, i8 48, i8 96, i8 96>
+ constexpr auto v = 12 >> FourCharsVecSize{1, 2, 2, 1};
+ // CHECK: store <4 x i8> <i8 6, i8 3, i8 3, i8 6>
+
+ constexpr auto w = FourCharsVecSize{1, 2, 3, 4} <
+ FourCharsVecSize{4, 3, 2, 1};
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 0>
+ constexpr auto x = FourCharsVecSize{1, 2, 3, 4} >
+ FourCharsVecSize{4, 3, 2, 1};
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ constexpr auto y = FourCharsVecSize{1, 2, 3, 4} <=
+ FourCharsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
+ constexpr auto z = FourCharsVecSize{1, 2, 3, 4} >=
+ FourCharsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ constexpr auto A = FourCharsVecSize{1, 2, 3, 4} ==
+ FourCharsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 0>
+ constexpr auto B = FourCharsVecSize{1, 2, 3, 4} !=
+ FourCharsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
+
+ constexpr auto C = FourCharsVecSize{1, 2, 3, 4} < 3;
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 0>
+ constexpr auto D = FourCharsVecSize{1, 2, 3, 4} > 3;
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 0, i8 1>
+ constexpr auto E = FourCharsVecSize{1, 2, 3, 4} <= 3;
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
+ constexpr auto F = FourCharsVecSize{1, 2, 3, 4} >= 3;
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ constexpr auto G = FourCharsVecSize{1, 2, 3, 4} == 3;
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 0>
+ constexpr auto H = FourCharsVecSize{1, 2, 3, 4} != 3;
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
+
+ constexpr auto I = FourCharsVecSize{1, 2, 3, 4} &
+ FourCharsVecSize{4, 3, 2, 1};
+ // CHECK: store <4 x i8> <i8 0, i8 2, i8 2, i8 0>
+ constexpr auto J = FourCharsVecSize{1, 2, 3, 4} ^
+ FourCharsVecSize { 4, 3, 2, 1 };
+ // CHECK: store <4 x i8> <i8 5, i8 1, i8 1, i8 5>
+ constexpr auto K = FourCharsVecSize{1, 2, 3, 4} |
+ FourCharsVecSize{4, 3, 2, 1};
+ // CHECK: store <4 x i8> <i8 5, i8 3, i8 3, i8 5>
+ constexpr auto L = FourCharsVecSize{1, 2, 3, 4} & 3;
+ // CHECK: store <4 x i8> <i8 1, i8 2, i8 3, i8 0>
+ constexpr auto M = FourCharsVecSize{1, 2, 3, 4} ^ 3;
+ // CHECK: store <4 x i8> <i8 2, i8 1, i8 0, i8 7>
+ constexpr auto N = FourCharsVecSize{1, 2, 3, 4} | 3;
+ // CHECK: store <4 x i8> <i8 3, i8 3, i8 3, i8 7>
+
+ constexpr auto O = FourCharsVecSize{5, 0, 6, 0} &&
+ FourCharsVecSize{5, 5, 0, 0};
+ // CHECK: store <4 x i8> <i8 1, i8 0, i8 0, i8 0>
+ constexpr auto P = FourCharsVecSize{5, 0, 6, 0} ||
+ FourCharsVecSize{5, 5, 0, 0};
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
+
+ constexpr auto Q = FourCharsVecSize{5, 0, 6, 0} && 3;
+ // CHECK: store <4 x i8> <i8 1, i8 0, i8 1, i8 0>
+ constexpr auto R = FourCharsVecSize{5, 0, 6, 0} || 3;
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 1>
+
+ constexpr auto T = CmpMul(a, b);
+ // CHECK: store <4 x i8> <i8 108, i8 18, i8 56, i8 72>
+
+ constexpr auto U = CmpDiv(a, b);
+ // CHECK: store <4 x i8> <i8 3, i8 18, i8 0, i8 0>
+
+ constexpr auto V = CmpRem(a, b);
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 7, i8 8>
+
+ constexpr auto X = CmpAdd(a, b);
+ // CHECK: store <4 x i8> <i8 24, i8 19, i8 15, i8 17>
+
+ constexpr auto Y = CmpSub(a, b);
+ // CHECK: store <4 x i8> <i8 12, i8 17, i8 -1, i8 -1>
+
+ constexpr auto Z = CmpLSH(a, H);
+ // CHECK: store <4 x i8> <i8 36, i8 36, i8 7, i8 16>
+
+ constexpr auto aa = CmpRSH(a, H);
+ // CHECK: store <4 x i8> <i8 9, i8 9, i8 7, i8 4>
+
+ constexpr auto ab = CmpBinAnd(a, b);
+ // CHECK: store <4 x i8> <i8 2, i8 0, i8 0, i8 8>
+
+ constexpr auto ac = CmpBinXOr(a, b);
+ // CHECK: store <4 x i8> <i8 20, i8 19, i8 15, i8 1>
+
+ constexpr auto ad = CmpBinOr(a, b);
+ // CHECK: store <4 x i8> <i8 22, i8 19, i8 15, i8 9>
+}
+
+void CharExtVecUsage() {
+ constexpr auto a = FourCharsExtVec{6, 3, 2, 1} +
+ FourCharsExtVec{12, 15, 5, 7};
+ // CHECK: store <4 x i8> <i8 18, i8 18, i8 7, i8 8>
+ constexpr auto b = FourCharsExtVec{19, 15, 13, 12} -
+ FourCharsExtVec{13, 14, 5, 3};
+ // CHECK: store <4 x i8> <i8 6, i8 1, i8 8, i8 9>
+ constexpr auto c = FourCharsExtVec{8, 4, 2, 1} *
+ FourCharsExtVec{3, 4, 5, 6};
+ // CHECK: store <4 x i8> <i8 24, i8 16, i8 10, i8 6>
+ constexpr auto d = FourCharsExtVec{12, 12, 10, 10} /
+ FourCharsExtVec{6, 4, 5, 2};
+ // CHECK: store <4 x i8> <i8 2, i8 3, i8 2, i8 5>
+ constexpr auto e = FourCharsExtVec{12, 12, 10, 10} %
+ FourCharsExtVec{6, 4, 4, 3};
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 2, i8 1>
+
+ constexpr auto f = FourCharsExtVec{6, 3, 2, 1} + 3;
+ // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4>
+ constexpr auto g = FourCharsExtVec{19, 15, 12, 10} - 3;
+ // CHECK: store <4 x i8> <i8 16, i8 12, i8 9, i8 7>
+ constexpr auto h = FourCharsExtVec{8, 4, 2, 1} * 3;
+ // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3>
+ constexpr auto j = FourCharsExtVec{12, 15, 18, 21} / 3;
+ // CHECK: store <4 x i8> <i8 4, i8 5, i8 6, i8 7>
+ constexpr auto k = FourCharsExtVec{12, 17, 19, 22} % 3;
+ // CHECK: store <4 x i8> <i8 0, i8 2, i8 1, i8 1>
+
+ constexpr auto l = 3 + FourCharsExtVec{6, 3, 2, 1};
+ // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4>
+ constexpr auto m = 20 - FourCharsExtVec{19, 15, 12, 10};
+ // CHECK: store <4 x i8> <i8 1, i8 5, i8 8, i8 10>
+ constexpr auto n = 3 * FourCharsExtVec{8, 4, 2, 1};
+ // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3>
+ constexpr auto o = 100 / FourCharsExtVec{12, 15, 18, 21};
+ // CHECK: store <4 x i8> <i8 8, i8 6, i8 5, i8 4>
+ constexpr auto p = 100 % FourCharsExtVec{12, 15, 18, 21};
+ // CHECK: store <4 x i8> <i8 4, i8 10, i8 10, i8 16>
+
+ constexpr auto q = FourCharsExtVec{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2};
+ // CHECK: store <4 x i8> <i8 12, i8 6, i8 8, i8 4>
+ constexpr auto r = FourCharsExtVec{19, 15, 12, 10} >>
+ FourCharsExtVec{1, 1, 2, 2};
+ // CHECK: store <4 x i8> <i8 9, i8 7, i8 3, i8 2>
+ constexpr auto s = FourCharsExtVec{6, 3, 5, 10} << 1;
+ // CHECK: store <4 x i8> <i8 12, i8 6, i8 10, i8 20>
+ constexpr auto t = FourCharsExtVec{19, 15, 10, 20} >> 1;
+ // CHECK: store <4 x i8> <i8 9, i8 7, i8 5, i8 10>
+ constexpr auto u = 12 << FourCharsExtVec{1, 2, 3, 3};
+ // CHECK: store <4 x i8> <i8 24, i8 48, i8 96, i8 96>
+ constexpr auto v = 12 >> FourCharsExtVec{1, 2, 2, 1};
+ // CHECK: store <4 x i8> <i8 6, i8 3, i8 3, i8 6>
+
+ constexpr auto w = FourCharsExtVec{1, 2, 3, 4} <
+ FourCharsExtVec{4, 3, 2, 1};
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 0>
+ constexpr auto x = FourCharsExtVec{1, 2, 3, 4} >
+ FourCharsExtVec{4, 3, 2, 1};
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ constexpr auto y = FourCharsExtVec{1, 2, 3, 4} <=
+ FourCharsExtVec{4, 3, 3, 1};
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
+ constexpr auto z = FourCharsExtVec{1, 2, 3, 4} >=
+ FourCharsExtVec{4, 3, 3, 1};
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ constexpr auto A = FourCharsExtVec{1, 2, 3, 4} ==
+ FourCharsExtVec{4, 3, 3, 1};
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 0>
+ constexpr auto B = FourCharsExtVec{1, 2, 3, 4} !=
+ FourCharsExtVec{4, 3, 3, 1};
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
+
+ constexpr auto C = FourCharsExtVec{1, 2, 3, 4} < 3;
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 0>
+ constexpr auto D = FourCharsExtVec{1, 2, 3, 4} > 3;
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 0, i8 1>
+ constexpr auto E = FourCharsExtVec{1, 2, 3, 4} <= 3;
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
+ constexpr auto F = FourCharsExtVec{1, 2, 3, 4} >= 3;
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ constexpr auto G = FourCharsExtVec{1, 2, 3, 4} == 3;
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 0>
+ constexpr auto H = FourCharsExtVec{1, 2, 3, 4} != 3;
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
+
+ constexpr auto I = FourCharsExtVec{1, 2, 3, 4} &
+ FourCharsExtVec{4, 3, 2, 1};
+ // CHECK: store <4 x i8> <i8 0, i8 2, i8 2, i8 0>
+ constexpr auto J = FourCharsExtVec{1, 2, 3, 4} ^
+ FourCharsExtVec { 4, 3, 2, 1 };
+ // CHECK: store <4 x i8> <i8 5, i8 1, i8 1, i8 5>
+ constexpr auto K = FourCharsExtVec{1, 2, 3, 4} |
+ FourCharsExtVec{4, 3, 2, 1};
+ // CHECK: store <4 x i8> <i8 5, i8 3, i8 3, i8 5>
+ constexpr auto L = FourCharsExtVec{1, 2, 3, 4} & 3;
+ // CHECK: store <4 x i8> <i8 1, i8 2, i8 3, i8 0>
+ constexpr auto M = FourCharsExtVec{1, 2, 3, 4} ^ 3;
+ // CHECK: store <4 x i8> <i8 2, i8 1, i8 0, i8 7>
+ constexpr auto N = FourCharsExtVec{1, 2, 3, 4} | 3;
+ // CHECK: store <4 x i8> <i8 3, i8 3, i8 3, i8 7>
+
+ constexpr auto O = FourCharsExtVec{5, 0, 6, 0} &&
+ FourCharsExtVec{5, 5, 0, 0};
+ // CHECK: store <4 x i8> <i8 1, i8 0, i8 0, i8 0>
+ constexpr auto P = FourCharsExtVec{5, 0, 6, 0} ||
+ FourCharsExtVec{5, 5, 0, 0};
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
+
+ constexpr auto Q = FourCharsExtVec{5, 0, 6, 0} && 3;
+ // CHECK: store <4 x i8> <i8 1, i8 0, i8 1, i8 0>
+ constexpr auto R = FourCharsExtVec{5, 0, 6, 0} || 3;
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 1>
+
+ constexpr auto T = CmpMul(a, b);
+ // CHECK: store <4 x i8> <i8 108, i8 18, i8 56, i8 72>
+
+ constexpr auto U = CmpDiv(a, b);
+ // CHECK: store <4 x i8> <i8 3, i8 18, i8 0, i8 0>
+
+ constexpr auto V = CmpRem(a, b);
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 7, i8 8>
+
+ constexpr auto X = CmpAdd(a, b);
+ // CHECK: store <4 x i8> <i8 24, i8 19, i8 15, i8 17>
+
+ constexpr auto Y = CmpSub(a, b);
+ // CHECK: store <4 x i8> <i8 12, i8 17, i8 -1, i8 -1>
+
+ constexpr auto Z = CmpLSH(a, H);
+ // CHECK: store <4 x i8> <i8 36, i8 36, i8 7, i8 16>
+
+ constexpr auto aa = CmpRSH(a, H);
+ // CHECK: store <4 x i8> <i8 9, i8 9, i8 7, i8 4>
+
+ constexpr auto ab = CmpBinAnd(a, b);
+ // CHECK: store <4 x i8> <i8 2, i8 0, i8 0, i8 8>
+
+ constexpr auto ac = CmpBinXOr(a, b);
+ // CHECK: store <4 x i8> <i8 20, i8 19, i8 15, i8 1>
+
+ constexpr auto ad = CmpBinOr(a, b);
+ // CHECK: store <4 x i8> <i8 22, i8 19, i8 15, i8 9>
+}
+
+void FloatUsage() {
+ constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} +
+ FourFloatsVecSize{12, 15, 5, 7};
+ // CHECK: <4 x float> <float 1.800000e+01, float 1.800000e+01, float 7.000000e+00, float 8.000000e+00>
+ constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} -
+ FourFloatsVecSize{13, 14, 5, 3};
+ // CHECK: store <4 x float> <float 6.000000e+00, float 1.000000e+00, float 8.000000e+00, float 9.000000e+00>
+ constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} *
+ FourFloatsVecSize{3, 4, 5, 6};
+ // CHECK: store <4 x float> <float 2.400000e+01, float 1.600000e+01, float 1.000000e+01, float 6.000000e+00>
+ constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} /
+ FourFloatsVecSize{6, 4, 5, 2};
+ // CHECK: store <4 x float> <float 2.000000e+00, float 3.000000e+00, float 2.000000e+00, float 5.000000e+00>
+
+ constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3;
+ // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00>
+ constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3;
+ // CHECK: store <4 x float> <float 1.600000e+01, float 1.200000e+01, float 9.000000e+00, float 7.000000e+00>
+ constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3;
+ // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00>
+ constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3;
+ // CHECK: store <4 x float> <float 4.000000e+00, float 5.000000e+00, float 6.000000e+00, float 7.000000e+00>
+
+ constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1};
+ // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00>
+ constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10};
+ // CHECK: store <4 x float> <float 1.000000e+00, float 5.000000e+00, float 8.000000e+00, float 1.000000e+01>
+ constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1};
+ // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00>
+ constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21};
+ // CHECK: store <4 x float> <float 0x4020AAAAA0000000, float 0x401AAAAAA0000000, float 0x401638E380000000, float 0x40130C30C0000000>
+
+ constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} <
+ FourFloatsVecSize{4, 3, 2, 1};
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 0>
+ constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} >
+ FourFloatsVecSize{4, 3, 2, 1};
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <=
+ FourFloatsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
+ constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >=
+ FourFloatsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} ==
+ FourFloatsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 0>
+ constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} !=
+ FourFloatsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 1>
+
+ constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3;
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 0>
+ constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3;
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 0, i32 1>
+ constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3;
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
+ constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3;
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3;
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 0>
+ constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3;
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 1>
+
+ constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} &&
+ FourFloatsVecSize{5, 5, 0, 0};
+ // CHECK: store <4 x i32> <i32 1, i32 0, i32 0, i32 0>
+ constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} ||
+ FourFloatsVecSize{5, 5, 0, 0};
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
+
+ constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3;
+ // CHECK: store <4 x i32> <i32 1, i32 0, i32 1, i32 0>
+ constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3;
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+
+ constexpr auto T = CmpMul(a, b);
+ // CHECK: store <4 x float> <float 1.080000e+02, float 1.800000e+01, float 5.600000e+01, float 7.200000e+01>
+
+ constexpr auto U = CmpDiv(a, b);
+ // CHECK: store <4 x float> <float 3.000000e+00, float 1.800000e+01, float 8.750000e-01, float 0x3FEC71C720000000>
+
+ constexpr auto X = CmpAdd(a, b);
+ // CHECK: store <4 x float> <float 2.400000e+01, float 1.900000e+01, float 1.500000e+01, float 1.700000e+01>
+
+ constexpr auto Y = CmpSub(a, b);
+ // CHECK: store <4 x float> <float 1.200000e+01, float 1.700000e+01, float -1.000000e+00, float -1.000000e+00>
+}
+
+void FloatVecUsage() {
+ constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} +
+ FourFloatsVecSize{12, 15, 5, 7};
+ // CHECK: <4 x float> <float 1.800000e+01, float 1.800000e+01, float 7.000000e+00, float 8.000000e+00>
+ constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} -
+ FourFloatsVecSize{13, 14, 5, 3};
+ // CHECK: store <4 x float> <float 6.000000e+00, float 1.000000e+00, float 8.000000e+00, float 9.000000e+00>
+ constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} *
+ FourFloatsVecSize{3, 4, 5, 6};
+ // CHECK: store <4 x float> <float 2.400000e+01, float 1.600000e+01, float 1.000000e+01, float 6.000000e+00>
+ constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} /
+ FourFloatsVecSize{6, 4, 5, 2};
+ // CHECK: store <4 x float> <float 2.000000e+00, float 3.000000e+00, float 2.000000e+00, float 5.000000e+00>
+
+ constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3;
+ // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00>
+ constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3;
+ // CHECK: store <4 x float> <float 1.600000e+01, float 1.200000e+01, float 9.000000e+00, float 7.000000e+00>
+ constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3;
+ // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00>
+ constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3;
+ // CHECK: store <4 x float> <float 4.000000e+00, float 5.000000e+00, float 6.000000e+00, float 7.000000e+00>
+
+ constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1};
+ // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00>
+ constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10};
+ // CHECK: store <4 x float> <float 1.000000e+00, float 5.000000e+00, float 8.000000e+00, float 1.000000e+01>
+ constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1};
+ // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00>
+ constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21};
+ // CHECK: store <4 x float> <float 0x4020AAAAA0000000, float 0x401AAAAAA0000000, float 0x401638E380000000, float 0x40130C30C0000000>
+
+ constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} <
+ FourFloatsVecSize{4, 3, 2, 1};
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 0>
+ constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} >
+ FourFloatsVecSize{4, 3, 2, 1};
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <=
+ FourFloatsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
+ constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >=
+ FourFloatsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} ==
+ FourFloatsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 0>
+ constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} !=
+ FourFloatsVecSize{4, 3, 3, 1};
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 1>
+
+ constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3;
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 0>
+ constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3;
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 0, i32 1>
+ constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3;
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
+ constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3;
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3;
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 0>
+ constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3;
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 1>
+
+ constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} &&
+ FourFloatsVecSize{5, 5, 0, 0};
+ // CHECK: store <4 x i32> <i32 1, i32 0, i32 0, i32 0>
+ constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} ||
+ FourFloatsVecSize{5, 5, 0, 0};
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
+
+ constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3;
+ // CHECK: store <4 x i32> <i32 1, i32 0, i32 1, i32 0>
+ constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3;
+ // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+
+ constexpr auto T = CmpMul(a, b);
+ // CHECK: store <4 x float> <float 1.080000e+02, float 1.800000e+01, float 5.600000e+01, float 7.200000e+01>
+
+ constexpr auto U = CmpDiv(a, b);
+ // CHECK: store <4 x float> <float 3.000000e+00, float 1.800000e+01, float 8.750000e-01, float 0x3FEC71C720000000>
+
+ constexpr auto X = CmpAdd(a, b);
+ // CHECK: store <4 x float> <float 2.400000e+01, float 1.900000e+01, float 1.500000e+01, float 1.700000e+01>
+
+ constexpr auto Y = CmpSub(a, b);
+ // CHECK: store <4 x float> <float 1.200000e+01, float 1.700000e+01, float -1.000000e+00, float -1.000000e+00>
+}