bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Re: powerpc64le-linux long double math test failures


From: Ulrich Weigand
Subject: [PATCH] Re: powerpc64le-linux long double math test failures
Date: Wed, 18 Dec 2013 20:09:10 +0100 (CET)

Alan Modra wrote:
> On Sat, Dec 14, 2013 at 10:13:29PM +0100, Ulrich Weigand wrote:
> > I'm wondering now what the best way to fix this would be.  I'm a little bit
> > confused about the original intentions of the test, however.  Why does it
> > attempt to move to another word?  If it simply attempted to set the
> > *second* highest mantissa bit, everything would work out OK.   And if it
> > does move to another word, why the NWORDS / 2 test?  Should we trust the
> > gl_BIGENDIAN macro instead?
> 
> I would say "LDBL_EXPBIT0_WORD < NWORDS / 2" is testing for floating
> point endianness (which seemingly can be different to integer
> endianness, at least it looks that way from code in gcc).  Now gcc has
> predefined macros to test for exactly that, so..
> 
> #ifdef __FLOAT_WORD_ORDER__
> #define FLOAT_BIG_ENDIAN (__FLOAT_WORD_ORDER__ != __ORDER_LITTLE_ENDIAN__)
> #else
> #define FLOAT_BIG_ENDIAN (LDBL_EXPBIT0_WORD < NWORDS / 2)
> #endif
> 
> then use FLOAT_BIG_ENDIAN everywhere you see LDBL_EXPBIT0_WORD < NWORDS / 2

I guess that would be one way.  I've been working on another patch
along these lines in the meantime:

> > Or should the test simply hardcode the information about the IBM double
> > double format, and treat the first half as 64-bit IEEE double?

This seems a bit more natural to me, as it addresses the actual underlying
problem with those test cases (IBM double double simply is not an IEEE
format, and treating it as such really only worked by accident).

The patch below fixes all the isfinite/isinf*/isnan*/signbit module tests
for me on powerpc64le-linux, and does not regress on powerpc64-linux.

Does this look reasonable?

Bye,
Ulrich


diff --git a/ChangeLog b/ChangeLog
index 1753c8e..52ec0df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2013-12-18  Ulrich Weigand  <address@hidden>
+
+       Fix math tests for little-endian PowerPC
+
+       * tests/test-isfinite.c (test_isfinitel): Only manipulate the
+       first double of a PowerPC "double double" pair.
+       * tests/test-isinf.c (test_isinfl): Likewise.
+       * tests/test-isnan.c (test_long_double): Likewise.
+       * tests/test-isnanl.h (main): Likewise.
+       * tests/test-signbit.c (test_signbitl): Likewise.
+
 2013-12-17  Paul Eggert  <address@hidden>
 
        gettimeofday: port recent C++ fix to Emacs
diff --git a/tests/test-isfinite.c b/tests/test-isfinite.c
index 9e8dd0d..a762ceb 100644
--- a/tests/test-isfinite.c
+++ b/tests/test-isfinite.c
@@ -152,6 +152,15 @@ test_isfinitel ()
   /* A bit pattern that is different from a Quiet NaN.  With a bit of luck,
      it's a Signalling NaN.  */
   {
+#if defined __powerpc__ && LDBL_MANT_DIG == 106
+    /* This is PowerPC "double double", a pair of two doubles.  Inf and Nan are
+       represented as the corresponding 64-bit IEEE values in the first double;
+       the second is ignored.  Manipulate only the first double.  */
+    #undef NWORDS
+    #define NWORDS \
+      ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+#endif
+
     memory_long_double m;
     m.value = zerol / zerol;
 # if LDBL_EXPBIT0_BIT > 0
diff --git a/tests/test-isinf.c b/tests/test-isinf.c
index 276e480..eb1b7f2 100644
--- a/tests/test-isinf.c
+++ b/tests/test-isinf.c
@@ -158,6 +158,15 @@ test_isinfl ()
   /* A bit pattern that is different from a Quiet NaN.  With a bit of luck,
      it's a Signalling NaN.  */
   {
+#if defined __powerpc__ && LDBL_MANT_DIG == 106
+    /* This is PowerPC "double double", a pair of two doubles.  Inf and Nan are
+       represented as the corresponding 64-bit IEEE values in the first double;
+       the second is ignored.  Manipulate only the first double.  */
+    #undef NWORDS
+    #define NWORDS \
+      ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+#endif
+
     memory_long_double m;
     m.value = zerol / zerol;
 # if LDBL_EXPBIT0_BIT > 0
diff --git a/tests/test-isnan.c b/tests/test-isnan.c
index ccebe3d..a11233a 100644
--- a/tests/test-isnan.c
+++ b/tests/test-isnan.c
@@ -139,6 +139,15 @@ test_long_double (void)
   /* A bit pattern that is different from a Quiet NaN.  With a bit of luck,
      it's a Signalling NaN.  */
   {
+#if defined __powerpc__ && LDBL_MANT_DIG == 106
+    /* This is PowerPC "double double", a pair of two doubles.  Inf and Nan are
+       represented as the corresponding 64-bit IEEE values in the first double;
+       the second is ignored.  Manipulate only the first double.  */
+    #undef NWORDSL
+    #define NWORDSL \
+      ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+#endif
+
     memory_long_double m;
     m.value = NaNl ();
 # if LDBL_EXPBIT0_BIT > 0
diff --git a/tests/test-isnanl.h b/tests/test-isnanl.h
index 06e6a7c..2df10f8 100644
--- a/tests/test-isnanl.h
+++ b/tests/test-isnanl.h
@@ -51,6 +51,15 @@ main ()
   /* A bit pattern that is different from a Quiet NaN.  With a bit of luck,
      it's a Signalling NaN.  */
   {
+#if defined __powerpc__ && LDBL_MANT_DIG == 106
+    /* This is PowerPC "double double", a pair of two doubles.  Inf and Nan are
+       represented as the corresponding 64-bit IEEE values in the first double;
+       the second is ignored.  Manipulate only the first double.  */
+    #undef NWORDS
+    #define NWORDS \
+      ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+#endif
+
     memory_long_double m;
     m.value = NaNl ();
 # if LDBL_EXPBIT0_BIT > 0
diff --git a/tests/test-signbit.c b/tests/test-signbit.c
index e8ea097..7e24292 100644
--- a/tests/test-signbit.c
+++ b/tests/test-signbit.c
@@ -151,6 +151,16 @@ test_signbitl ()
     #define NWORDS \
       ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned 
int))
     typedef union { long double value; unsigned int word[NWORDS]; } 
memory_long_double;
+
+#if defined __powerpc__ && LDBL_MANT_DIG == 106
+    /* This is PowerPC "double double", a pair of two doubles.  Inf and Nan are
+       represented as the corresponding 64-bit IEEE values in the first double;
+       the second is ignored.  Manipulate only the first double.  */
+    #undef NWORDS
+    #define NWORDS \
+      ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+#endif
+
     memory_long_double m;
     m.value = zerol / zerol;
 # if LDBL_EXPBIT0_BIT > 0

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  address@hidden




reply via email to

[Prev in Thread] Current Thread [Next in Thread]