forked from OSchip/llvm-project
Implement constexpr BinaryOperator for vector types
These operations do member-wise versions of the all of the listed operations. This patch implements all of the binaryoperators for these types. Note that the test is required to use codegen as I could not come up with a good way to validate the values without the array-subscript operator implemented (which is likely a much more involved change). Differential Reivision: https://reviews.llvm.org/D79755
This commit is contained in:
parent
98c2f4eea5
commit
b30c16670e
|
@ -2664,6 +2664,155 @@ static bool handleFloatFloatBinOp(EvalInfo &Info, const Expr *E,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool handleLogicalOpForVector(const APInt &LHSValue,
|
||||
BinaryOperatorKind Opcode,
|
||||
const APInt &RHSValue, APInt &Result) {
|
||||
bool LHS = (LHSValue != 0);
|
||||
bool RHS = (RHSValue != 0);
|
||||
|
||||
if (Opcode == BO_LAnd)
|
||||
Result = LHS && RHS;
|
||||
else
|
||||
Result = LHS || RHS;
|
||||
return true;
|
||||
}
|
||||
static bool handleLogicalOpForVector(const APFloat &LHSValue,
|
||||
BinaryOperatorKind Opcode,
|
||||
const APFloat &RHSValue, APInt &Result) {
|
||||
bool LHS = !LHSValue.isZero();
|
||||
bool RHS = !RHSValue.isZero();
|
||||
|
||||
if (Opcode == BO_LAnd)
|
||||
Result = LHS && RHS;
|
||||
else
|
||||
Result = LHS || RHS;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool handleLogicalOpForVector(const APValue &LHSValue,
|
||||
BinaryOperatorKind Opcode,
|
||||
const APValue &RHSValue, APInt &Result) {
|
||||
// The result is always an int type, however operands match the first.
|
||||
if (LHSValue.getKind() == APValue::Int)
|
||||
return handleLogicalOpForVector(LHSValue.getInt(), Opcode,
|
||||
RHSValue.getInt(), Result);
|
||||
assert(LHSValue.getKind() == APValue::Float && "Should be no other options");
|
||||
return handleLogicalOpForVector(LHSValue.getFloat(), Opcode,
|
||||
RHSValue.getFloat(), Result);
|
||||
}
|
||||
|
||||
template <typename APTy>
|
||||
static bool
|
||||
handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode,
|
||||
const APTy &RHSValue, APInt &Result) {
|
||||
switch (Opcode) {
|
||||
default:
|
||||
llvm_unreachable("unsupported binary operator");
|
||||
case BO_EQ:
|
||||
Result = (LHSValue == RHSValue);
|
||||
break;
|
||||
case BO_NE:
|
||||
Result = (LHSValue != RHSValue);
|
||||
break;
|
||||
case BO_LT:
|
||||
Result = (LHSValue < RHSValue);
|
||||
break;
|
||||
case BO_GT:
|
||||
Result = (LHSValue > RHSValue);
|
||||
break;
|
||||
case BO_LE:
|
||||
Result = (LHSValue <= RHSValue);
|
||||
break;
|
||||
case BO_GE:
|
||||
Result = (LHSValue >= RHSValue);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool handleCompareOpForVector(const APValue &LHSValue,
|
||||
BinaryOperatorKind Opcode,
|
||||
const APValue &RHSValue, APInt &Result) {
|
||||
// The result is always an int type, however operands match the first.
|
||||
if (LHSValue.getKind() == APValue::Int)
|
||||
return handleCompareOpForVectorHelper(LHSValue.getInt(), Opcode,
|
||||
RHSValue.getInt(), Result);
|
||||
assert(LHSValue.getKind() == APValue::Float && "Should be no other options");
|
||||
return handleCompareOpForVectorHelper(LHSValue.getFloat(), Opcode,
|
||||
RHSValue.getFloat(), Result);
|
||||
}
|
||||
|
||||
// Perform binary operations for vector types, in place on the LHS.
|
||||
static bool handleVectorVectorBinOp(EvalInfo &Info, const Expr *E,
|
||||
BinaryOperatorKind Opcode,
|
||||
APValue &LHSValue,
|
||||
const APValue &RHSValue) {
|
||||
assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
|
||||
"Operation not supported on vector types");
|
||||
|
||||
const auto *VT = E->getType()->castAs<VectorType>();
|
||||
unsigned NumElements = VT->getNumElements();
|
||||
QualType EltTy = VT->getElementType();
|
||||
|
||||
// In the cases (typically C as I've observed) where we aren't evaluating
|
||||
// constexpr but are checking for cases where the LHS isn't yet evaluatable,
|
||||
// just give up.
|
||||
if (!LHSValue.isVector()) {
|
||||
assert(LHSValue.isLValue() &&
|
||||
"A vector result that isn't a vector OR uncalculated LValue");
|
||||
Info.FFDiag(E);
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(LHSValue.getVectorLength() == NumElements &&
|
||||
RHSValue.getVectorLength() == NumElements && "Different vector sizes");
|
||||
|
||||
SmallVector<APValue, 4> ResultElements;
|
||||
|
||||
for (unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
|
||||
APValue LHSElt = LHSValue.getVectorElt(EltNum);
|
||||
APValue RHSElt = RHSValue.getVectorElt(EltNum);
|
||||
|
||||
if (EltTy->isIntegerType()) {
|
||||
APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
|
||||
EltTy->isUnsignedIntegerType()};
|
||||
bool Success = true;
|
||||
|
||||
if (BinaryOperator::isLogicalOp(Opcode))
|
||||
Success = handleLogicalOpForVector(LHSElt, Opcode, RHSElt, EltResult);
|
||||
else if (BinaryOperator::isComparisonOp(Opcode))
|
||||
Success = handleCompareOpForVector(LHSElt, Opcode, RHSElt, EltResult);
|
||||
else
|
||||
Success = handleIntIntBinOp(Info, E, LHSElt.getInt(), Opcode,
|
||||
RHSElt.getInt(), EltResult);
|
||||
|
||||
if (!Success) {
|
||||
Info.FFDiag(E);
|
||||
return false;
|
||||
}
|
||||
ResultElements.emplace_back(EltResult);
|
||||
|
||||
} else if (EltTy->isFloatingType()) {
|
||||
assert(LHSElt.getKind() == APValue::Float &&
|
||||
RHSElt.getKind() == APValue::Float &&
|
||||
"Mismatched LHS/RHS/Result Type");
|
||||
APFloat LHSFloat = LHSElt.getFloat();
|
||||
|
||||
if (!handleFloatFloatBinOp(Info, E, LHSFloat, Opcode,
|
||||
RHSElt.getFloat())) {
|
||||
Info.FFDiag(E);
|
||||
return false;
|
||||
}
|
||||
|
||||
ResultElements.emplace_back(LHSFloat);
|
||||
}
|
||||
}
|
||||
|
||||
LHSValue = APValue(ResultElements.data(), ResultElements.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Cast an lvalue referring to a base subobject to a derived class, by
|
||||
/// truncating the lvalue's path to the given length.
|
||||
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result,
|
||||
|
@ -3910,12 +4059,26 @@ struct CompoundAssignSubobjectHandler {
|
|||
return false;
|
||||
case APValue::LValue:
|
||||
return foundPointer(Subobj, SubobjType);
|
||||
case APValue::Vector:
|
||||
return foundVector(Subobj, SubobjType);
|
||||
default:
|
||||
// FIXME: can this happen?
|
||||
Info.FFDiag(E);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool foundVector(APValue &Value, QualType SubobjType) {
|
||||
if (!checkConst(SubobjType))
|
||||
return false;
|
||||
|
||||
if (!SubobjType->isVectorType()) {
|
||||
Info.FFDiag(E);
|
||||
return false;
|
||||
}
|
||||
return handleVectorVectorBinOp(Info, E, Opcode, Value, RHS);
|
||||
}
|
||||
|
||||
bool found(APSInt &Value, QualType SubobjType) {
|
||||
if (!checkConst(SubobjType))
|
||||
return false;
|
||||
|
@ -9516,10 +9679,9 @@ namespace {
|
|||
bool VisitCastExpr(const CastExpr* E);
|
||||
bool VisitInitListExpr(const InitListExpr *E);
|
||||
bool VisitUnaryImag(const UnaryOperator *E);
|
||||
// FIXME: Missing: unary -, unary ~, binary add/sub/mul/div,
|
||||
// binary comparisons, binary and/or/xor,
|
||||
// conditional operator (for GNU conditional select),
|
||||
// shufflevector, ExtVectorElementExpr
|
||||
bool VisitBinaryOperator(const BinaryOperator *E);
|
||||
// FIXME: Missing: unary -, unary ~, conditional operator (for GNU
|
||||
// conditional select), shufflevector, ExtVectorElementExpr
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
@ -9667,6 +9829,41 @@ bool VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
|
|||
return ZeroInitialization(E);
|
||||
}
|
||||
|
||||
bool VectorExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
||||
BinaryOperatorKind Op = E->getOpcode();
|
||||
assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
|
||||
"Operation not supported on vector types");
|
||||
|
||||
if (Op == BO_Comma)
|
||||
return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
|
||||
|
||||
Expr *LHS = E->getLHS();
|
||||
Expr *RHS = E->getRHS();
|
||||
|
||||
assert(LHS->getType()->isVectorType() && RHS->getType()->isVectorType() &&
|
||||
"Must both be vector types");
|
||||
// Checking JUST the types are the same would be fine, except shifts don't
|
||||
// need to have their types be the same (since you always shift by an int).
|
||||
assert(LHS->getType()->getAs<VectorType>()->getNumElements() ==
|
||||
E->getType()->getAs<VectorType>()->getNumElements() &&
|
||||
RHS->getType()->getAs<VectorType>()->getNumElements() ==
|
||||
E->getType()->getAs<VectorType>()->getNumElements() &&
|
||||
"All operands must be the same size.");
|
||||
|
||||
APValue LHSValue;
|
||||
APValue RHSValue;
|
||||
bool LHSOK = Evaluate(LHSValue, Info, LHS);
|
||||
if (!LHSOK && !Info.noteFailure())
|
||||
return false;
|
||||
if (!Evaluate(RHSValue, Info, RHS) || !LHSOK)
|
||||
return false;
|
||||
|
||||
if (!handleVectorVectorBinOp(Info, E, Op, LHSValue, RHSValue))
|
||||
return false;
|
||||
|
||||
return Success(LHSValue, E);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Array Evaluation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -0,0 +1,616 @@
|
|||
// 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>
|
||||
}
|
Loading…
Reference in New Issue