-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[CIR] Upstream CmpOp #133159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CIR] Upstream CmpOp #133159
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -707,6 +707,85 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { | |
HANDLEBINOP(Xor) | ||
HANDLEBINOP(Or) | ||
#undef HANDLEBINOP | ||
|
||
mlir::Value emitCmp(const BinaryOperator *e) { | ||
const mlir::Location loc = cgf.getLoc(e->getExprLoc()); | ||
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 for cir.cmp"); | ||
} | ||
}; | ||
|
||
if (lhsTy->getAs<MemberPointerType>()) { | ||
assert(!cir::MissingFeatures::dataMemberType()); | ||
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(loc, 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(loc, "vector comparisons"); | ||
result = builder.getBool(false, loc); | ||
} else if (boInfo.isFixedPointOp()) { | ||
assert(!cir::MissingFeatures::fixedPointType()); | ||
cgf.cgm.errorNYI(loc, "fixed point comparisons"); | ||
result = builder.getBool(false, loc); | ||
} else { | ||
// integers and pointers | ||
if (cgf.cgm.getCodeGenOpts().StrictVTablePointers && | ||
mlir::isa<cir::PointerType>(lhs.getType()) && | ||
mlir::isa<cir::PointerType>(rhs.getType())) { | ||
cgf.cgm.errorNYI(loc, "strict vtable pointer comparisons"); | ||
} | ||
|
||
cir::CmpOpKind kind = clangCmpToCIRCmp(e->getOpcode()); | ||
result = builder.createCompare(loc, kind, lhs, rhs); | ||
} | ||
} else { | ||
// Complex Comparison: can only be an equality comparison. | ||
assert(!cir::MissingFeatures::complexType()); | ||
cgf.cgm.errorNYI(loc, "complex comparison"); | ||
result = builder.getBool(false, loc); | ||
} | ||
|
||
return emitScalarConversion(result, cgf.getContext().BoolTy, e->getType(), | ||
e->getExprLoc()); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a bit of a mess how locations are emitted here:
tbf I am not sure what is correct way, or whether clangir even has some rule of thumb how AST locations are translated to mlir locations. Just the inconsistency caught my eye. @bcardosolopes @andykaylor ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW classic codegen uses In any case I get the Location at the beginning of the function now and store it in a variable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. |
||
|
||
// Comparisons. | ||
#define VISITCOMP(CODE) \ | ||
mlir::Value VisitBin##CODE(const BinaryOperator *E) { return emitCmp(E); } | ||
VISITCOMP(LT) | ||
VISITCOMP(GT) | ||
VISITCOMP(LE) | ||
VISITCOMP(GE) | ||
VISITCOMP(EQ) | ||
VISITCOMP(NE) | ||
#undef VISITCOMP | ||
}; | ||
|
||
LValue ScalarExprEmitter::emitCompoundAssignLValue( | ||
|
Uh oh!
There was an error while loading. Please reload this page.