[clang] [CIR] Upstream CmpOp (PR #133159)

Bruno Cardoso Lopes via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 28 15:17:36 PDT 2025


================
@@ -710,6 +710,89 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
   HANDLEBINOP(Xor)
   HANDLEBINOP(Or)
 #undef HANDLEBINOP
+
+  mlir::Value emitCmp(const BinaryOperator *e) {
+    mlir::Value result;
+    QualType lhsTy = e->getLHS()->getType();
+    QualType rhsTy = e->getRHS()->getType();
+
+    auto clangCmpToCIRCmp =
+        [](clang::BinaryOperatorKind clangCmp) -> cir::CmpOpKind {
+      switch (clangCmp) {
+      case BO_LT:
+        return cir::CmpOpKind::lt;
+      case BO_GT:
+        return cir::CmpOpKind::gt;
+      case BO_LE:
+        return cir::CmpOpKind::le;
+      case BO_GE:
+        return cir::CmpOpKind::ge;
+      case BO_EQ:
+        return cir::CmpOpKind::eq;
+      case BO_NE:
+        return cir::CmpOpKind::ne;
+      default:
+        llvm_unreachable("unsupported comparison kind");
+      }
+    };
+
+    if (lhsTy->getAs<MemberPointerType>()) {
+      assert(e->getOpcode() == BO_EQ || e->getOpcode() == BO_NE);
+      mlir::Value lhs = cgf.emitScalarExpr(e->getLHS());
+      mlir::Value rhs = cgf.emitScalarExpr(e->getRHS());
+      cir::CmpOpKind kind = clangCmpToCIRCmp(e->getOpcode());
+      result =
+          builder.createCompare(cgf.getLoc(e->getExprLoc()), kind, lhs, rhs);
+    } else if (!lhsTy->isAnyComplexType() && !rhsTy->isAnyComplexType()) {
+      BinOpInfo boInfo = emitBinOps(e);
+      mlir::Value lhs = boInfo.lhs;
+      mlir::Value rhs = boInfo.rhs;
+
+      if (lhsTy->isVectorType()) {
+        assert(!cir::MissingFeatures::vectorType());
+        cgf.cgm.errorNYI(boInfo.loc, "vector comparisons");
+        result = builder.getBool(false, cgf.getLoc(boInfo.loc));
+      } else if (boInfo.isFixedPointOp()) {
+        assert(!cir::MissingFeatures::fixedPointType());
+        cgf.cgm.errorNYI(boInfo.loc, "fixed point comparisons");
+        result = builder.getBool(false, cgf.getLoc(boInfo.loc));
+      } else if (lhsTy->hasSignedIntegerRepresentation()) {
+        cir::CmpOpKind kind = clangCmpToCIRCmp(e->getOpcode());
+        result = builder.createCompare(cgf.getLoc(boInfo.loc), kind, lhs, rhs);
+      } else {
+        // Unsigned integers and pointers.
+        if (cgf.cgm.getCodeGenOpts().StrictVTablePointers &&
+            mlir::isa<cir::PointerType>(lhs.getType()) &&
+            mlir::isa<cir::PointerType>(rhs.getType())) {
+          cgf.cgm.errorNYI(boInfo.loc, "strict vtable pointer comparisons");
+          result = builder.getBool(false, cgf.getLoc(boInfo.loc));
+        }
+
+        cir::CmpOpKind kind = clangCmpToCIRCmp(e->getOpcode());
+        result = builder.createCompare(cgf.getLoc(boInfo.loc), kind, lhs, rhs);
+      }
+    } else {
+      // Complex Comparison: can only be an equality comparison.
+      assert(!cir::MissingFeatures::complexType());
+      const mlir::Location loc = cgf.getLoc(e->getSourceRange());
+      cgf.cgm.errorNYI(loc, "complex comparison");
+      result = builder.getBool(false, loc);
+    }
+
+    return emitScalarConversion(result, cgf.getContext().BoolTy, e->getType(),
+                                e->getExprLoc());
+  }
----------------
bcardosolopes wrote:

>  whether clangir even has some rule of thumb how AST locations are translated to mlir locations

we try to capture what makes more sense w.r.t source code and good diagnostic experience, but I wouldn't claim we have done a diligent process, so I can't attest for the quality. I fixed many bad source locations when working on the lifetime checker, so it's somewhat reliable, but I haven't tested much away from that.

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


More information about the cfe-commits mailing list