Author: Folkert de Vries
Date: 2026-08-25T15:52:23+02:00
New Revision: e1c2a9c9242e1c50dcb26b444e66a70d36364843

URL: 
https://github.com/llvm/llvm-project/commit/e1c2a9c9242e1c50dcb26b444e66a70d36364843
DIFF: 
https://github.com/llvm/llvm-project/commit/e1c2a9c9242e1c50dcb26b444e66a70d36364843.diff

LOG: [PowerPC][Clang] fix IEEE f128 complex div/mul use IBM f128 libcalls on 
powerpc (#218151)

fixes https://github.com/llvm/llvm-project/issues/216820

Previously the IBM f128 libcall was used also for IEEE f128 complex
mul/div.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.md
    clang/lib/CodeGen/CGExprComplex.cpp
    clang/test/CodeGen/fp128_complex.c

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 2a0af2f357b66..b69b4d616ee77 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -434,6 +434,7 @@ features cannot lower the translation-unit ABI level;
 - Fixed a crash when checking scalar type with excess braces. (#GH69213), 
(#GH137845), (#GH198767), (#GH207566), (#GH106180)
 - Fixed an assertion crash when instantiating a nested requirement with an 
invalid constraint. (#GH213575)
 - Clang now defines the GCC-compatible predefined macro `__SIG_ATOMIC_TYPE__`. 
(#GH213895)
+- Fixed IEEE f128 complex mul/div using the IBM f128 libcalls on powerpc. 
(#GH216820)
 - Fixed an ICE that occurred when a structured binding pack is expanded 
outside the lambda where it was declared. (#GH214160)
 - Fixed a bug where a stray closing curley brace in an OpenMP/OpenACC pragma 
could cause pragma parsing issues when inside of a member function. (#GH214195)
 - Fixed a bug where preprocessor directives following comments were not 
correctly recognized when using -C. (#GH48361)

diff  --git a/clang/lib/CodeGen/CGExprComplex.cpp 
b/clang/lib/CodeGen/CGExprComplex.cpp
index 350cbd18c7ed7..30d693fb371cb 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -798,7 +798,8 @@ ComplexPairTy 
ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
 
 /// Lookup the libcall name for a given floating point type complex
 /// multiply.
-static StringRef getComplexMultiplyLibCallName(llvm::Type *Ty) {
+static StringRef getComplexMultiplyLibCallName(const llvm::Triple &T,
+                                               llvm::Type *Ty) {
   switch (Ty->getTypeID()) {
   default:
     llvm_unreachable("Unsupported floating point type!");
@@ -813,7 +814,7 @@ static StringRef getComplexMultiplyLibCallName(llvm::Type 
*Ty) {
   case llvm::Type::X86_FP80TyID:
     return "__mulxc3";
   case llvm::Type::FP128TyID:
-    return "__multc3";
+    return T.isPPC() ? "__mulkc3" : "__multc3";
   }
 }
 
@@ -880,8 +881,9 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const 
BinOpInfo &Op) {
       // Now emit the libcall on this slowest of the slow paths.
       CGF.EmitBlock(LibCallBB);
       Value *LibCallR, *LibCallI;
+      llvm::Triple Triple = CGF.getTarget().getTriple();
       std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall(
-          getComplexMultiplyLibCallName(Op.LHS.first->getType()), Op);
+          getComplexMultiplyLibCallName(Triple, Op.LHS.first->getType()), Op);
       Builder.CreateBr(ContBB);
 
       // Finally continue execution by phi-ing together the 
diff erent
@@ -1078,7 +1080,9 @@ ComplexPairTy ComplexExprEmitter::EmitBinDiv(const 
BinOpInfo &Op) {
       case llvm::Type::X86_FP80TyID:
         return EmitComplexBinOpLibCall("__divxc3", LibCallOp);
       case llvm::Type::FP128TyID:
-        return EmitComplexBinOpLibCall("__divtc3", LibCallOp);
+        return EmitComplexBinOpLibCall(
+            CGF.getTarget().getTriple().isPPC() ? "__divkc3" : "__divtc3",
+            LibCallOp);
       }
     } else {
       return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);

diff  --git a/clang/test/CodeGen/fp128_complex.c 
b/clang/test/CodeGen/fp128_complex.c
index d1593fae9c9bc..0cd3b59bf3615 100644
--- a/clang/test/CodeGen/fp128_complex.c
+++ b/clang/test/CodeGen/fp128_complex.c
@@ -1,9 +1,37 @@
-// RUN: %clang --target=aarch64 %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang --target=aarch64 %s -S -emit-llvm -o - | FileCheck %s 
--check-prefix=TC3
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -target-feature 
+float128 -DTEST_PPC128 -emit-llvm -o - %s \
+// RUN:   | FileCheck %s --check-prefixes=IBM,PPC
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -target-feature 
+float128 -DTEST_PPC128 -mabi=ieeelongdouble -emit-llvm -o - %s \
+// RUN:   | FileCheck %s --check-prefixes=KC3,PPC
 
 _Complex long double a, b, c, d;
 void test_fp128_compound_assign(void) {
-  // CHECK: call { fp128, fp128 } @__multc3
+  // TC3: call { fp128, fp128 } @__multc3
+  // IBM: call { ppc_fp128, ppc_fp128 } @__multc3
+  // KC3: call { fp128, fp128 } @__mulkc3
   a *= b;
-  // CHECK: call { fp128, fp128 } @__divtc3
+  // TC3: call { fp128, fp128 } @__divtc3
+  // IBM: call { ppc_fp128, ppc_fp128 } @__divtc3
+  // KC3: call { fp128, fp128 } @__divkc3
   c /= d;
 }
+
+#ifdef __FLOAT128__
+_Complex __float128 e, f, g, h;
+void test_float128_compound_assign(void) {
+  // PPC: call { fp128, fp128 } @__mulkc3
+  e *= f;
+  // PPC: call { fp128, fp128 } @__divkc3
+  g /= h;
+}
+#endif
+
+#ifdef __powerpc__
+_Complex __ibm128 i, j, k, l;
+void test_ibm128_compound_assign(void) {
+  // PPC: call { ppc_fp128, ppc_fp128 } @__multc3
+  i *= j;
+  // PPC: call { ppc_fp128, ppc_fp128 } @__divtc3
+  k /= l;
+}
+#endif


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to