erichkeane created this revision. erichkeane added reviewers: RKSimon, aaron.ballman, void, efriedma. erichkeane requested review of this revision.
All of our boolean operations on vector types should be using something like vcmpeqd, which results in a mask of '-1' for the 'truth' type. We are currently instead using '1', which results in some incorrect calculations when used later (note that it does NOT result in a boolean vector, as that is not really a thing). This patch corrects that 1 to be a -1, and updates the affected tests. Additionally, in order to simplify changing of the tests, this ALSo implements operator-, which simply negates all values of the vector type. https://reviews.llvm.org/D115670 Files: clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constexpr-vectors.cpp
Index: clang/test/SemaCXX/constexpr-vectors.cpp =================================================================== --- clang/test/SemaCXX/constexpr-vectors.cpp +++ clang/test/SemaCXX/constexpr-vectors.cpp @@ -204,35 +204,35 @@ 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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}; @@ -277,10 +277,12 @@ 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); + constexpr auto InvH = -H; + // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1> + constexpr auto Z = CmpLSH(a, InvH); // CHECK: store <4 x i8> <i8 36, i8 36, i8 7, i8 16> - constexpr auto aa = CmpRSH(a, H); + constexpr auto aa = CmpRSH(a, InvH); // CHECK: store <4 x i8> <i8 9, i8 9, i8 7, i8 4> constexpr auto ab = CmpBinAnd(a, b); @@ -348,35 +350,35 @@ 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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}; @@ -421,10 +423,13 @@ 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); + constexpr auto InvH = -H; + // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1> + + constexpr auto Z = CmpLSH(a, InvH); // CHECK: store <4 x i8> <i8 36, i8 36, i8 7, i8 16> - constexpr auto aa = CmpRSH(a, H); + constexpr auto aa = CmpRSH(a, InvH); // CHECK: store <4 x i8> <i8 9, i8 9, i8 7, i8 4> constexpr auto ab = CmpBinAnd(a, b); @@ -471,35 +476,35 @@ 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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}; @@ -524,6 +529,9 @@ 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> + + constexpr auto Z = -Y; + // CHECK: store <4 x float> <float -1.200000e+01, float -1.700000e+01, float 1.000000e+00, float 1.000000e+00> } void FloatVecUsage() { @@ -560,35 +568,35 @@ 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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> + // 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}; @@ -613,4 +621,7 @@ 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> + + constexpr auto Z = -Y; + // CHECK: store <4 x float> <float -1.200000e+01, float -1.700000e+01, float 1.000000e+00, float 1.000000e+00> } Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -2912,22 +2912,22 @@ default: llvm_unreachable("unsupported binary operator"); case BO_EQ: - Result = (LHSValue == RHSValue); + Result = -(LHSValue == RHSValue); break; case BO_NE: - Result = (LHSValue != RHSValue); + Result = -(LHSValue != RHSValue); break; case BO_LT: - Result = (LHSValue < RHSValue); + Result = -(LHSValue < RHSValue); break; case BO_GT: - Result = (LHSValue > RHSValue); + Result = -(LHSValue > RHSValue); break; case BO_LE: - Result = (LHSValue <= RHSValue); + Result = -(LHSValue <= RHSValue); break; case BO_GE: - Result = (LHSValue >= RHSValue); + Result = -(LHSValue >= RHSValue); break; } @@ -10179,7 +10179,8 @@ bool VisitInitListExpr(const InitListExpr *E); bool VisitUnaryImag(const UnaryOperator *E); bool VisitBinaryOperator(const BinaryOperator *E); - // FIXME: Missing: unary -, unary ~, conditional operator (for GNU + bool VisitUnaryOperator(const UnaryOperator *E); + // FIXME: Missing: unary ~, conditional operator (for GNU // conditional select), shufflevector, ExtVectorElementExpr }; } // end anonymous namespace @@ -10364,6 +10365,43 @@ return Success(LHSValue, E); } +bool VectorExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { + Expr *SubExpr = E->getSubExpr(); + const auto *VD = SubExpr->getType()->castAs<VectorType>(); + UnaryOperatorKind Op = E->getOpcode(); + + APValue SubExprValue; + if (!Evaluate(SubExprValue, Info, SubExpr)) + return false; + + assert(SubExprValue.getVectorLength() == VD->getNumElements() && + "Vector length doesn't match type?"); + + switch (Op) { + default: + // FIXME: Implement the rest of the unary operators. + return false; + case UO_Minus: { + for (unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) { + APValue &Elt = SubExprValue.getVectorElt(EltNum); + if (Elt.getKind() == APValue::Int) { + Elt.setInt(-Elt.getInt()); + } else { + assert(Elt.getKind() == APValue::Float && + "Vector can only be int or float type"); + Elt.setFloat(-Elt.getFloat()); + } + } + break; + } + case UO_Plus: + // Do nothing, Unary plus is a no-op. + break; + } + + return Success(SubExprValue, E); +} + //===----------------------------------------------------------------------===// // Array Evaluation //===----------------------------------------------------------------------===//
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits