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

Joshua Cranmer via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 8 11:43:40 PST 2024


================
@@ -283,9 +283,48 @@ 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);
+    const llvm::Triple TI = CGF.getTarget().getTriple();
+    if ((llvm::APFloat::getSizeInBits(HigherElementTypeSemantics) >
+         llvm::APFloat::getSizeInBits(ElementTypeSemantics)) &&
----------------
jcranmer-intel wrote:

To avoid intermediate overflow, we need Smaller::largest() * Smaller::largest() + Smaller::largest() * Smaller::largest() <= Larger::largest(). That means the correct check should be, I think:

```c++
if (ApFloatBase::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <= ApFloatBase::semanticsMaxExponent(HigherElementTypeSemantics))
```

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


More information about the cfe-commits mailing list