https://github.com/yronglin created https://github.com/llvm/llvm-project/pull/107678
Implement `&&`, `||` logical operators for vector type. >From b9da0771d479fe5384f6e83bb1e2b75cd48fd5b4 Mon Sep 17 00:00:00 2001 From: yronglin <yronglin...@gmail.com> Date: Sat, 7 Sep 2024 16:53:12 +0800 Subject: [PATCH] [clang][bytecode] Implement logical operators for vector type Signed-off-by: yronglin <yronglin...@gmail.com> --- clang/lib/AST/ByteCode/Compiler.cpp | 23 ++++- clang/test/AST/ByteCode/constexpr-vectors.cpp | 90 +++++++++++++++++++ 2 files changed, 111 insertions(+), 2 deletions(-) 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, ""); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits