[clang] [clang][bytecode] Implement comparsion operators for vector type (PR #107258)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 5 01:00:20 PDT 2024


================
@@ -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) {
----------------
tbaederr wrote:

I don't think we're going to use this anywhere else, so a separate function shouldn't be necessary

https://github.com/llvm/llvm-project/pull/107258


More information about the cfe-commits mailing list