[clang] [CLANG] Full support of complex multiplication and division. (PR #81514)

Joshua Cranmer via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 14 13:18:06 PDT 2024


================
@@ -287,9 +288,47 @@ class ComplexExprEmitter
   ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName,
                                         const BinOpInfo &Op);
 
-  QualType getPromotionType(QualType Ty) {
+  QualType GetHigherPrecisionFPType(QualType ElementType) {
+    const auto *CurrentBT = dyn_cast<BuiltinType>(ElementType);
+    switch (CurrentBT->getKind()) {
+    case BuiltinType::Kind::Float16:
+      return CGF.getContext().FloatTy;
+    case BuiltinType::Kind::Float:
+    case BuiltinType::Kind::BFloat16:
+      return CGF.getContext().DoubleTy;
+    case BuiltinType::Kind::Double:
+      return CGF.getContext().LongDoubleTy;
+    default:
+      return ElementType;
+    }
+  }
+
+  QualType HigherPrecisionTypeForComplexArithmetic(QualType ElementType,
+                                                   bool IsDivOpCode) {
+    QualType HigherElementType = GetHigherPrecisionFPType(ElementType);
+    const llvm::fltSemantics &ElementTypeSemantics =
+        CGF.getContext().getFloatTypeSemantics(ElementType);
+    const llvm::fltSemantics &HigherElementTypeSemantics =
+        CGF.getContext().getFloatTypeSemantics(HigherElementType);
+    if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <=
+        llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) {
+      return CGF.getContext().getComplexType(HigherElementType);
+    } else {
+      FPHasBeenPromoted = LangOptions::ComplexRangeKind::CX_Improved;
----------------
jcranmer-intel wrote:

If I'm following correctly, this means that the behavior wouldn't be right for this code:

```c
_Complex float func(_Complex float a, _Complex long double b, _Complex float c) {
  return (_Complex float)(b / c) / a;
}
```

The code would first process the long double complex division, which isn't promotable, and then the float division, using the same `ComplexExprEmitter` I think, so the resetting to improved would cause the second float division to be emitted as improved instead of promoted.

https://github.com/llvm/llvm-project/pull/81514


More information about the cfe-commits mailing list