llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: None (yronglin) <details> <summary>Changes</summary> Implement `&&`, `||` logical operators for vector type. --- Full diff: https://github.com/llvm/llvm-project/pull/107678.diff 2 Files Affected: - (modified) clang/lib/AST/ByteCode/Compiler.cpp (+21-2) - (modified) clang/test/AST/ByteCode/constexpr-vectors.cpp (+90) ``````````diff diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index eea77c2f0a9bb4..0dd690a69dca71 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -15,6 +15,7 @@ #include "PrimType.h" #include "Program.h" #include "clang/AST/Attr.h" +#include "clang/AST/OperationKinds.h" using namespace clang; using namespace clang::interp; @@ -1232,7 +1233,7 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) { // FIXME: Current only support comparison binary operator, add support for // other binary operator. - if (!E->isComparisonOp()) + if (!E->isComparisonOp() && !E->isLogicalOp()) return this->emitInvalid(E); // Prepare storage for result. if (!Initializing) { @@ -1267,7 +1268,15 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) { auto getElem = [=](unsigned Offset, unsigned Index) { if (!this->emitGetLocal(PT_Ptr, Offset, E)) return false; - return this->emitArrayElemPop(ElemT, Index, E); + if (!this->emitArrayElemPop(ElemT, Index, E)) + return false; + if (E->isLogicalOp()) { + if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E)) + return false; + if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E)) + return false; + } + return true; }; for (unsigned I = 0; I != VecTy->getNumElements(); ++I) { @@ -1300,6 +1309,16 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) { if (!this->emitGT(ElemT, E)) return false; break; + case BO_LAnd: + // a && b is equivalent to a!=0 & b!=0 + if (!this->emitBitAnd(ResultElemT, E)) + return false; + break; + case BO_LOr: + // a || b is equivalent to a!=0 | b!=0 + if (!this->emitBitOr(ResultElemT, E)) + return false; + break; default: llvm_unreachable("Unsupported binary operator"); } diff --git a/clang/test/AST/ByteCode/constexpr-vectors.cpp b/clang/test/AST/ByteCode/constexpr-vectors.cpp index 684c5810702cc3..7a65b263784586 100644 --- a/clang/test/AST/ByteCode/constexpr-vectors.cpp +++ b/clang/test/AST/ByteCode/constexpr-vectors.cpp @@ -57,6 +57,20 @@ void CharUsage() { 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 O = FourCharsVecSize{5, 0, 6, 0} && + FourCharsVecSize{5, 5, 0, 0}; + static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, ""); + + constexpr auto P = FourCharsVecSize{5, 0, 6, 0} || + FourCharsVecSize{5, 5, 0, 0}; + static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, ""); + + constexpr auto Q = FourCharsVecSize{5, 0, 6, 0} && 3; + static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, ""); + + constexpr auto R = FourCharsVecSize{5, 0, 6, 0} || 3; + static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[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, ""); @@ -111,6 +125,21 @@ void CharExtVecUsage() { 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 O = FourCharsExtVec{5, 0, 6, 0} && + FourCharsExtVec{5, 5, 0, 0}; + static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, ""); + + constexpr auto P = FourCharsExtVec{5, 0, 6, 0} || + FourCharsExtVec{5, 5, 0, 0}; + static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, ""); + + constexpr auto Q = FourCharsExtVec{5, 0, 6, 0} && 3; + static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, ""); + + constexpr auto R = FourCharsExtVec{5, 0, 6, 0} || 3; + static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[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, ""); @@ -165,10 +194,33 @@ void FloatUsage() { 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 O1 = FourFloatsVecSize{5, 0, 6, 0} && + FourFloatsVecSize{5, 5, 0, 0}; + static_assert(O1[0] == 1 && O1[1] == 0 && O1[2] == 0 && O1[3] == 0, ""); + + constexpr auto P1 = FourFloatsVecSize{5, 0, 6, 0} || + FourFloatsVecSize{5, 5, 0, 0}; + static_assert(P1[0] == 1 && P1[1] == 1 && P1[2] == 1 && P1[3] == 0, ""); + + constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3; + static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, ""); + + constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3; + static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[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, ""); + constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} && + FourFloatsVecSize{5, 5, 0, 0}; + static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, ""); + + constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} || + FourFloatsVecSize{5, 5, 0, 0}; + static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, ""); + // Operator ~ is illegal on floats. constexpr auto ae = ~FourFloatsVecSize{0, 1, 8, -1}; // expected-error {{invalid argument type}} @@ -219,6 +271,20 @@ void FloatVecUsage() { 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 O = FourFloatsVecSize{5, 0, 6, 0} && + FourFloatsVecSize{5, 5, 0, 0}; + static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, ""); + + constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} || + FourFloatsVecSize{5, 5, 0, 0}; + static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, ""); + + constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3; + static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, ""); + + constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3; + static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[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, ""); @@ -234,6 +300,18 @@ 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 a1 = FourI128VecSize{5, 0, 6, 0} && FourI128VecSize{5, 5, 0, 0}; + static_assert(a1[0] == 1 && a1[1] == 0 && a1[2] == 0 && a1[3] == 0, ""); + + constexpr auto a2 = FourI128VecSize{5, 0, 6, 0} || FourI128VecSize{5, 5, 0, 0}; + static_assert(a2[0] == 1 && a2[1] == 1 && a2[2] == 1 && a2[3] == 0, ""); + + constexpr auto Q = FourI128VecSize{5, 0, 6, 0} && 3; + static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, ""); + + constexpr auto R = FourI128VecSize{5, 0, 6, 0} || 3; + static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, ""); + constexpr auto b = a < 3; static_assert(b[0] == -1 && b[1] == -1 && b[2] == 0 && b[3] == 0, ""); @@ -249,6 +327,18 @@ 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 a1 = FourI128ExtVec{5, 0, 6, 0} && FourI128ExtVec{5, 5, 0, 0}; + static_assert(a1[0] == 1 && a1[1] == 0 && a1[2] == 0 && a1[3] == 0, ""); + + constexpr auto a2 = FourI128ExtVec{5, 0, 6, 0} || FourI128ExtVec{5, 5, 0, 0}; + static_assert(a2[0] == 1 && a2[1] == 1 && a2[2] == 1 && a2[3] == 0, ""); + + constexpr auto Q = FourI128ExtVec{5, 0, 6, 0} && 3; + static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, ""); + + constexpr auto R = FourI128ExtVec{5, 0, 6, 0} || 3; + static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, ""); + constexpr auto b = a < 3; static_assert(b[0] == -1 && b[1] == -1 && b[2] == 0 && b[3] == 0, ""); `````````` </details> https://github.com/llvm/llvm-project/pull/107678 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits