diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp')
| -rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index cb83691b4452..0a22771378ff 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -56,7 +56,28 @@ public: mlir::Value VisitParenExpr(ParenExpr *e); mlir::Value VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e); + + mlir::Value VisitPrePostIncDec(const UnaryOperator *e, bool isInc, + bool isPre); + + mlir::Value VisitUnaryPostDec(const UnaryOperator *e) { + return VisitPrePostIncDec(e, false, false); + } + + mlir::Value VisitUnaryPostInc(const UnaryOperator *e) { + return VisitPrePostIncDec(e, true, false); + } + + mlir::Value VisitUnaryPreDec(const UnaryOperator *e) { + return VisitPrePostIncDec(e, false, true); + } + + mlir::Value VisitUnaryPreInc(const UnaryOperator *e) { + return VisitPrePostIncDec(e, true, true); + } + mlir::Value VisitUnaryDeref(const Expr *e); + mlir::Value VisitUnaryNot(const UnaryOperator *e); struct BinOpInfo { mlir::Location loc; @@ -74,6 +95,7 @@ public: mlir::Value emitPromotedComplexOperand(const Expr *e, QualType promotionTy); mlir::Value emitBinAdd(const BinOpInfo &op); + mlir::Value emitBinSub(const BinOpInfo &op); QualType getPromotionType(QualType ty, bool isDivOpCode = false) { if (auto *complexTy = ty->getAs<ComplexType>()) { @@ -105,6 +127,7 @@ public: } HANDLEBINOP(Add) + HANDLEBINOP(Sub) #undef HANDLEBINOP }; } // namespace @@ -228,8 +251,7 @@ mlir::Value ComplexExprEmitter::VisitBinComma(const BinaryOperator *e) { mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) { if (e->getCallReturnType(cgf.getContext())->isReferenceType()) return emitLoadOfLValue(e); - - return cgf.emitCallExpr(e).getValue(); + return cgf.emitCallExpr(e).getComplexValue(); } mlir::Value ComplexExprEmitter::VisitCastExpr(CastExpr *e) { @@ -332,10 +354,21 @@ mlir::Value ComplexExprEmitter::VisitSubstNonTypeTemplateParmExpr( return Visit(e->getReplacement()); } +mlir::Value ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *e, + bool isInc, bool isPre) { + LValue lv = cgf.emitLValue(e->getSubExpr()); + return cgf.emitComplexPrePostIncDec(e, lv, isInc, isPre); +} + mlir::Value ComplexExprEmitter::VisitUnaryDeref(const Expr *e) { return emitLoadOfLValue(e); } +mlir::Value ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *e) { + mlir::Value op = Visit(e->getSubExpr()); + return builder.createNot(op); +} + mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e, QualType promotionTy) { e = e->IgnoreParens(); @@ -345,6 +378,7 @@ mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e, case BO_##OP: \ return emitBin##OP(emitBinOps(bo, promotionTy)); HANDLE_BINOP(Add) + HANDLE_BINOP(Sub) #undef HANDLE_BINOP default: break; @@ -390,6 +424,12 @@ mlir::Value ComplexExprEmitter::emitBinAdd(const BinOpInfo &op) { return builder.create<cir::ComplexAddOp>(op.loc, op.lhs, op.rhs); } +mlir::Value ComplexExprEmitter::emitBinSub(const BinOpInfo &op) { + assert(!cir::MissingFeatures::fastMathFlags()); + assert(!cir::MissingFeatures::cgFPOptionsRAII()); + return builder.create<cir::ComplexSubOp>(op.loc, op.lhs, op.rhs); +} + LValue CIRGenFunction::emitComplexAssignmentLValue(const BinaryOperator *e) { assert(e->getOpcode() == BO_Assign && "Expected assign op"); @@ -408,6 +448,29 @@ mlir::Value CIRGenFunction::emitComplexExpr(const Expr *e) { return ComplexExprEmitter(*this).Visit(const_cast<Expr *>(e)); } +mlir::Value CIRGenFunction::emitComplexPrePostIncDec(const UnaryOperator *e, + LValue lv, bool isInc, + bool isPre) { + mlir::Value inVal = emitLoadOfComplex(lv, e->getExprLoc()); + mlir::Location loc = getLoc(e->getExprLoc()); + auto opKind = isInc ? cir::UnaryOpKind::Inc : cir::UnaryOpKind::Dec; + mlir::Value incVal = builder.createUnaryOp(loc, opKind, inVal); + + // Store the updated result through the lvalue. + emitStoreOfComplex(loc, incVal, lv, /*isInit=*/false); + + if (getLangOpts().OpenMP) + cgm.errorNYI(loc, "emitComplexPrePostIncDec OpenMP"); + + // If this is a postinc, return the value read from memory, otherwise use the + // updated value. + return isPre ? incVal : inVal; +} + +mlir::Value CIRGenFunction::emitLoadOfComplex(LValue src, SourceLocation loc) { + return ComplexExprEmitter(*this).emitLoadOfLValue(src, loc); +} + void CIRGenFunction::emitStoreOfComplex(mlir::Location loc, mlir::Value v, LValue dest, bool isInit) { ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit); |
