================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits