rs6000_mangle_decl_assembler_name rewrites the long double math
built-ins (sqrtl -> __sqrtieee128, and the fused sincos) to the names
glibc exports for IEEE-128 long double, gated only on TARGET_IEEEQUAD.
On a non-glibc target such as FreeBSD those __*ieee128 names do not
exist, so code using long double math (e.g. libgfortran's cargl calling
atan2l) ends up with unsatisfiable references.

Gate the remapping on glibc_supports_ieee_128bit (), which exists for
exactly this purpose: only rewrite to glibc's names when glibc provides
them.  Non-glibc targets keep the plain *l names, which their libm
provides as IEEE-128.  The complex multiply/divide remapping above is
unchanged (those map to libgcc's __mulkc3/__divkc3, present everywhere).

gcc/ChangeLog:

        * config/rs6000/rs6000.cc (rs6000_mangle_decl_assembler_name):
        Only remap long double built-ins to __*ieee128 when
        glibc_supports_ieee_128bit ().

Signed-off-by: Piotr Kubaj <[email protected]>
---
 gcc/config/rs6000/rs6000.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -28563,6 +28563,7 @@
 
   /* Map long double built-in functions if long double is IEEE 128-bit.  */
   if (TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
+      && glibc_supports_ieee_128bit ()
       && TREE_CODE (decl) == FUNCTION_DECL
       && DECL_IS_UNDECLARED_BUILTIN (decl)
       && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)

-- 
2.49.0

Reply via email to