[clang] [clang][bytecode] Implement logical operators for vector type (PR #107678)

via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 7 01:55:28 PDT 2024


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


More information about the cfe-commits mailing list