[2/2] PR 115800: Fix libstdc++-v3 on little endian powerpc using --with-cpu=power5

Message ID Zo7EQUQSlkNGDCkm@cowardly-lion.the-meissners.org
State New
Headers
Series [1/2] PR 115800: Fix libgfortran build using --with-cpu=power5 |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed

Commit Message

Michael Meissner July 10, 2024, 5:26 p.m. UTC
  If you build a little endian compiler and select a default CPU of power5
(i.e. --with-cpu=power5), GCC cannot be built.  The reason is that both the
libgfortran and libstdc++-v3 libraries assume that all little endian powerpc
builds support IEEE 128-bit floating point.

However, if the default cpu does not support the VSX instruction set, then we
cannot build the IEEE 128-bit libraries.  This patch fixes the libstdc++-v3
library so if the GCC compiler does not support IEEE 128-bit floating point, the
IEEE 128-bit floating point libraries are not built.  A companion patch will fix
the libgfortran library.

I have built these patches on a little endian system, doing both normal builds,
and making a build with a power5 default.  There was no regression in the normal
builds.  I have also built a big endian GCC compiler and there was no regression
there.  Can I check this patch into the trunk?

2024-07-10  Michael Meissner  <meissner@linux.ibm.com>

libstdc++-v3/

	PR target/115800
	* configure.ac (powerpc*-*-linux*): Don't enable IEEE 128-bit on PowerPC
	systems without VSX.
	* configure: Regenerate.
	* numeric_traits.h: Don't enable IEEE 128-bit on PowerPC systems without
	VSX.
---
 libstdc++-v3/configure                    | 68 ++++++++++++++++-------
 libstdc++-v3/configure.ac                 | 58 +++++++++++--------
 libstdc++-v3/include/ext/numeric_traits.h |  2 +-
 3 files changed, 86 insertions(+), 42 deletions(-)
  

Patch

diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 5645e991af7..daab67f9dee 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -51355,8 +51355,31 @@  $as_echo "#define _GLIBCXX_LONG_DOUBLE_COMPAT 1" >>confdefs.h
     case "$target" in
       powerpc*-*-linux*)
 	LONG_DOUBLE_COMPAT_FLAGS="$LONG_DOUBLE_COMPAT_FLAGS -mno-gnu-attribute"
