@@ -116,6 +116,15 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
116
116
117
117
mlir::Value emitPromotedComplexOperand (const Expr *e, QualType promotionTy);
118
118
119
+ LValue emitCompoundAssignLValue (
120
+ const CompoundAssignOperator *e,
121
+ mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &),
122
+ RValue &value);
123
+
124
+ mlir::Value emitCompoundAssign (
125
+ const CompoundAssignOperator *e,
126
+ mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &));
127
+
119
128
mlir::Value emitBinAdd (const BinOpInfo &op);
120
129
mlir::Value emitBinSub (const BinOpInfo &op);
121
130
mlir::Value emitBinMul (const BinOpInfo &op);
@@ -153,6 +162,15 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
153
162
HANDLEBINOP(Sub)
154
163
HANDLEBINOP(Mul)
155
164
#undef HANDLEBINOP
165
+
166
+ // Compound assignments.
167
+ mlir::Value VisitBinAddAssign (const CompoundAssignOperator *e) {
168
+ return emitCompoundAssign (e, &ComplexExprEmitter::emitBinAdd);
169
+ }
170
+
171
+ mlir::Value VisitBinSubAssign (const CompoundAssignOperator *e) {
172
+ return emitCompoundAssign (e, &ComplexExprEmitter::emitBinSub);
173
+ }
156
174
};
157
175
} // namespace
158
176
@@ -166,6 +184,12 @@ static const ComplexType *getComplexType(QualType type) {
166
184
}
167
185
#endif // NDEBUG
168
186
187
+ static mlir::Value createComplexFromReal (CIRGenBuilderTy &builder,
188
+ mlir::Location loc, mlir::Value real) {
189
+ mlir::Value imag = builder.getNullValue (real.getType (), loc);
190
+ return builder.createComplexCreate (loc, real, imag);
191
+ }
192
+
169
193
LValue ComplexExprEmitter::emitBinAssignLValue (const BinaryOperator *e,
170
194
mlir::Value &value) {
171
195
assert (cgf.getContext ().hasSameUnqualifiedType (e->getLHS ()->getType (),
@@ -602,7 +626,7 @@ mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e,
602
626
603
627
mlir::Value result = Visit (const_cast <Expr *>(e));
604
628
if (!promotionTy.isNull ())
605
- cgf.cgm . errorNYI ( " emitPromoted emitPromotedValue " );
629
+ return cgf.emitPromotedValue (result, promotionTy );
606
630
607
631
return result;
608
632
}
@@ -630,6 +654,104 @@ ComplexExprEmitter::emitBinOps(const BinaryOperator *e, QualType promotionTy) {
630
654
return binOpInfo;
631
655
}
632
656
657
+ LValue ComplexExprEmitter::emitCompoundAssignLValue (
658
+ const CompoundAssignOperator *e,
659
+ mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &), RValue &value) {
660
+ QualType lhsTy = e->getLHS ()->getType ();
661
+ QualType rhsTy = e->getRHS ()->getType ();
662
+ SourceLocation exprLoc = e->getExprLoc ();
663
+ mlir::Location loc = cgf.getLoc (exprLoc);
664
+
665
+ if (lhsTy->getAs <AtomicType>()) {
666
+ cgf.cgm .errorNYI (" emitCompoundAssignLValue AtmoicType" );
667
+ return {};
668
+ }
669
+
670
+ BinOpInfo opInfo{loc};
671
+ opInfo.fpFeatures = e->getFPFeaturesInEffect (cgf.getLangOpts ());
672
+
673
+ assert (!cir::MissingFeatures::cgFPOptionsRAII ());
674
+
675
+ // Load the RHS and LHS operands.
676
+ // __block variables need to have the rhs evaluated first, plus this should
677
+ // improve codegen a little.
678
+ QualType promotionTypeCR = getPromotionType (e->getComputationResultType ());
679
+ opInfo.ty = promotionTypeCR.isNull () ? e->getComputationResultType ()
680
+ : promotionTypeCR;
681
+
682
+ QualType complexElementTy =
683
+ opInfo.ty ->castAs <ComplexType>()->getElementType ();
684
+ QualType promotionTypeRHS = getPromotionType (rhsTy);
685
+
686
+ // The RHS should have been converted to the computation type.
687
+ if (e->getRHS ()->getType ()->isRealFloatingType ()) {
688
+ if (!promotionTypeRHS.isNull ()) {
689
+ opInfo.rhs = createComplexFromReal (
690
+ cgf.getBuilder (), loc,
691
+ cgf.emitPromotedScalarExpr (e->getRHS (), promotionTypeRHS));
692
+ } else {
693
+ assert (cgf.getContext ().hasSameUnqualifiedType (complexElementTy, rhsTy));
694
+ opInfo.rhs = createComplexFromReal (cgf.getBuilder (), loc,
695
+ cgf.emitScalarExpr (e->getRHS ()));
696
+ }
697
+ } else {
698
+ if (!promotionTypeRHS.isNull ()) {
699
+ opInfo.rhs = cgf.emitPromotedComplexExpr (e->getRHS (), promotionTypeRHS);
700
+ } else {
701
+ assert (cgf.getContext ().hasSameUnqualifiedType (opInfo.ty , rhsTy));
702
+ opInfo.rhs = Visit (e->getRHS ());
703
+ }
704
+ }
705
+
706
+ LValue lhs = cgf.emitLValue (e->getLHS ());
707
+
708
+ // Load from the l-value and convert it.
709
+ QualType promotionTypeLHS = getPromotionType (e->getComputationLHSType ());
710
+ if (lhsTy->isAnyComplexType ()) {
711
+ mlir::Value lhsValue = emitLoadOfLValue (lhs, exprLoc);
712
+ QualType destTy = promotionTypeLHS.isNull () ? opInfo.ty : promotionTypeLHS;
713
+ opInfo.lhs = emitComplexToComplexCast (lhsValue, lhsTy, destTy, exprLoc);
714
+ } else {
715
+ cgf.cgm .errorNYI (" emitCompoundAssignLValue emitLoadOfScalar" );
716
+ return {};
717
+ }
718
+
719
+ // Expand the binary operator.
720
+ mlir::Value result = (this ->*func)(opInfo);
721
+
722
+ // Truncate the result and store it into the LHS lvalue.
723
+ if (lhsTy->isAnyComplexType ()) {
724
+ mlir::Value resultValue =
725
+ emitComplexToComplexCast (result, opInfo.ty , lhsTy, exprLoc);
726
+ emitStoreOfComplex (loc, resultValue, lhs, /* isInit*/ false );
727
+ value = RValue::getComplex (resultValue);
728
+ } else {
729
+ mlir::Value resultValue =
730
+ cgf.emitComplexToScalarConversion (result, opInfo.ty , lhsTy, exprLoc);
731
+ cgf.emitStoreOfScalar (resultValue, lhs, /* isInit*/ false );
732
+ value = RValue::get (resultValue);
733
+ }
734
+
735
+ return lhs;
736
+ }
737
+
738
+ mlir::Value ComplexExprEmitter::emitCompoundAssign (
739
+ const CompoundAssignOperator *e,
740
+ mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &)) {
741
+ RValue val;
742
+ LValue lv = emitCompoundAssignLValue (e, func, val);
743
+
744
+ // The result of an assignment in C is the assigned r-value.
745
+ if (!cgf.getLangOpts ().CPlusPlus )
746
+ return val.getComplexValue ();
747
+
748
+ // If the lvalue is non-volatile, return the computed value of the assignment.
749
+ if (!lv.isVolatileQualified ())
750
+ return val.getComplexValue ();
751
+
752
+ return emitLoadOfLValue (lv, e->getExprLoc ());
753
+ }
754
+
633
755
mlir::Value ComplexExprEmitter::emitBinAdd (const BinOpInfo &op) {
634
756
assert (!cir::MissingFeatures::fastMathFlags ());
635
757
assert (!cir::MissingFeatures::cgFPOptionsRAII ());
@@ -685,6 +807,31 @@ mlir::Value CIRGenFunction::emitComplexExpr(const Expr *e) {
685
807
return ComplexExprEmitter (*this ).Visit (const_cast <Expr *>(e));
686
808
}
687
809
810
+ using CompoundFunc =
811
+ mlir::Value (ComplexExprEmitter::*)(const ComplexExprEmitter::BinOpInfo &);
812
+
813
+ static CompoundFunc getComplexOp (BinaryOperatorKind op) {
814
+ switch (op) {
815
+ case BO_MulAssign:
816
+ llvm_unreachable (" getComplexOp: BO_MulAssign" );
817
+ case BO_DivAssign:
818
+ llvm_unreachable (" getComplexOp: BO_DivAssign" );
819
+ case BO_SubAssign:
820
+ return &ComplexExprEmitter::emitBinSub;
821
+ case BO_AddAssign:
822
+ return &ComplexExprEmitter::emitBinAdd;
823
+ default :
824
+ llvm_unreachable (" unexpected complex compound assignment" );
825
+ }
826
+ }
827
+
828
+ LValue CIRGenFunction::emitComplexCompoundAssignmentLValue (
829
+ const CompoundAssignOperator *e) {
830
+ CompoundFunc op = getComplexOp (e->getOpcode ());
831
+ RValue val;
832
+ return ComplexExprEmitter (*this ).emitCompoundAssignLValue (e, op, val);
833
+ }
834
+
688
835
mlir::Value CIRGenFunction::emitComplexPrePostIncDec (const UnaryOperator *e,
689
836
LValue lv,
690
837
cir::UnaryOpKind op,
@@ -729,3 +876,11 @@ mlir::Value CIRGenFunction::emitPromotedComplexExpr(const Expr *e,
729
876
QualType promotionType) {
730
877
return ComplexExprEmitter (*this ).emitPromoted (e, promotionType);
731
878
}
879
+
880
+ mlir::Value CIRGenFunction::emitPromotedValue (mlir::Value result,
881
+ QualType promotionType) {
882
+ assert (!mlir::cast<cir::ComplexType>(result.getType ()).isIntegerComplex () &&
883
+ " integral complex will never be promoted" );
884
+ return builder.createCast (cir::CastKind::float_complex, result,
885
+ convertType (promotionType));
886
+ }
0 commit comments