[clang] cf11eb6 - [clang][bytecode] Implement logical operators for vector type (#107678)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 7 23:04:06 PDT 2024
Author: yronglin
Date: 2024-09-08T14:04:00+08:00
New Revision: cf11eb62e1d0fa41f68b4ca3150eac854ac2e991
URL: https://github.com/llvm/llvm-project/commit/cf11eb62e1d0fa41f68b4ca3150eac854ac2e991
DIFF: https://github.com/llvm/llvm-project/commit/cf11eb62e1d0fa41f68b4ca3150eac854ac2e991.diff
LOG: [clang][bytecode] Implement logical operators for vector type (#107678)
Implement `&&`, `||` logical operators for vector type.
---------
Signed-off-by: yronglin <yronglin777 at gmail.com>
Added:
Modified:
clang/lib/AST/ByteCode/Compiler.cpp
clang/test/AST/ByteCode/constexpr-vectors.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 46f9c98d59befc..43268bafc387bd 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -1232,7 +1232,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 +1267,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 +1308,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, "");
More information about the cfe-commits
mailing list