]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix tests that require IBM 128-bit long double
authorMichael Meissner <meissner@linux.ibm.com>
Fri, 3 Sep 2021 16:59:47 +0000 (12:59 -0400)
committerMichael Meissner <meissner@linux.ibm.com>
Fri, 3 Sep 2021 16:59:47 +0000 (12:59 -0400)
2021-09-03  Michael Meissner  <meissner@linux.ibm.com>

gcc/testsuite/
PR target/94630
* gcc.target/powerpc/pr70117.c: Specify that we need the long double
type to be IBM 128-bit.  Remove the code to use __ibm128.
Backport from master 2021-08-25.
* c-c++-common/dfp/convert-bfp-11.c: Specify that we need the long
double type to be IBM 128-bit.  Run the test at -O2 optimization.
Backport from master 2021-08-25.
* lib/target-supports.exp (add_options_for_long_double_ibm128): New
function.  Backport from master 2021-08-25.
(check_effective_target_long_double_ibm128): New function.
(add_options_for_long_double_ieee128): New function.
(check_effective_target_long_double_ieee128): New function.
(add_options_for_long_double_64bit): New function.
(check_effective_target_long_double_64bit): New function.

gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c
gcc/testsuite/gcc.target/powerpc/pr70117.c
gcc/testsuite/lib/target-supports.exp

index 95c433d2c24e7b6ece47551509cddc9d7da640ae..c09c8342bbbd868a777fe1f64f8b51fed2d0913a 100644 (file)
@@ -1,9 +1,16 @@
-/* { dg-skip-if "" { ! "powerpc*-*-linux*" } } */
+/* { dg-require-effective-target dfp } */
 
-/* Test decimal float conversions to and from IBM 128-bit long double. 
-   Checks are skipped at runtime if long double is not 128 bits.
-   Don't force 128-bit long doubles because runtime support depends
-   on glibc.  */
+/* We need the long double type to be IBM 128-bit because the CONVERT_TO_PINF
+   tests will fail if we use IEEE 128-bit floating point.  This is due to IEEE
+   128-bit having a larger exponent range than IBM 128-bit extended double.  So
+   tests that would generate an infinity with IBM 128-bit will generate a
+   normal number with IEEE 128-bit.  */
+
+/* { dg-require-effective-target long_double_ibm128 } */
+/* { dg-options "-O2" } */
+/* { dg-add-options long_double_ibm128 } */
+
+/* Test decimal float conversions to and from IBM 128-bit long double.   */
 
 #include "convert.h"
 
