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

Andy Kaylor via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 31 10:37:30 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());
+  }
----------------
andykaylor wrote:

I agree that we need to look at context to decide which source location/range makes sense. I've seen problems where we were getting source locations from operands rather than from the expression where the operand is used, which was wrong in that case.

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


More information about the cfe-commits mailing list