summaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp67
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);