@@ -36,9 +43,6 @@ CONVERT_TO_PINF (312, tf, sd, 1.6e+308L, d32)
 int
 main ()
 {
-  if (sizeof (long double) != 16)
-    return 0;
-
   convert_101 ();
   convert_102 ();
 
index 3bbd2c595e0426d55e782a77097385eb081db125..4a51f5831575ae029d57af2869a265d147b2768a 100644 (file)
@@ -1,26 +1,18 @@
-/* { dg-do run { target { powerpc*-*-linux* powerpc*-*-darwin* powerpc*-*-aix* rs6000-*-* } } } */
-/* { dg-options "-std=c99 -mlong-double-128 -O2" } */
+/* { dg-do run } */
+/* { dg-require-effective-target long_double_ibm128 } */
+/* { dg-options "-std=c99 -O2" } */
+/* { dg-add-options long_double_ibm128 } */
 
 #include <float.h>
 
-#if defined(__LONG_DOUBLE_IEEE128__)
-/* If long double is IEEE 128-bit, we need to use the __ibm128 type instead of
-   long double.  We can't use __ibm128 on systems that don't support IEEE
-   128-bit floating point, because the type is not enabled on those
-   systems.  */
-#define LDOUBLE __ibm128
-
-#elif defined(__LONG_DOUBLE_IBM128__)
-#define LDOUBLE long double
-
-#else
-#error "long double must be either IBM 128-bit or IEEE 128-bit"
+#ifndef __LONG_DOUBLE_IBM128__
+#error "long double must be IBM 128-bit"
 #endif
 
 union gl_long_double_union
 {
   struct { double hi; double lo; } dd;
-  LDOUBLE ld;
+  long double ld;
 };
 
 /* This is gnulib's LDBL_MAX which, being 107 bits in precision, is
@@ -36,7 +28,7 @@ volatile double dnan = 0.0/0.0;
 int
 main (void)
 {
-  LDOUBLE ld;
+  long double ld;
 
   ld = gl_LDBL_MAX.ld;
   if (__builtin_isinf (ld))
index 8aebd2e9a91daa0b92ad76f083ba92ae05b9e390..45d34e1a58ef43d2391973e1bb00032e5b99bb59 100644 (file)
@@ -2360,6 +2360,134 @@ proc check_effective_target_ppc_ieee128_ok { } {
     }]
 }
 
+# Check if GCC and GLIBC supports explicitly specifying that the long double
+# format uses the IBM 128-bit extended double format.  Under little endian
+# PowerPC Linux, you need GLIBC 2.32 or later to be able to use a different
+# long double format for running a program than the system default.
+
+proc check_effective_target_long_double_ibm128 { } {
+    return [check_runtime_nocache long_double_ibm128 {
+       #include <string.h>
+       #include <stdio.h>
+       /* use volatile to prevent optimization.  */
+       volatile __ibm128 a = (__ibm128) 3.0;
+       volatile long double one = 1.0L;
+       volatile long double two = 2.0L;
+       volatile long double b;
+       char buffer[20];
+       int main()
+       {
+         __ibm128 a2;
+         long double b2;
+         if (sizeof (long double) != 16)
+           return 1;
+         b = one + two;
+         /* eliminate removing volatile cast warning.  */
+         a2 = a;
+         b2 = b;
+         if (memcmp (&a2, &b2, 16) != 0)
+           return 1;
+         sprintf (buffer, "%lg", b);
+         return strcmp (buffer, "3") != 0;
+       }
+    } [add_options_for_long_double_ibm128 ""]]
+}
+
+# Return the appropriate options to specify that long double uses the IBM
+# 128-bit format on PowerPC.
+
+proc add_options_for_long_double_ibm128 { flags } {
+    if { [istarget powerpc*-*-*] } {
+       return "$flags -mlong-double-128 -Wno-psabi -mabi=ibmlongdouble"
+    }
+    return "$flags"
+}
+
+# Check if GCC and GLIBC supports explicitly specifying that the long double
+# format uses the IEEE 128-bit format.  Under little endian PowerPC Linux, you
+# need GLIBC 2.32 or later to be able to use a different long double format for
+# running a program than the system default.
+
+proc check_effective_target_long_double_ieee128 { } {
+    return [check_runtime_nocache long_double_ieee128 {
+       #include <string.h>
+       #include <stdio.h>
+       /* use volatile to prevent optimization.  */
+       volatile _Float128 a = 3.0f128;
+       volatile long double one = 1.0L;
+       volatile long double two = 2.0L;
+       volatile long double b;
+       char buffer[20];
+       int main()
+       {
+         _Float128 a2;
+         long double b2;  
+         if (sizeof (long double) != 16)
+           return 1;
+         b = one + two;
+         /* eliminate removing volatile cast warning.  */
+         a2 = a;
+         b2 = b;
+         if (memcmp (&a2, &b2, 16) != 0)
+           return 1;
+         sprintf (buffer, "%lg", b);
+         return strcmp (buffer, "3") != 0;
+       }
+    }  [add_options_for_long_double_ieee128 ""]]
+}
+
+# Return the appropriate options to specify that long double uses the IBM
+# 128-bit format on PowerPC.
+proc add_options_for_long_double_ieee128 { flags } {
+    if { [istarget powerpc*-*-*] } {
+       return "$flags -mlong-double-128 -Wno-psabi -mabi=ieeelongdouble"
+    }
+    return "$flags"
+}
+
+# Check if GCC and GLIBC supports explicitly specifying that the long double
+# format uses the IEEE 64-bit.  Under little endian PowerPC Linux, you need
+# GLIBC 2.32 or later to be able to use a different long double format for
+# running a program than the system default.
+
+proc check_effective_target_long_double_64bit { } {
+    return [check_runtime_nocache long_double_64bit {
+       #include <string.h>
+       #include <stdio.h>
+       /* use volatile to prevent optimization.  */
+       volatile double a = 3.0;
+       volatile long double one = 1.0L;
+       volatile long double two = 2.0L;
+       volatile long double b;
+       char buffer[20];
+       int main()
+       {
+         double a2;
+         long double b2;
+         if (sizeof (long double) != 8)
+           return 1;
+         b = one + two;
+         /* eliminate removing volatile cast warning.  */
+         a2 = a;
+         b2 = b;
+         if (memcmp (&a2, &b2, 16) != 0)
+           return 1;
+         sprintf (buffer, "%lg", b);
+         return strcmp (buffer, "3") != 0;
+       }
+    }  [add_options_for_ppc_long_double_override_64bit ""]]
+}
+
+# Return the appropriate options to specify that long double uses the IEEE
+# 64-bit format on PowerPC.
+
+proc add_options_for_long_double_64bit { flags } {
+    if { [istarget powerpc*-*-*] } {
+       return "$flags -mlong-double-64"
+    }
+    return "$flags"
+}
+
 # Return 1 if the target supports executing VSX instructions, 0
 # otherwise.  Cache the result.