[clang] [CIR] Add binary operators (PR #132420)
Andy Kaylor via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 21 14:50:36 PDT 2025
================
@@ -558,8 +624,225 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
return res;
}
+
+ BinOpInfo emitBinOps(const BinaryOperator *e,
+ QualType promotionType = QualType()) {
+ BinOpInfo result;
+ result.lhs = cgf.emitPromotedScalarExpr(e->getLHS(), promotionType);
+ result.rhs = cgf.emitPromotedScalarExpr(e->getRHS(), promotionType);
+ if (!promotionType.isNull())
+ result.fullType = promotionType;
+ else
+ result.fullType = e->getType();
+ result.compType = result.fullType;
+ if (const auto *vecType = dyn_cast_or_null<VectorType>(result.fullType)) {
+ result.compType = vecType->getElementType();
+ }
+ result.opcode = e->getOpcode();
+ result.loc = e->getSourceRange();
+ // TODO(cir): Result.FPFeatures
+ assert(!cir::MissingFeatures::getFPFeaturesInEffect());
+ result.e = e;
+ return result;
+ }
+
+ mlir::Value emitMul(const BinOpInfo &ops);
+ mlir::Value emitDiv(const BinOpInfo &ops);
+ mlir::Value emitRem(const BinOpInfo &ops);
+ mlir::Value emitAdd(const BinOpInfo &ops);
+ mlir::Value emitSub(const BinOpInfo &ops);
+ mlir::Value emitShl(const BinOpInfo &ops);
+ mlir::Value emitShr(const BinOpInfo &ops);
+ mlir::Value emitAnd(const BinOpInfo &ops);
+ mlir::Value emitXor(const BinOpInfo &ops);
+ mlir::Value emitOr(const BinOpInfo &ops);
+
+ LValue emitCompoundAssignLValue(
+ const CompoundAssignOperator *e,
+ mlir::Value (ScalarExprEmitter::*f)(const BinOpInfo &),
+ mlir::Value &result);
+ mlir::Value
+ emitCompoundAssign(const CompoundAssignOperator *e,
+ mlir::Value (ScalarExprEmitter::*f)(const BinOpInfo &));
+
+ // TODO(cir): Candidate to be in a common AST helper between CIR and LLVM
+ // codegen.
+ QualType getPromotionType(QualType ty) {
+ if (ty->getAs<ComplexType>()) {
+ assert(!cir::MissingFeatures::complexType());
+ cgf.cgm.errorNYI("promotion to complex type");
+ return QualType();
+ }
+ if (ty.UseExcessPrecision(cgf.getContext())) {
+ if (ty->getAs<VectorType>()) {
+ assert(!cir::MissingFeatures::vectorType());
+ cgf.cgm.errorNYI("promotion to vector type");
+ return QualType();
+ }
+ return cgf.getContext().FloatTy;
+ }
+ return QualType();
+ }
+
+// Binary operators and binary compound assignment operators.
+#define HANDLEBINOP(OP) \
+ mlir::Value VisitBin##OP(const BinaryOperator *e) { \
+ QualType promotionTy = getPromotionType(e->getType()); \
+ auto result = emit##OP(emitBinOps(e, promotionTy)); \
+ if (result && !promotionTy.isNull()) \
+ result = emitUnPromotedValue(result, e->getType()); \
+ return result; \
+ } \
+ mlir::Value VisitBin##OP##Assign(const CompoundAssignOperator *e) { \
+ return emitCompoundAssign(e, &ScalarExprEmitter::emit##OP); \
+ }
+
+ HANDLEBINOP(Mul)
+ HANDLEBINOP(Div)
+ HANDLEBINOP(Rem)
+ HANDLEBINOP(Add)
+ HANDLEBINOP(Sub)
+ HANDLEBINOP(Shl)
+ HANDLEBINOP(Shr)
+ HANDLEBINOP(And)
+ HANDLEBINOP(Xor)
+ HANDLEBINOP(Or)
+#undef HANDLEBINOP
};
+LValue ScalarExprEmitter::emitCompoundAssignLValue(
+ const CompoundAssignOperator *e,
+ mlir::Value (ScalarExprEmitter::*func)(const BinOpInfo &),
+ mlir::Value &result) {
+ QualType lhsTy = e->getLHS()->getType();
+ BinOpInfo opInfo;
+
+ if (e->getComputationResultType()->isAnyComplexType()) {
+ cgf.cgm.errorNYI(result.getLoc(), "complex lvalue assign");
+ return LValue();
+ }
+
+ // Emit the RHS first. __block variables need to have the rhs evaluated
+ // first, plus this should improve codegen a little.
+
+ QualType promotionTypeCR = getPromotionType(e->getComputationResultType());
+ if (promotionTypeCR.isNull())
+ promotionTypeCR = e->getComputationResultType();
+
+ QualType promotionTypeLHS = getPromotionType(e->getComputationLHSType());
+ QualType promotionTypeRHS = getPromotionType(e->getRHS()->getType());
+
+ if (!promotionTypeRHS.isNull())
+ opInfo.rhs = cgf.emitPromotedScalarExpr(e->getRHS(), promotionTypeRHS);
+ else
+ opInfo.rhs = Visit(e->getRHS());
+
+ opInfo.fullType = promotionTypeCR;
+ opInfo.compType = opInfo.fullType;
+ if (const auto *vecType = dyn_cast_or_null<VectorType>(opInfo.fullType)) {
----------------
andykaylor wrote:
Don't need braces here.
https://github.com/llvm/llvm-project/pull/132420
More information about the cfe-commits
mailing list