-        # Check for IEEE128 support in libm:
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __frexpieee128 in -lm" >&5
+	# Eliminate little endian systems without VSX
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+	  #ifndef __VSX__
+	  #error "IEEE 128-bit needs VSX"
+	  #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_ieee128_possible=yes
+else
+  ac_ieee128_possible=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+	if test $ac_ieee128_possible = yes; then
+          # Check for IEEE128 support in libm:
+          { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __frexpieee128 in -lm" >&5
 $as_echo_n "checking for __frexpieee128 in -lm... " >&6; }
 if ${ac_cv_lib_m___frexpieee128+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -51401,18 +51424,18 @@  else
   ac_ldbl_ieee128_in_libc=no
 fi
 
-        if test $ac_ldbl_ieee128_in_libc = yes; then
-          # Determine which long double format is the compiler's default:
-          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+          if test $ac_ldbl_ieee128_in_libc = yes; then
+            # Determine which long double format is the compiler's default:
+            cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
 main ()
 {
 
-            #ifndef __LONG_DOUBLE_IEEE128__
-            #error compiler defaults to ibm128
-            #endif
+              #ifndef __LONG_DOUBLE_IEEE128__
+              #error compiler defaults to ibm128
+              #endif
 
   ;
   return 0;
@@ -51424,21 +51447,28 @@  else
   ac_ldbl_ieee128_default=no
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-          # Library objects should use default long double format.
-          if test "$ac_ldbl_ieee128_default" = yes; then
-            LONG_DOUBLE_128_FLAGS="-mno-gnu-attribute"
-            # Except for the ones that explicitly use these flags:
-            LONG_DOUBLE_ALT128_COMPAT_FLAGS="-mabi=ibmlongdouble -mno-gnu-attribute -Wno-psabi"
-          else
-            LONG_DOUBLE_128_FLAGS="-mno-gnu-attribute"
-            LONG_DOUBLE_ALT128_COMPAT_FLAGS="-mabi=ieeelongdouble -mno-gnu-attribute -Wno-psabi"
-          fi
+            # Library objects should use default long double format.
+            if test "$ac_ldbl_ieee128_default" = yes; then
+              LONG_DOUBLE_128_FLAGS="-mno-gnu-attribute"
+              # Except for the ones that explicitly use these flags:
+              LONG_DOUBLE_ALT128_COMPAT_FLAGS="-mabi=ibmlongdouble -mno-gnu-attribute -Wno-psabi"
+            else
+              LONG_DOUBLE_128_FLAGS="-mno-gnu-attribute"
+              LONG_DOUBLE_ALT128_COMPAT_FLAGS="-mabi=ieeelongdouble -mno-gnu-attribute -Wno-psabi"
+            fi
 
 $as_echo "#define _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT 1" >>confdefs.h
 
-          port_specific_symbol_files="$port_specific_symbol_files \$(top_srcdir)/config/os/gnu-linux/ldbl-ieee128-extra.ver"
-          ac_ldbl_alt128_compat=yes
+            port_specific_symbol_files="$port_specific_symbol_files \$(top_srcdir)/config/os/gnu-linux/ldbl-ieee128-extra.ver"
+            ac_ldbl_alt128_compat=yes
+          else
+            ac_ldbl_alt128_compat=no
+          fi
+
+        # IEEE 128-bit not possible
         else
+          acl_ldbl_ieee128_in_libc=no
+          acl_ldbl_ieee128_default=no
           ac_ldbl_alt128_compat=no
         fi
 	;;
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index ccb24a82be7..69f795bd453 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -479,31 +479,45 @@  case "$target" in
     case "$target" in
       powerpc*-*-linux*)
 	LONG_DOUBLE_COMPAT_FLAGS="$LONG_DOUBLE_COMPAT_FLAGS -mno-gnu-attribute"
-        # Check for IEEE128 support in libm:
-        AC_CHECK_LIB(m, __frexpieee128,
-                     [ac_ldbl_ieee128_in_libc=yes],
-                     [ac_ldbl_ieee128_in_libc=no])
-        if test $ac_ldbl_ieee128_in_libc = yes; then
-          # Determine which long double format is the compiler's default:
-          AC_TRY_COMPILE(, [
-            #ifndef __LONG_DOUBLE_IEEE128__
-            #error compiler defaults to ibm128
-            #endif
-          ], [ac_ldbl_ieee128_default=yes], [ac_ldbl_ieee128_default=no])
-          # Library objects should use default long double format.
-          if test "$ac_ldbl_ieee128_default" = yes; then
-            LONG_DOUBLE_128_FLAGS="-mno-gnu-attribute"
-            # Except for the ones that explicitly use these flags:
-            LONG_DOUBLE_ALT128_COMPAT_FLAGS="-mabi=ibmlongdouble -mno-gnu-attribute -Wno-psabi"
+	# Eliminate little endian systems without VSX
+	AC_TRY_COMPILE(, [
+	  #ifndef __VSX__
+	  #error "IEEE 128-bit needs VSX"
+	  #endif
+	], [ac_ieee128_possible=yes], [ac_ieee128_possible=no])
+	if test $ac_ieee128_possible = yes; then
+          # Check for IEEE128 support in libm:
+          AC_CHECK_LIB(m, __frexpieee128,
+                       [ac_ldbl_ieee128_in_libc=yes],
+                       [ac_ldbl_ieee128_in_libc=no])
+          if test $ac_ldbl_ieee128_in_libc = yes; then
+            # Determine which long double format is the compiler's default:
+            AC_TRY_COMPILE(, [
+              #ifndef __LONG_DOUBLE_IEEE128__
+              #error compiler defaults to ibm128
+              #endif
+            ], [ac_ldbl_ieee128_default=yes], [ac_ldbl_ieee128_default=no])
+            # Library objects should use default long double format.
+            if test "$ac_ldbl_ieee128_default" = yes; then
+              LONG_DOUBLE_128_FLAGS="-mno-gnu-attribute"
+              # Except for the ones that explicitly use these flags:
+              LONG_DOUBLE_ALT128_COMPAT_FLAGS="-mabi=ibmlongdouble -mno-gnu-attribute -Wno-psabi"
+            else
+              LONG_DOUBLE_128_FLAGS="-mno-gnu-attribute"
+              LONG_DOUBLE_ALT128_COMPAT_FLAGS="-mabi=ieeelongdouble -mno-gnu-attribute -Wno-psabi"
+            fi
+            AC_DEFINE([_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT],1,
+                  [Define if compatibility should be provided for alternative 128-bit long double formats.])
+            port_specific_symbol_files="$port_specific_symbol_files \$(top_srcdir)/config/os/gnu-linux/ldbl-ieee128-extra.ver"
+            ac_ldbl_alt128_compat=yes
           else
-            LONG_DOUBLE_128_FLAGS="-mno-gnu-attribute"
-            LONG_DOUBLE_ALT128_COMPAT_FLAGS="-mabi=ieeelongdouble -mno-gnu-attribute -Wno-psabi"
+            ac_ldbl_alt128_compat=no
           fi
-          AC_DEFINE([_GLIBCXX_LONG_DOUBLE_ALT128_COMPAT],1,
-                [Define if compatibility should be provided for alternative 128-bit long double formats.])
-          port_specific_symbol_files="$port_specific_symbol_files \$(top_srcdir)/config/os/gnu-linux/ldbl-ieee128-extra.ver"
-          ac_ldbl_alt128_compat=yes
+        
+        # IEEE 128-bit not possible
         else
+          acl_ldbl_ieee128_in_libc=no
+          acl_ldbl_ieee128_default=no
           ac_ldbl_alt128_compat=no
         fi
 	;;
diff --git a/libstdc++-v3/include/ext/numeric_traits.h b/libstdc++-v3/include/ext/numeric_traits.h
index b2723bfabfa..0f00abb3db6 100644
--- a/libstdc++-v3/include/ext/numeric_traits.h
+++ b/libstdc++-v3/include/ext/numeric_traits.h
@@ -218,7 +218,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __numeric_traits<__ibm128>
     : public __numeric_traits_floating<__ibm128>
     { };
-# elif defined __LONG_DOUBLE_IBM128__
+# elif defined __LONG_DOUBLE_IBM128__ && defined __VSX__
   // long double is __ibm128, define traits for __ieee128
   template<>
     struct __numeric_traits_floating<__ieee128>