================
@@ -570,6 +594,124 @@ ComplexExprEmitter::emitBinOps(const BinaryOperator *e, 
QualType promotionTy) {
   return binOpInfo;
 }
 
+LValue ComplexExprEmitter::emitCompoundAssignLValue(
+    const CompoundAssignOperator *e,
+    mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &), RValue &value) 
{
+  QualType lhsTy = e->getLHS()->getType();
+  QualType rhsTy = e->getRHS()->getType();
+  SourceLocation exprLoc = e->getExprLoc();
+  mlir::Location loc = cgf.getLoc(exprLoc);
+
+  if (const AtomicType *atomicTy = lhsTy->getAs<AtomicType>())
+    lhsTy = atomicTy->getValueType();
+
+  BinOpInfo opInfo{loc};
+  opInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts());
+
+  assert(!cir::MissingFeatures::cgFPOptionsRAII());
+
+  // Load the RHS and LHS operands.
+  // __block variables need to have the rhs evaluated first, plus this should
+  // improve codegen a little.
+  QualType promotionTypeCR = getPromotionType(e->getComputationResultType());
+  opInfo.ty = promotionTypeCR.isNull() ? e->getComputationResultType()
+                                       : promotionTypeCR;
+
+  QualType complexElementTy =
+      opInfo.ty->castAs<ComplexType>()->getElementType();
+  QualType promotionTypeRHS = getPromotionType(rhsTy);
+
+  // The RHS should have been converted to the computation type.
+  if (e->getRHS()->getType()->isRealFloatingType()) {
+    if (!promotionTypeRHS.isNull())
+      opInfo.rhs = createComplexFromReal(
+          cgf.getBuilder(), loc,
+          cgf.emitPromotedScalarExpr(e->getRHS(), promotionTypeRHS));
+    else {
+      assert(cgf.getContext().hasSameUnqualifiedType(complexElementTy, rhsTy));
+      opInfo.rhs = createComplexFromReal(cgf.getBuilder(), loc,
+                                         cgf.emitScalarExpr(e->getRHS()));
+    }
+  } else {
+    if (!promotionTypeRHS.isNull()) {
+      opInfo.rhs = createComplexFromReal(
+          cgf.getBuilder(), loc,
+          cgf.emitPromotedComplexExpr(e->getRHS(), promotionTypeRHS));
+    } else {
+      assert(cgf.getContext().hasSameUnqualifiedType(opInfo.ty, rhsTy));
+      opInfo.rhs = Visit(e->getRHS());
+    }
+  }
+
+  LValue lhs = cgf.emitLValue(e->getLHS());
+
+  // Load from the l-value and convert it.
+  QualType promotionTypeLHS = getPromotionType(e->getComputationLHSType());
+  if (lhsTy->isAnyComplexType()) {
+    mlir::Value lhsValue = emitLoadOfLValue(lhs, exprLoc);
+    QualType destTy = promotionTypeLHS.isNull() ? opInfo.ty : promotionTypeLHS;
+    opInfo.lhs = emitComplexToComplexCast(lhsValue, lhsTy, destTy, exprLoc);
+  } else {
+    mlir::Value lhsValue = cgf.emitLoadOfScalar(lhs, exprLoc);
+    // For floating point real operands we can directly pass the scalar form
+    // to the binary operator emission and potentially get more efficient code.
+    if (lhsTy->isRealFloatingType()) {
+      QualType promotedComplexElementTy;
+      if (!promotionTypeLHS.isNull()) {
+        promotedComplexElementTy =
+            cast<ComplexType>(promotionTypeLHS)->getElementType();
+        if (!cgf.getContext().hasSameUnqualifiedType(promotedComplexElementTy,
+                                                     promotionTypeLHS))
+          lhsValue = cgf.emitScalarConversion(
+              lhsValue, lhsTy, promotedComplexElementTy, exprLoc);
+      } else {
+        if (!cgf.getContext().hasSameUnqualifiedType(complexElementTy, lhsTy))
+          lhsValue = cgf.emitScalarConversion(lhsValue, lhsTy, 
complexElementTy,
+                                              exprLoc);
+      }
+      opInfo.lhs = createComplexFromReal(cgf.getBuilder(),
+                                         cgf.getLoc(e->getExprLoc()), 
lhsValue);
+    } else {
+      opInfo.lhs = emitScalarToComplexCast(lhsValue, lhsTy, opInfo.ty, 
exprLoc);
+    }
+  }
+
+  // Expand the binary operator.
+  mlir::Value result = (this->*func)(opInfo);
+
+  // Truncate the result and store it into the LHS lvalue.
+  if (lhsTy->isAnyComplexType()) {
+    mlir::Value resultValue =
+        emitComplexToComplexCast(result, opInfo.ty, lhsTy, exprLoc);
+    emitStoreOfComplex(loc, resultValue, lhs, /*isInit*/ false);
+    value = RValue::getComplex(resultValue);
+  } else {
+    mlir::Value resultValue =
+        cgf.emitComplexToScalarConversion(result, opInfo.ty, lhsTy, exprLoc);
----------------
AmrDeveloper wrote:

>From the original CG, this part is for handling one case in C where the LHS is 
>scalar and the RHS is complex. The code will not assert because the source is 
>still complex 

https://github.com/llvm/llvm-project/blob/d4e8619ef12d1de0b839f91c3ee976811823bd7c/clang/test/CodeGen/complex.c#L34

```
_Complex float cf;
double D;

void test3(void) {
  cf += D;   <-----
}
```

https://github.com/llvm/llvm-project/pull/150759
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to