================ @@ -92,6 +92,222 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { mlir::Value VisitCastExpr(CastExpr *E); + // Unary Operators. + mlir::Value VisitUnaryPostDec(const UnaryOperator *e) { + LValue lv = cgf.emitLValue(e->getSubExpr()); + return emitScalarPrePostIncDec(e, lv, false, false); + } + mlir::Value VisitUnaryPostInc(const UnaryOperator *e) { + LValue lv = cgf.emitLValue(e->getSubExpr()); + return emitScalarPrePostIncDec(e, lv, true, false); + } + mlir::Value VisitUnaryPreDec(const UnaryOperator *e) { + LValue lv = cgf.emitLValue(e->getSubExpr()); + return emitScalarPrePostIncDec(e, lv, false, true); + } + mlir::Value VisitUnaryPreInc(const UnaryOperator *e) { + LValue lv = cgf.emitLValue(e->getSubExpr()); + return emitScalarPrePostIncDec(e, lv, true, true); + } + mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv, + bool isInc, bool isPre) { + if (cgf.getLangOpts().OpenMP) + cgf.cgm.errorNYI(e->getSourceRange(), "inc/dec OpenMP"); + + QualType type = e->getSubExpr()->getType(); + + mlir::Value value; + mlir::Value input; + + if (type->getAs<AtomicType>()) { + cgf.cgm.errorNYI(e->getSourceRange(), "Atomic inc/dec"); + // TODO(cir): This is not correct, but it will produce reasonable code + // until atomic operations are implemented. + value = cgf.emitLoadOfLValue(lv, e->getExprLoc()).getScalarVal(); + input = value; + } else { + value = cgf.emitLoadOfLValue(lv, e->getExprLoc()).getScalarVal(); + input = value; + } + + // NOTE: When possible, more frequent cases are handled first. + + // Special case of integer increment that we have to check first: bool++. + // Due to promotion rules, we get: + // bool++ -> bool = bool + 1 + // -> bool = (int)bool + 1 + // -> bool = ((int)bool + 1 != 0) + // An interesting aspect of this is that increment is always true. + // Decrement does not have this property. + if (isInc && type->isBooleanType()) { + value = builder.create<cir::ConstantOp>(cgf.getLoc(e->getExprLoc()), + cgf.convertType(type), + builder.getCIRBoolAttr(true)); + } else if (type->isIntegerType()) { + QualType promotedType; + bool canPerformLossyDemotionCheck = false; + if (cgf.getContext().isPromotableIntegerType(type)) { + promotedType = cgf.getContext().getPromotedIntegerType(type); + assert(promotedType != type && "Shouldn't promote to the same type."); + canPerformLossyDemotionCheck = true; + canPerformLossyDemotionCheck &= + cgf.getContext().getCanonicalType(type) != + cgf.getContext().getCanonicalType(promotedType); + canPerformLossyDemotionCheck &= + type->isIntegerType() && promotedType->isIntegerType(); + + // TODO(cir): Currently, we store bitwidths in CIR types only for + // integers. This might also be required for other types. + auto srcCirTy = mlir::dyn_cast<cir::IntType>(cgf.convertType(type)); + auto promotedCirTy = + mlir::dyn_cast<cir::IntType>(cgf.convertType(type)); + assert(srcCirTy && promotedCirTy && "Expected integer type"); ---------------- erichkeane wrote:
If we're asserting here, those should just be `cast` above, and count on the `cast` assert. https://github.com/llvm/llvm-project/pull/131369 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits