// 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 constexpr auto CmpMul(T t, U u) { t *= u; return t; } template constexpr auto CmpDiv(T t, U u) { t /= u; return t; } template constexpr auto CmpRem(T t, U u) { t %= u; return t; } template constexpr auto CmpAdd(T t, U u) { t += u; return t; } template constexpr auto CmpSub(T t, U u) { t -= u; return t; } template constexpr auto CmpLSH(T t, U u) { t <<= u; return t; } template constexpr auto CmpRSH(T t, U u) { t >>= u; return t; } template constexpr auto CmpBinAnd(T t, U u) { t &= u; return t; } template constexpr auto CmpBinXOr(T t, U u) { t ^= u; return t; } template 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> constexpr auto b = FourCharsVecSize{19, 15, 13, 12} - FourCharsVecSize{13, 14, 5, 3}; // CHECK: store <4 x i8> constexpr auto c = FourCharsVecSize{8, 4, 2, 1} * FourCharsVecSize{3, 4, 5, 6}; // CHECK: store <4 x i8> constexpr auto d = FourCharsVecSize{12, 12, 10, 10} / FourCharsVecSize{6, 4, 5, 2}; // CHECK: store <4 x i8> constexpr auto e = FourCharsVecSize{12, 12, 10, 10} % FourCharsVecSize{6, 4, 4, 3}; // CHECK: store <4 x i8> constexpr auto f = FourCharsVecSize{6, 3, 2, 1} + 3; // CHECK: store <4 x i8> constexpr auto g = FourCharsVecSize{19, 15, 12, 10} - 3; // CHECK: store <4 x i8> constexpr auto h = FourCharsVecSize{8, 4, 2, 1} * 3; // CHECK: store <4 x i8> constexpr auto j = FourCharsVecSize{12, 15, 18, 21} / 3; // CHECK: store <4 x i8> constexpr auto k = FourCharsVecSize{12, 17, 19, 22} % 3; // CHECK: store <4 x i8> constexpr auto l = 3 + FourCharsVecSize{6, 3, 2, 1}; // CHECK: store <4 x i8> constexpr auto m = 20 - FourCharsVecSize{19, 15, 12, 10}; // CHECK: store <4 x i8> constexpr auto n = 3 * FourCharsVecSize{8, 4, 2, 1}; // CHECK: store <4 x i8> constexpr auto o = 100 / FourCharsVecSize{12, 15, 18, 21}; // CHECK: store <4 x i8> constexpr auto p = 100 % FourCharsVecSize{12, 15, 18, 21}; // CHECK: store <4 x i8> constexpr auto q = FourCharsVecSize{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2}; // CHECK: store <4 x i8> constexpr auto r = FourCharsVecSize{19, 15, 12, 10} >> FourCharsVecSize{1, 1, 2, 2}; // CHECK: store <4 x i8> constexpr auto s = FourCharsVecSize{6, 3, 5, 10} << 1; // CHECK: store <4 x i8> constexpr auto t = FourCharsVecSize{19, 15, 10, 20} >> 1; // CHECK: store <4 x i8> constexpr auto u = 12 << FourCharsVecSize{1, 2, 3, 3}; // CHECK: store <4 x i8> constexpr auto v = 12 >> FourCharsVecSize{1, 2, 2, 1}; // CHECK: store <4 x i8> constexpr auto w = FourCharsVecSize{1, 2, 3, 4} < FourCharsVecSize{4, 3, 2, 1}; // CHECK: store <4 x i8> constexpr auto x = FourCharsVecSize{1, 2, 3, 4} > FourCharsVecSize{4, 3, 2, 1}; // CHECK: store <4 x i8> constexpr auto y = FourCharsVecSize{1, 2, 3, 4} <= FourCharsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i8> constexpr auto z = FourCharsVecSize{1, 2, 3, 4} >= FourCharsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i8> constexpr auto A = FourCharsVecSize{1, 2, 3, 4} == FourCharsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i8> constexpr auto B = FourCharsVecSize{1, 2, 3, 4} != FourCharsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i8> constexpr auto C = FourCharsVecSize{1, 2, 3, 4} < 3; // CHECK: store <4 x i8> constexpr auto D = FourCharsVecSize{1, 2, 3, 4} > 3; // CHECK: store <4 x i8> constexpr auto E = FourCharsVecSize{1, 2, 3, 4} <= 3; // CHECK: store <4 x i8> constexpr auto F = FourCharsVecSize{1, 2, 3, 4} >= 3; // CHECK: store <4 x i8> constexpr auto G = FourCharsVecSize{1, 2, 3, 4} == 3; // CHECK: store <4 x i8> constexpr auto H = FourCharsVecSize{1, 2, 3, 4} != 3; // CHECK: store <4 x i8> constexpr auto I = FourCharsVecSize{1, 2, 3, 4} & FourCharsVecSize{4, 3, 2, 1}; // CHECK: store <4 x i8> constexpr auto J = FourCharsVecSize{1, 2, 3, 4} ^ FourCharsVecSize { 4, 3, 2, 1 }; // CHECK: store <4 x i8> constexpr auto K = FourCharsVecSize{1, 2, 3, 4} | FourCharsVecSize{4, 3, 2, 1}; // CHECK: store <4 x i8> constexpr auto L = FourCharsVecSize{1, 2, 3, 4} & 3; // CHECK: store <4 x i8> constexpr auto M = FourCharsVecSize{1, 2, 3, 4} ^ 3; // CHECK: store <4 x i8> constexpr auto N = FourCharsVecSize{1, 2, 3, 4} | 3; // CHECK: store <4 x i8> constexpr auto O = FourCharsVecSize{5, 0, 6, 0} && FourCharsVecSize{5, 5, 0, 0}; // CHECK: store <4 x i8> constexpr auto P = FourCharsVecSize{5, 0, 6, 0} || FourCharsVecSize{5, 5, 0, 0}; // CHECK: store <4 x i8> constexpr auto Q = FourCharsVecSize{5, 0, 6, 0} && 3; // CHECK: store <4 x i8> constexpr auto R = FourCharsVecSize{5, 0, 6, 0} || 3; // CHECK: store <4 x i8> constexpr auto T = CmpMul(a, b); // CHECK: store <4 x i8> constexpr auto U = CmpDiv(a, b); // CHECK: store <4 x i8> constexpr auto V = CmpRem(a, b); // CHECK: store <4 x i8> constexpr auto X = CmpAdd(a, b); // CHECK: store <4 x i8> constexpr auto Y = CmpSub(a, b); // CHECK: store <4 x i8> constexpr auto Z = CmpLSH(a, H); // CHECK: store <4 x i8> constexpr auto aa = CmpRSH(a, H); // CHECK: store <4 x i8> constexpr auto ab = CmpBinAnd(a, b); // CHECK: store <4 x i8> constexpr auto ac = CmpBinXOr(a, b); // CHECK: store <4 x i8> constexpr auto ad = CmpBinOr(a, b); // CHECK: store <4 x i8> } void CharExtVecUsage() { constexpr auto a = FourCharsExtVec{6, 3, 2, 1} + FourCharsExtVec{12, 15, 5, 7}; // CHECK: store <4 x i8> constexpr auto b = FourCharsExtVec{19, 15, 13, 12} - FourCharsExtVec{13, 14, 5, 3}; // CHECK: store <4 x i8> constexpr auto c = FourCharsExtVec{8, 4, 2, 1} * FourCharsExtVec{3, 4, 5, 6}; // CHECK: store <4 x i8> constexpr auto d = FourCharsExtVec{12, 12, 10, 10} / FourCharsExtVec{6, 4, 5, 2}; // CHECK: store <4 x i8> constexpr auto e = FourCharsExtVec{12, 12, 10, 10} % FourCharsExtVec{6, 4, 4, 3}; // CHECK: store <4 x i8> constexpr auto f = FourCharsExtVec{6, 3, 2, 1} + 3; // CHECK: store <4 x i8> constexpr auto g = FourCharsExtVec{19, 15, 12, 10} - 3; // CHECK: store <4 x i8> constexpr auto h = FourCharsExtVec{8, 4, 2, 1} * 3; // CHECK: store <4 x i8> constexpr auto j = FourCharsExtVec{12, 15, 18, 21} / 3; // CHECK: store <4 x i8> constexpr auto k = FourCharsExtVec{12, 17, 19, 22} % 3; // CHECK: store <4 x i8> constexpr auto l = 3 + FourCharsExtVec{6, 3, 2, 1}; // CHECK: store <4 x i8> constexpr auto m = 20 - FourCharsExtVec{19, 15, 12, 10}; // CHECK: store <4 x i8> constexpr auto n = 3 * FourCharsExtVec{8, 4, 2, 1}; // CHECK: store <4 x i8> constexpr auto o = 100 / FourCharsExtVec{12, 15, 18, 21}; // CHECK: store <4 x i8> constexpr auto p = 100 % FourCharsExtVec{12, 15, 18, 21}; // CHECK: store <4 x i8> constexpr auto q = FourCharsExtVec{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2}; // CHECK: store <4 x i8> constexpr auto r = FourCharsExtVec{19, 15, 12, 10} >> FourCharsExtVec{1, 1, 2, 2}; // CHECK: store <4 x i8> constexpr auto s = FourCharsExtVec{6, 3, 5, 10} << 1; // CHECK: store <4 x i8> constexpr auto t = FourCharsExtVec{19, 15, 10, 20} >> 1; // CHECK: store <4 x i8> constexpr auto u = 12 << FourCharsExtVec{1, 2, 3, 3}; // CHECK: store <4 x i8> constexpr auto v = 12 >> FourCharsExtVec{1, 2, 2, 1}; // CHECK: store <4 x i8> constexpr auto w = FourCharsExtVec{1, 2, 3, 4} < FourCharsExtVec{4, 3, 2, 1}; // CHECK: store <4 x i8> constexpr auto x = FourCharsExtVec{1, 2, 3, 4} > FourCharsExtVec{4, 3, 2, 1}; // CHECK: store <4 x i8> constexpr auto y = FourCharsExtVec{1, 2, 3, 4} <= FourCharsExtVec{4, 3, 3, 1}; // CHECK: store <4 x i8> constexpr auto z = FourCharsExtVec{1, 2, 3, 4} >= FourCharsExtVec{4, 3, 3, 1}; // CHECK: store <4 x i8> constexpr auto A = FourCharsExtVec{1, 2, 3, 4} == FourCharsExtVec{4, 3, 3, 1}; // CHECK: store <4 x i8> constexpr auto B = FourCharsExtVec{1, 2, 3, 4} != FourCharsExtVec{4, 3, 3, 1}; // CHECK: store <4 x i8> constexpr auto C = FourCharsExtVec{1, 2, 3, 4} < 3; // CHECK: store <4 x i8> constexpr auto D = FourCharsExtVec{1, 2, 3, 4} > 3; // CHECK: store <4 x i8> constexpr auto E = FourCharsExtVec{1, 2, 3, 4} <= 3; // CHECK: store <4 x i8> constexpr auto F = FourCharsExtVec{1, 2, 3, 4} >= 3; // CHECK: store <4 x i8> constexpr auto G = FourCharsExtVec{1, 2, 3, 4} == 3; // CHECK: store <4 x i8> constexpr auto H = FourCharsExtVec{1, 2, 3, 4} != 3; // CHECK: store <4 x i8> constexpr auto I = FourCharsExtVec{1, 2, 3, 4} & FourCharsExtVec{4, 3, 2, 1}; // CHECK: store <4 x i8> constexpr auto J = FourCharsExtVec{1, 2, 3, 4} ^ FourCharsExtVec { 4, 3, 2, 1 }; // CHECK: store <4 x i8> constexpr auto K = FourCharsExtVec{1, 2, 3, 4} | FourCharsExtVec{4, 3, 2, 1}; // CHECK: store <4 x i8> constexpr auto L = FourCharsExtVec{1, 2, 3, 4} & 3; // CHECK: store <4 x i8> constexpr auto M = FourCharsExtVec{1, 2, 3, 4} ^ 3; // CHECK: store <4 x i8> constexpr auto N = FourCharsExtVec{1, 2, 3, 4} | 3; // CHECK: store <4 x i8> constexpr auto O = FourCharsExtVec{5, 0, 6, 0} && FourCharsExtVec{5, 5, 0, 0}; // CHECK: store <4 x i8> constexpr auto P = FourCharsExtVec{5, 0, 6, 0} || FourCharsExtVec{5, 5, 0, 0}; // CHECK: store <4 x i8> constexpr auto Q = FourCharsExtVec{5, 0, 6, 0} && 3; // CHECK: store <4 x i8> constexpr auto R = FourCharsExtVec{5, 0, 6, 0} || 3; // CHECK: store <4 x i8> constexpr auto T = CmpMul(a, b); // CHECK: store <4 x i8> constexpr auto U = CmpDiv(a, b); // CHECK: store <4 x i8> constexpr auto V = CmpRem(a, b); // CHECK: store <4 x i8> constexpr auto X = CmpAdd(a, b); // CHECK: store <4 x i8> constexpr auto Y = CmpSub(a, b); // CHECK: store <4 x i8> constexpr auto Z = CmpLSH(a, H); // CHECK: store <4 x i8> constexpr auto aa = CmpRSH(a, H); // CHECK: store <4 x i8> constexpr auto ab = CmpBinAnd(a, b); // CHECK: store <4 x i8> constexpr auto ac = CmpBinXOr(a, b); // CHECK: store <4 x i8> constexpr auto ad = CmpBinOr(a, b); // CHECK: store <4 x i8> } void FloatUsage() { constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} + FourFloatsVecSize{12, 15, 5, 7}; // CHECK: <4 x float> constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} - FourFloatsVecSize{13, 14, 5, 3}; // CHECK: store <4 x float> constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} * FourFloatsVecSize{3, 4, 5, 6}; // CHECK: store <4 x float> constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} / FourFloatsVecSize{6, 4, 5, 2}; // CHECK: store <4 x float> constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3; // CHECK: store <4 x float> constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3; // CHECK: store <4 x float> constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3; // CHECK: store <4 x float> constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3; // CHECK: store <4 x float> constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1}; // CHECK: store <4 x float> constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10}; // CHECK: store <4 x float> constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1}; // CHECK: store <4 x float> constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21}; // CHECK: store <4 x float> constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} < FourFloatsVecSize{4, 3, 2, 1}; // CHECK: store <4 x i32> constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} > FourFloatsVecSize{4, 3, 2, 1}; // CHECK: store <4 x i32> constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <= FourFloatsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i32> constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >= FourFloatsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i32> constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} == FourFloatsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i32> constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} != FourFloatsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i32> constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3; // CHECK: store <4 x i32> constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3; // CHECK: store <4 x i32> constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3; // CHECK: store <4 x i32> constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3; // CHECK: store <4 x i32> constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3; // CHECK: store <4 x i32> constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3; // CHECK: store <4 x i32> constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} && FourFloatsVecSize{5, 5, 0, 0}; // CHECK: store <4 x i32> constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} || FourFloatsVecSize{5, 5, 0, 0}; // CHECK: store <4 x i32> constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3; // CHECK: store <4 x i32> constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3; // CHECK: store <4 x i32> constexpr auto T = CmpMul(a, b); // CHECK: store <4 x float> constexpr auto U = CmpDiv(a, b); // CHECK: store <4 x float> constexpr auto X = CmpAdd(a, b); // CHECK: store <4 x float> constexpr auto Y = CmpSub(a, b); // CHECK: store <4 x float> } void FloatVecUsage() { constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} + FourFloatsVecSize{12, 15, 5, 7}; // CHECK: <4 x float> constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} - FourFloatsVecSize{13, 14, 5, 3}; // CHECK: store <4 x float> constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} * FourFloatsVecSize{3, 4, 5, 6}; // CHECK: store <4 x float> constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} / FourFloatsVecSize{6, 4, 5, 2}; // CHECK: store <4 x float> constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3; // CHECK: store <4 x float> constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3; // CHECK: store <4 x float> constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3; // CHECK: store <4 x float> constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3; // CHECK: store <4 x float> constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1}; // CHECK: store <4 x float> constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10}; // CHECK: store <4 x float> constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1}; // CHECK: store <4 x float> constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21}; // CHECK: store <4 x float> constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} < FourFloatsVecSize{4, 3, 2, 1}; // CHECK: store <4 x i32> constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} > FourFloatsVecSize{4, 3, 2, 1}; // CHECK: store <4 x i32> constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <= FourFloatsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i32> constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >= FourFloatsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i32> constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} == FourFloatsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i32> constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} != FourFloatsVecSize{4, 3, 3, 1}; // CHECK: store <4 x i32> constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3; // CHECK: store <4 x i32> constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3; // CHECK: store <4 x i32> constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3; // CHECK: store <4 x i32> constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3; // CHECK: store <4 x i32> constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3; // CHECK: store <4 x i32> constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3; // CHECK: store <4 x i32> constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} && FourFloatsVecSize{5, 5, 0, 0}; // CHECK: store <4 x i32> constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} || FourFloatsVecSize{5, 5, 0, 0}; // CHECK: store <4 x i32> constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3; // CHECK: store <4 x i32> constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3; // CHECK: store <4 x i32> constexpr auto T = CmpMul(a, b); // CHECK: store <4 x float> constexpr auto U = CmpDiv(a, b); // CHECK: store <4 x float> constexpr auto X = CmpAdd(a, b); // CHECK: store <4 x float> constexpr auto Y = CmpSub(a, b); // CHECK: store <4 x float> }