https://github.com/yronglin updated https://github.com/llvm/llvm-project/pull/107258
>From ae9fd2653ef3f5d6323c8c8e857fbf45f394f0ce Mon Sep 17 00:00:00 2001 From: yronglin <yronglin...@gmail.com> Date: Wed, 4 Sep 2024 23:31:16 +0800 Subject: [PATCH 1/2] [clang][bytecode] Implement comparsion operators for vector type Signed-off-by: yronglin <yronglin...@gmail.com> --- clang/lib/AST/ByteCode/Compiler.cpp | 113 ++++++++++ clang/lib/AST/ByteCode/Compiler.h | 3 +- clang/test/AST/ByteCode/constexpr-vectors.cpp | 212 +++++++++++++++++- 3 files changed, 323 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index a831f196abdcb5..c3fb812971ac52 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -687,6 +687,8 @@ bool Compiler<Emitter>::VisitParenExpr(const ParenExpr *E) { template <class Emitter> bool Compiler<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) { // Need short-circuiting for these. + if (BO->getType()->isVectorType()) + return this->VisitVectorBinOp(BO); if (BO->isLogicalOp()) return this->VisitLogicalBinOp(BO); @@ -1222,6 +1224,117 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) { return true; } +template <class Emitter> +bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) { + assert(E->getType()->isVectorType()); + + // FIXME: Current only support comparison binary operator, add support for + // other binary operator. + if (!E->isComparisonOp()) + return this->emitInvalid(E); + // Prepare storage for result. + if (!Initializing) { + unsigned LocalIndex = allocateTemporary(E); + if (!this->emitGetPtrLocal(LocalIndex, E)) + return false; + } + + const Expr *LHS = E->getLHS(); + const Expr *RHS = E->getRHS(); + const auto *VecTy = E->getType()->getAs<VectorType>(); + + // The LHS and RHS of a comparison operator must have the same type. So we + // just use LHS vector element type here. + PrimType ElemT = this->classifyVectorElementType(LHS->getType()); + PrimType ResultElemT = this->classifyVectorElementType(E->getType()); + + // Evaluate LHS and save value to LHSOffset. + unsigned LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false); + if (!this->visit(LHS)) + return false; + if (!this->emitSetLocal(PT_Ptr, LHSOffset, E)) + return false; + + // Evaluate RHS and save value to RHSOffset. + unsigned RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false); + if (!this->visit(RHS)) + return false; + if (!this->emitSetLocal(PT_Ptr, RHSOffset, E)) + return false; + + auto getElem = [=](unsigned Offset, unsigned Index, PrimType ElemT) -> bool { + if (!this->emitGetLocal(PT_Ptr, Offset, E)) + return false; + return this->emitArrayElemPop(ElemT, Index, E); + }; + + for (unsigned I = 0; I != VecTy->getNumElements(); ++I) { + if (!getElem(LHSOffset, I, ElemT)) + return false; + if (!getElem(RHSOffset, I, ElemT)) + return false; + if (E->isComparisonOp()) { + if (!this->emitVectorComparison(E)) + return false; + } else { + llvm_unreachable("Unsupported binary operator"); + } + if (!this->emitInitElem(ResultElemT, I, E)) + return false; + } + return true; +} + +template <class Emitter> +bool Compiler<Emitter>::emitVectorComparison(const BinaryOperator *E) { + assert(E->isComparisonOp()); + assert(!DiscardResult); + const auto *VecTy = E->getType()->getAs<VectorType>(); + + // The LHS and RHS of a comparison operator must have the same type. So we + // just use LHS vector element type here. + PrimType LHSElemT = this->classifyVectorElementType(E->getLHS()->getType()); + PrimType ResultElemT = this->classifyVectorElementType(E->getType()); + switch (E->getOpcode()) { + case BO_EQ: + if (!this->emitEQ(LHSElemT, E)) + return false; + break; + case BO_NE: + if (!this->emitNE(LHSElemT, E)) + return false; + break; + case BO_LE: + if (!this->emitLE(LHSElemT, E)) + return false; + break; + case BO_LT: + if (!this->emitLT(LHSElemT, E)) + return false; + break; + case BO_GE: + if (!this->emitGE(LHSElemT, E)) + return false; + break; + case BO_GT: + if (!this->emitGT(LHSElemT, E)) + return false; + break; + default: + llvm_unreachable("Unsupported binary operator"); + } + + // The result of the comparison is a vector of the same width and number of + // elements as the comparison operands with a signed integral element type. + // + // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html + if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E)) + return false; + if (!this->emitNeg(ResultElemT, E)) + return false; + return true; +} + template <class Emitter> bool Compiler<Emitter>::VisitImplicitValueInitExpr( const ImplicitValueInitExpr *E) { diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index b18afacdb2e491..c9dacbc76d7c4f 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -130,6 +130,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, bool VisitLogicalBinOp(const BinaryOperator *E); bool VisitPointerArithBinOp(const BinaryOperator *E); bool VisitComplexBinOp(const BinaryOperator *E); + bool VisitVectorBinOp(const BinaryOperator *E); bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E); bool VisitCallExpr(const CallExpr *E); bool VisitBuiltinCallExpr(const CallExpr *E); @@ -363,7 +364,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, bool emitComplexBoolCast(const Expr *E); bool emitComplexComparison(const Expr *LHS, const Expr *RHS, const BinaryOperator *E); - + bool emitVectorComparison(const BinaryOperator *E); bool emitRecordDestruction(const Record *R); bool emitDestruction(const Descriptor *Desc); unsigned collectBaseOffset(const QualType BaseType, diff --git a/clang/test/AST/ByteCode/constexpr-vectors.cpp b/clang/test/AST/ByteCode/constexpr-vectors.cpp index a738cfe617a0e0..684c5810702cc3 100644 --- a/clang/test/AST/ByteCode/constexpr-vectors.cpp +++ b/clang/test/AST/ByteCode/constexpr-vectors.cpp @@ -15,8 +15,50 @@ using FourI128ExtVec __attribute__((ext_vector_type(4))) = __int128; // 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 H = FourCharsVecSize{-1, -1, 0, -1}; - constexpr auto InvH = -H; + constexpr auto w = FourCharsVecSize{1, 2, 3, 4} < + FourCharsVecSize{4, 3, 2, 1}; + static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, ""); + + constexpr auto x = FourCharsVecSize{1, 2, 3, 4} > + FourCharsVecSize{4, 3, 2, 1}; + static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[3] == -1, ""); + + constexpr auto y = FourCharsVecSize{1, 2, 3, 4} <= + FourCharsVecSize{4, 3, 3, 1}; + static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, ""); + + constexpr auto z = FourCharsVecSize{1, 2, 3, 4} >= + FourCharsVecSize{4, 3, 3, 1}; + static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, ""); + + constexpr auto A = FourCharsVecSize{1, 2, 3, 4} == + FourCharsVecSize{4, 3, 3, 1}; + static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, ""); + + constexpr auto B = FourCharsVecSize{1, 2, 3, 4} != + FourCharsVecSize{4, 3, 3, 1}; + static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, ""); + + constexpr auto C = FourCharsVecSize{1, 2, 3, 4} < 3; + static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, ""); + + constexpr auto D = FourCharsVecSize{1, 2, 3, 4} > 3; + static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, ""); + + constexpr auto E = FourCharsVecSize{1, 2, 3, 4} <= 3; + static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, ""); + + constexpr auto F = FourCharsVecSize{1, 2, 3, 4} >= 3; + static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, ""); + + constexpr auto G = FourCharsVecSize{1, 2, 3, 4} == 3; + static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, ""); + + constexpr auto H = FourCharsVecSize{1, 2, 3, 4} != 3; + static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, ""); + + constexpr auto H1 = FourCharsVecSize{-1, -1, 0, -1}; + constexpr auto InvH = -H1; static_assert(InvH[0] == 1 && InvH[1] == 1 && InvH[2] == 0 && InvH[3] == 1, ""); constexpr auto ae = ~FourCharsVecSize{1, 2, 10, 20}; @@ -27,8 +69,50 @@ void CharUsage() { } void CharExtVecUsage() { - constexpr auto H = FourCharsExtVec{-1, -1, 0, -1}; - constexpr auto InvH = -H; + constexpr auto w = FourCharsExtVec{1, 2, 3, 4} < + FourCharsExtVec{4, 3, 2, 1}; + static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, ""); + + constexpr auto x = FourCharsExtVec{1, 2, 3, 4} > + FourCharsExtVec{4, 3, 2, 1}; + static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[3] == -1, ""); + + constexpr auto y = FourCharsExtVec{1, 2, 3, 4} <= + FourCharsExtVec{4, 3, 3, 1}; + static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, ""); + + constexpr auto z = FourCharsExtVec{1, 2, 3, 4} >= + FourCharsExtVec{4, 3, 3, 1}; + static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, ""); + + constexpr auto A = FourCharsExtVec{1, 2, 3, 4} == + FourCharsExtVec{4, 3, 3, 1}; + static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, ""); + + constexpr auto B = FourCharsExtVec{1, 2, 3, 4} != + FourCharsExtVec{4, 3, 3, 1}; + static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, ""); + + constexpr auto C = FourCharsExtVec{1, 2, 3, 4} < 3; + static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, ""); + + constexpr auto D = FourCharsExtVec{1, 2, 3, 4} > 3; + static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, ""); + + constexpr auto E = FourCharsExtVec{1, 2, 3, 4} <= 3; + static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, ""); + + constexpr auto F = FourCharsExtVec{1, 2, 3, 4} >= 3; + static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, ""); + + constexpr auto G = FourCharsExtVec{1, 2, 3, 4} == 3; + static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, ""); + + constexpr auto H = FourCharsExtVec{1, 2, 3, 4} != 3; + static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, ""); + + constexpr auto H1 = FourCharsExtVec{-1, -1, 0, -1}; + constexpr auto InvH = -H1; static_assert(InvH[0] == 1 && InvH[1] == 1 && InvH[2] == 0 && InvH[3] == 1, ""); constexpr auto ae = ~FourCharsExtVec{1, 2, 10, 20}; @@ -39,6 +123,48 @@ void CharExtVecUsage() { } void FloatUsage() { + constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} < + FourFloatsVecSize{4, 3, 2, 1}; + static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, ""); + + constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} > + FourFloatsVecSize{4, 3, 2, 1}; + static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[3] == -1, ""); + + constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <= + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, ""); + + constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >= + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, ""); + + constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} == + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, ""); + + constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} != + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, ""); + + constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3; + static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, ""); + + constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3; + static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, ""); + + constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3; + static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, ""); + + constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3; + static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, ""); + + constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3; + static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, ""); + + constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3; + static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, ""); + constexpr auto Y = FourFloatsVecSize{1.200000e+01, 1.700000e+01, -1.000000e+00, -1.000000e+00}; constexpr auto Z = -Y; static_assert(Z[0] == -1.200000e+01 && Z[1] == -1.700000e+01 && Z[2] == 1.000000e+00 && Z[3] == 1.000000e+00, ""); @@ -51,6 +177,48 @@ void FloatUsage() { } void FloatVecUsage() { + constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} < + FourFloatsVecSize{4, 3, 2, 1}; + static_assert(w[0] == -1 && w[1] == -1 && w[2] == 0 && w[3] == 0, ""); + + constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} > + FourFloatsVecSize{4, 3, 2, 1}; + static_assert(x[0] == 0 && x[1] == 0 && x[2] == -1 && x[2] == -1, ""); + + constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <= + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(y[0] == -1 && y[1] == -1 && y[2] == -1 && y[3] == 0, ""); + + constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >= + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(z[0] == 0 && z[1] == 0 && z[2] == -1 && z[3] == -1, ""); + + constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} == + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(A[0] == 0 && A[1] == 0 && A[2] == -1 && A[3] == 0, ""); + + constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} != + FourFloatsVecSize{4, 3, 3, 1}; + static_assert(B[0] == -1 && B[1] == -1 && B[2] == 0 && B[3] == -1, ""); + + constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3; + static_assert(C[0] == -1 && C[1] == -1 && C[2] == 0 && C[3] == 0, ""); + + constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3; + static_assert(D[0] == 0 && D[1] == 0 && D[2] == 0 && D[3] == -1, ""); + + constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3; + static_assert(E[0] == -1 && E[1] == -1 && E[2] == -1 && E[3] == 0, ""); + + constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3; + static_assert(F[0] == 0 && F[1] == 0 && F[2] == -1 && F[3] == -1, ""); + + constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3; + static_assert(G[0] == 0 && G[1] == 0 && G[2] == -1 && G[3] == 0, ""); + + constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3; + static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, ""); + constexpr auto Y = FourFloatsVecSize{1.200000e+01, 1.700000e+01, -1.000000e+00, -1.000000e+00}; constexpr auto Z = -Y; static_assert(Z[0] == -1.200000e+01 && Z[1] == -1.700000e+01 && Z[2] == 1.000000e+00 && Z[3] == 1.000000e+00, ""); @@ -63,6 +231,12 @@ void FloatVecUsage() { } void I128Usage() { + constexpr auto a = FourI128VecSize{1, 2, 3, 4}; + static_assert(a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4, ""); + + constexpr auto b = a < 3; + static_assert(b[0] == -1 && b[1] == -1 && b[2] == 0 && b[3] == 0, ""); + // Operator ~ is illegal on floats, so no test for that. constexpr auto c = ~FourI128VecSize{1, 2, 10, 20}; static_assert(c[0] == -2 && c[1] == -3 && c[2] == -11 && c[3] == -21, ""); @@ -72,6 +246,12 @@ void I128Usage() { } void I128VecUsage() { + constexpr auto a = FourI128ExtVec{1, 2, 3, 4}; + static_assert(a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4, ""); + + constexpr auto b = a < 3; + static_assert(b[0] == -1 && b[1] == -1 && b[2] == 0 && b[3] == 0, ""); + // Operator ~ is illegal on floats, so no test for that. constexpr auto c = ~FourI128ExtVec{1, 2, 10, 20}; static_assert(c[0] == -2 && c[1] == -3 && c[2] == -11 && c[3] == -21, ""); @@ -82,6 +262,30 @@ void I128VecUsage() { using FourBoolsExtVec __attribute__((ext_vector_type(4))) = bool; void BoolVecUsage() { + constexpr auto a = FourBoolsExtVec{true, false, true, false} < + FourBoolsExtVec{false, false, true, true}; + static_assert(a[0] == false && a[1] == false && a[2] == false && a[3] == true, ""); + + constexpr auto b = FourBoolsExtVec{true, false, true, false} <= + FourBoolsExtVec{false, false, true, true}; + static_assert(b[0] == false && b[1] == true && b[2] == true && b[3] == true, ""); + + constexpr auto c = FourBoolsExtVec{true, false, true, false} == + FourBoolsExtVec{false, false, true, true}; + static_assert(c[0] == false && c[1] == true && c[2] == true && c[3] == false, ""); + + constexpr auto d = FourBoolsExtVec{true, false, true, false} != + FourBoolsExtVec{false, false, true, true}; + static_assert(d[0] == true && d[1] == false && d[2] == false && d[3] == true, ""); + + constexpr auto e = FourBoolsExtVec{true, false, true, false} >= + FourBoolsExtVec{false, false, true, true}; + static_assert(e[0] == true && e[1] == true && e[2] == true && e[3] == false, ""); + + constexpr auto f = FourBoolsExtVec{true, false, true, false} > + FourBoolsExtVec{false, false, true, true}; + static_assert(f[0] == true && f[1] == false && f[2] == false && f[3] == false, ""); + constexpr auto j = !FourBoolsExtVec{true, false, true, false}; static_assert(j[0] == false && j[1] == true && j[2] == false && j[3] == true, ""); >From e0148f41fa34fc6f1f7b31af07060e1e7df6c1cc Mon Sep 17 00:00:00 2001 From: yronglin <yronglin...@gmail.com> Date: Thu, 5 Sep 2024 21:03:38 +0800 Subject: [PATCH 2/2] Remove unnecessary emitVectorComparsion Signed-off-by: yronglin <yronglin...@gmail.com> --- clang/lib/AST/ByteCode/Compiler.cpp | 90 +++++++++++++---------------- clang/lib/AST/ByteCode/Compiler.h | 1 - 2 files changed, 39 insertions(+), 52 deletions(-) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index c3fb812971ac52..22134725c4dfad 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -1227,6 +1227,8 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) { template <class Emitter> bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) { assert(E->getType()->isVectorType()); + assert(E->getLHS()->getType()->isVectorType()); + assert(E->getRHS()->getType()->isVectorType()); // FIXME: Current only support comparison binary operator, add support for // other binary operator. @@ -1274,7 +1276,43 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) { if (!getElem(RHSOffset, I, ElemT)) return false; if (E->isComparisonOp()) { - if (!this->emitVectorComparison(E)) + switch (E->getOpcode()) { + case BO_EQ: + if (!this->emitEQ(ElemT, E)) + return false; + break; + case BO_NE: + if (!this->emitNE(ElemT, E)) + return false; + break; + case BO_LE: + if (!this->emitLE(ElemT, E)) + return false; + break; + case BO_LT: + if (!this->emitLT(ElemT, E)) + return false; + break; + case BO_GE: + if (!this->emitGE(ElemT, E)) + return false; + break; + case BO_GT: + if (!this->emitGT(ElemT, E)) + return false; + break; + default: + llvm_unreachable("Unsupported binary operator"); + } + + // The result of the comparison is a vector of the same width and number + // of elements as the comparison operands with a signed integral element + // type. + // + // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html + if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E)) + return false; + if (!this->emitNeg(ResultElemT, E)) return false; } else { llvm_unreachable("Unsupported binary operator"); @@ -1285,56 +1323,6 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) { return true; } -template <class Emitter> -bool Compiler<Emitter>::emitVectorComparison(const BinaryOperator *E) { - assert(E->isComparisonOp()); - assert(!DiscardResult); - const auto *VecTy = E->getType()->getAs<VectorType>(); - - // The LHS and RHS of a comparison operator must have the same type. So we - // just use LHS vector element type here. - PrimType LHSElemT = this->classifyVectorElementType(E->getLHS()->getType()); - PrimType ResultElemT = this->classifyVectorElementType(E->getType()); - switch (E->getOpcode()) { - case BO_EQ: - if (!this->emitEQ(LHSElemT, E)) - return false; - break; - case BO_NE: - if (!this->emitNE(LHSElemT, E)) - return false; - break; - case BO_LE: - if (!this->emitLE(LHSElemT, E)) - return false; - break; - case BO_LT: - if (!this->emitLT(LHSElemT, E)) - return false; - break; - case BO_GE: - if (!this->emitGE(LHSElemT, E)) - return false; - break; - case BO_GT: - if (!this->emitGT(LHSElemT, E)) - return false; - break; - default: - llvm_unreachable("Unsupported binary operator"); - } - - // The result of the comparison is a vector of the same width and number of - // elements as the comparison operands with a signed integral element type. - // - // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html - if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E)) - return false; - if (!this->emitNeg(ResultElemT, E)) - return false; - return true; -} - template <class Emitter> bool Compiler<Emitter>::VisitImplicitValueInitExpr( const ImplicitValueInitExpr *E) { diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index c9dacbc76d7c4f..e6f54fe05427b7 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -364,7 +364,6 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, bool emitComplexBoolCast(const Expr *E); bool emitComplexComparison(const Expr *LHS, const Expr *RHS, const BinaryOperator *E); - bool emitVectorComparison(const BinaryOperator *E); bool emitRecordDestruction(const Record *R); bool emitDestruction(const Descriptor *Desc); unsigned collectBaseOffset(const QualType BaseType, _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits