bug-gnulib
[Top][All Lists]
Advanced

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

Re: computing long double NaN on Irix 6.5


From: Eric Blake
Subject: Re: computing long double NaN on Irix 6.5
Date: Thu, 26 Feb 2009 21:17:28 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.19) Gecko/20081209 Thunderbird/2.0.0.19 Mnenhy/0.7.6.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Eric Blake on 2/26/2009 4:57 PM:
> I've done some investigation into failures of test-frexpl, test-isnanl, and 
> test-vasnprintf-posix on Irix 6.5.
> 
> So, I am working on a patch that looks for all instances of 0.0L / 0.0L in 
> the 
> testsuite, and replacing them with a call to NaNl() from tests/nan.h; at the 
> same time, beefing up that macro to use type conversion from double to long 
> double on Irix as the only known way to guarantee a NaN.

Before the patch, gcc gave 9 of 16 tests failing on assertions, all
dealing with NaN, when I ran:

gnulib-tool --with-tests --test isfinite isnan ceill floorl frexpl isnanl
ldexpl roundl truncl

After the patch, under gcc, 2 tests still fail (probably due to gcc
mishandling Irix's weird notion of a 128-bit long double formed by adding
two 64-bit doubles together).  It reminds me of a previously fixed MaxOS
failure in that area, although I haven't had time to test.  But since the
new failures are unrelated to NaN, and since cc passes all 16 tests, I'm
committing the patch below.

../../gltests/test-frexpl.c:144: assertion failed
/bin/sh[9]: 341777 Abort(coredump)
FAIL: test-frexpl
../../gltests/test-ldexpl.c:130: assertion failed
/bin/sh[9]: 338455 Abort(coredump)
FAIL: test-ldexpl

Meanwhile, while running the tests, I noticed:

checking whether HUGE_VAL works... yes
checking whether roundl is declared... no
checking whether ceill is declared... (cached) yes
checking whether floorl is declared... (cached) yes
(cached) (cached) checking for signbit macro... no
checking for signbit compiler built-ins... no

Ouch.  That double (cached) at the beginning of a line means that we are
doing one AC_CACHE_CHECK inside the body of another, and that it is likely
that 'configure -C' will get things wrong on a second run.  I'm still
hunting that one down.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkmnaVgACgkQ84KuGfSFAYDxdQCfXqvbdW8IpzzoDFLo/HLJm0LE
cOoAoJy07d0KUCdKkXLuocB558uz/MEI
=r1Zb
-----END PGP SIGNATURE-----
>From ecab4471c7da5d367a62c8db75ee54ed6d948e40 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Thu, 26 Feb 2009 20:18:42 -0700
Subject: [PATCH] avoid gcc 3.4.3 bug on long double NaN on Irix 6.5

* tests/nan.h (NaNl): Rewrite as function on Irix, to avoid
compilation bug by using runtime conversion.
* m4/isfinite.m4 (gl_ISFINITE): Likewise.
* m4/isnanl.m4 (gl_FUNC_ISNANL): Likewise.
* modules/ceill-tests (Files): Use nan.h.
* modules/floorl-tests (Files): Likewise.
* modules/frexpl-tests (Files): Likewise.
* modules/isnanl-tests (Files): Likewise.
* modules/ldexpl-tests (Files): Likewise.
* modules/roundl-tests (Files): Likewise.
* modules/truncl-tests (Files): Likewise.
* tests/test-ceill.c (main): Use a working NaN.
* tests/test-floorl.c (main): Likewise.
* tests/test-frexpl.c (main): Likewise.
* tests/test-isnan.c (test_long_double): Likewise.
* tests/test-isnanl.h (main): Likewise.
* tests/test-ldexpl.h (main): Likewise.
* tests/test-roundl.h (main): Likewise.
* tests/test-truncl.h (main): Likewise.
See http://lists.gnu.org/archive/html/bug-gnulib/2009-02/msg00190.html.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog            |   26 +++++++++++++++++++++++++-
 m4/isfinite.m4       |   15 +++++++++++++--
 m4/isnanl.m4         |   18 ++++++++++++++----
 modules/ceill-tests  |    1 +
 modules/floorl-tests |    1 +
 modules/frexpl-tests |    1 +
 modules/isnanl-tests |    1 +
 modules/ldexpl-tests |    1 +
 modules/roundl-tests |    1 +
 modules/truncl-tests |    1 +
 tests/nan.h          |   14 ++++++++++++--
 tests/test-ceill.c   |    3 ++-
 tests/test-floorl.c  |    3 ++-
 tests/test-frexpl.c  |    3 ++-
 tests/test-isnan.c   |    4 ++--
 tests/test-isnanl.h  |    6 ++++--
 tests/test-ldexpl.c  |    3 ++-
 tests/test-roundl.c  |    3 ++-
 tests/test-truncl.c  |    3 ++-
 19 files changed, 89 insertions(+), 19 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 583fa8f..90f91f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
 2009-02-26  Eric Blake  <address@hidden>
-            Bruno Haible  <address@hidden>
+
+       avoid gcc 3.4.3 bug on long double NaN on Irix 6.5
+       * tests/nan.h (NaNl): Rewrite as function on Irix, to avoid
+       compilation bug by using runtime conversion.
+       * m4/isfinite.m4 (gl_ISFINITE): Likewise.
+       * m4/isnanl.m4 (gl_FUNC_ISNANL): Likewise.
+       * modules/ceill-tests (Files): Use nan.h.
+       * modules/floorl-tests (Files): Likewise.
+       * modules/frexpl-tests (Files): Likewise.
+       * modules/isnanl-tests (Files): Likewise.
+       * modules/ldexpl-tests (Files): Likewise.
+       * modules/roundl-tests (Files): Likewise.
+       * modules/truncl-tests (Files): Likewise.
+       * tests/test-ceill.c (main): Use a working NaN.
+       * tests/test-floorl.c (main): Likewise.
+       * tests/test-frexpl.c (main): Likewise.
+       * tests/test-isnan.c (test_long_double): Likewise.
+       * tests/test-isnanl.h (main): Likewise.
+       * tests/test-ldexpl.h (main): Likewise.
+       * tests/test-roundl.h (main): Likewise.
+       * tests/test-truncl.h (main): Likewise.
+       See http://lists.gnu.org/archive/html/bug-gnulib/2009-02/msg00190.html.
+
+2009-02-26  Eric Blake  <address@hidden>
+           Bruno Haible  <address@hidden>

        Work around a *printf bug with %ls on Solaris.
        * m4/printf.m4 (gl_PRINTF_DIRECTIVE_LS): Also test whether, when a
diff --git a/m4/isfinite.m4 b/m4/isfinite.m4
index 055ba82..019eb95 100644
--- a/m4/isfinite.m4
+++ b/m4/isfinite.m4
@@ -1,4 +1,4 @@
-# isfinite.m4 serial 4
+# isfinite.m4 serial 5
 dnl Copyright (C) 2007-2009 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -56,6 +56,17 @@ AC_DEFUN([gl_ISFINITEL_WORKS],
   ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
 typedef union { unsigned int word[NWORDS]; long double value; }
         memory_long_double;
+/* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the
+   runtime type conversion.  */
+#ifdef __sgi
+static long double NaNl ()
+{
+  double zero = 0.0;
+  return zero / zero;
+}
+#else
+# define NaNl() (0.0L / 0.0L)
+#endif
 int main ()
 {
   memory_long_double m;
@@ -65,7 +76,7 @@ int main ()
      in the mantissa bits.  The xor operation twiddles a bit that can only be
      a sign bit or a mantissa bit (since the exponent never extends to
      bit 31).  */
-  m.value = 0.0L / 0.0L;
+  m.value = NaNl ();
   m.word[NWORDS / 2] ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT 
- 1);
   for (i = 0; i < NWORDS; i++)
     m.word[i] |= 1;
diff --git a/m4/isnanl.m4 b/m4/isnanl.m4
index fb63ac4..e3029f5 100644
--- a/m4/isnanl.m4
+++ b/m4/isnanl.m4
@@ -1,4 +1,4 @@
-# isnanl.m4 serial 11
+# isnanl.m4 serial 12
 dnl Copyright (C) 2007-2009 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -133,20 +133,30 @@ AC_DEFUN([gl_FUNC_ISNANL_WORKS],
   ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
 typedef union { unsigned int word[NWORDS]; long double value; }
         memory_long_double;
+/* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the
+   runtime type conversion.  */
+#ifdef __sgi
+static long double NaNl ()
+{
+  double zero = 0.0;
+  return zero / zero;
+}
+#else
+# define NaNl() (0.0L / 0.0L)
+#endif
 int main ()
 {
   memory_long_double m;
   unsigned int i;

-  /* gcc-3.4.3 on IRIX 6.5 appears to have a problem with this.  */
-  if (!isnanl (0.0L / 0.0L))
+  if (!isnanl (NaNl ()))
     return 1;

   /* The isnanl function should be immune against changes in the sign bit and
      in the mantissa bits.  The xor operation twiddles a bit that can only be
      a sign bit or a mantissa bit (since the exponent never extends to
      bit 31).  */
-  m.value = 0.0L / 0.0L;
+  m.value = NaNl ();
   m.word[NWORDS / 2] ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT 
- 1);
   for (i = 0; i < NWORDS; i++)
     m.word[i] |= 1;
diff --git a/modules/ceill-tests b/modules/ceill-tests
index 381b3a5..ab10141 100644
--- a/modules/ceill-tests
+++ b/modules/ceill-tests
@@ -1,5 +1,6 @@
 Files:
 tests/test-ceill.c
+tests/nan.h

 Depends-on:
 fpucw
diff --git a/modules/floorl-tests b/modules/floorl-tests
index 7aef91d..ca7c746 100644
--- a/modules/floorl-tests
+++ b/modules/floorl-tests
@@ -1,5 +1,6 @@
 Files:
 tests/test-floorl.c
+tests/nan.h

 Depends-on:
 fpucw
diff --git a/modules/frexpl-tests b/modules/frexpl-tests
index 6291f4e..f5505b4 100644
--- a/modules/frexpl-tests
+++ b/modules/frexpl-tests
@@ -1,5 +1,6 @@
 Files:
 tests/test-frexpl.c
+tests/nan.h

 Depends-on:
 fpucw
diff --git a/modules/isnanl-tests b/modules/isnanl-tests
index 7b4086e..518420f 100644
--- a/modules/isnanl-tests
+++ b/modules/isnanl-tests
@@ -1,6 +1,7 @@
 Files:
 tests/test-isnanl.c
 tests/test-isnanl.h
+tests/nan.h

 Depends-on:
 float
diff --git a/modules/ldexpl-tests b/modules/ldexpl-tests
index 6c88bfd..0b1ba04 100644
--- a/modules/ldexpl-tests
+++ b/modules/ldexpl-tests
@@ -1,5 +1,6 @@
 Files:
 tests/test-ldexpl.c
+tests/nan.h

 Depends-on:
 fpucw
diff --git a/modules/roundl-tests b/modules/roundl-tests
index 8e329a5..442c279 100644
--- a/modules/roundl-tests
+++ b/modules/roundl-tests
@@ -1,5 +1,6 @@
 Files:
 tests/test-roundl.c
+tests/nan.h

 Depends-on:
 fpucw
diff --git a/modules/truncl-tests b/modules/truncl-tests
index 2365854..7ffc1cd 100644
--- a/modules/truncl-tests
+++ b/modules/truncl-tests
@@ -1,5 +1,6 @@
 Files:
 tests/test-truncl.c
+tests/nan.h

 Depends-on:
 fpucw
diff --git a/tests/nan.h b/tests/nan.h
index 3bdf643..8aa8bf0 100644
--- a/tests/nan.h
+++ b/tests/nan.h
@@ -1,5 +1,5 @@
 /* Macros for not-a-number.
-   Copyright (C) 2007-2008 Free Software Foundation, Inc.
+   Copyright (C) 2007-2009 Free Software Foundation, Inc.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -47,4 +47,14 @@ NaNd ()

 /* NaNl () returns a 'long double' not-a-number.  */

-#define NaNl() (0.0L / 0.0L)
+/* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the
+   runtime type conversion.  */
+#ifdef __sgi
+static long double NaNl ()
+{
+  double zero = 0.0;
+  return zero / zero;
+}
+#else
+# define NaNl() (0.0L / 0.0L)
+#endif
diff --git a/tests/test-ceill.c b/tests/test-ceill.c
index d1f0266..3d4c9e3 100644
--- a/tests/test-ceill.c
+++ b/tests/test-ceill.c
@@ -26,6 +26,7 @@

 #include "fpucw.h"
 #include "isnanl-nolibm.h"
+#include "nan.h"

 #define ASSERT(expr) \
   do                                                                        \
@@ -90,7 +91,7 @@ main ()
   ASSERT (ceill (1.0L / 0.0L) == 1.0L / 0.0L);
   ASSERT (ceill (-1.0L / 0.0L) == -1.0L / 0.0L);
   /* NaNs.  */
-  ASSERT (isnanl (ceill (0.0L / 0.0L)));
+  ASSERT (isnanl (ceill (NaNl ())));

   return 0;
 }
diff --git a/tests/test-floorl.c b/tests/test-floorl.c
index 14979e6..87fea7f 100644
--- a/tests/test-floorl.c
+++ b/tests/test-floorl.c
@@ -26,6 +26,7 @@

 #include "fpucw.h"
 #include "isnanl-nolibm.h"
+#include "nan.h"

 #define ASSERT(expr) \
   do                                                                        \
@@ -90,7 +91,7 @@ main ()
   ASSERT (floorl (1.0L / 0.0L) == 1.0L / 0.0L);
   ASSERT (floorl (-1.0L / 0.0L) == -1.0L / 0.0L);
   /* NaNs.  */
-  ASSERT (isnanl (floorl (0.0L / 0.0L)));
+  ASSERT (isnanl (floorl (NaNl ())));

   return 0;
 }
diff --git a/tests/test-frexpl.c b/tests/test-frexpl.c
index 2b968b8..d4babb8 100644
--- a/tests/test-frexpl.c
+++ b/tests/test-frexpl.c
@@ -26,6 +26,7 @@

 #include "fpucw.h"
 #include "isnanl-nolibm.h"
+#include "nan.h"

 /* Avoid some warnings from "gcc -Wshadow".
    This file doesn't use the exp() function.  */
@@ -95,7 +96,7 @@ main ()
   { /* NaN.  */
     int exp = -9999;
     long double mantissa;
-    x = 0.0L / 0.0L;
+    x = NaNl ();
     mantissa = frexpl (x, &exp);
     ASSERT (isnanl (mantissa));
   }
diff --git a/tests/test-isnan.c b/tests/test-isnan.c
index 6149017..9a0856a 100644
--- a/tests/test-isnan.c
+++ b/tests/test-isnan.c
@@ -163,14 +163,14 @@ test_long_double (void)
   ASSERT (!isnan (1.0L / 0.0L));
   ASSERT (!isnan (-1.0L / 0.0L));
   /* Quiet NaN.  */
-  ASSERT (isnan (0.0L / 0.0L));
+  ASSERT (isnan (NaNl ()));

 #if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
   /* A bit pattern that is different from a Quiet NaN.  With a bit of luck,
      it's a Signalling NaN.  */
   {
     memory_long_double m;
-    m.value = 0.0L / 0.0L;
+    m.value = NaNl ();
 # if LDBL_EXPBIT0_BIT > 0
     m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1);
 # else
diff --git a/tests/test-isnanl.h b/tests/test-isnanl.h
index 37e2857..baf04db 100644
--- a/tests/test-isnanl.h
+++ b/tests/test-isnanl.h
@@ -21,6 +21,8 @@
 #include <stdio.h>
 #include <stdlib.h>

+#include "nan.h"
+
 #define ASSERT(expr) \
   do                                                                        \
     {                                                                       \
@@ -70,14 +72,14 @@ main ()
   ASSERT (!isnanl (1.0L / 0.0L));
   ASSERT (!isnanl (-1.0L / 0.0L));
   /* Quiet NaN.  */
-  ASSERT (isnanl (0.0L / 0.0L));
+  ASSERT (isnanl (NaNl ()));

 #if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
   /* A bit pattern that is different from a Quiet NaN.  With a bit of luck,
      it's a Signalling NaN.  */
   {
     memory_long_double m;
-    m.value = 0.0L / 0.0L;
+    m.value = NaNl ();
 # if LDBL_EXPBIT0_BIT > 0
     m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1);
 # else
diff --git a/tests/test-ldexpl.c b/tests/test-ldexpl.c
index 395c00f..5f1fbd9 100644
--- a/tests/test-ldexpl.c
+++ b/tests/test-ldexpl.c
@@ -26,6 +26,7 @@

 #include "fpucw.h"
 #include "isnanl-nolibm.h"
+#include "nan.h"

 #define ASSERT(expr) \
   do                                                                        \
@@ -66,7 +67,7 @@ main ()
   BEGIN_LONG_DOUBLE_ROUNDING ();

   { /* NaN.  */
-    x = 0.0L / 0.0L;
+    x = NaNl ();
     y = ldexpl (x, 0); ASSERT (isnanl (y));
     y = ldexpl (x, 5); ASSERT (isnanl (y));
     y = ldexpl (x, -5); ASSERT (isnanl (y));
diff --git a/tests/test-roundl.c b/tests/test-roundl.c
index 51cd1cd..ddbf474 100644
--- a/tests/test-roundl.c
+++ b/tests/test-roundl.c
@@ -28,6 +28,7 @@

 #include "fpucw.h"
 #include "isnanl-nolibm.h"
+#include "nan.h"

 #define ASSERT(expr) \
   do                                                                        \
@@ -97,7 +98,7 @@ main ()
   ASSERT (roundl (1.0 / 0.0L) == 1.0 / 0.0L);
   ASSERT (roundl (-1.0 / 0.0L) == -1.0 / 0.0L);
   /* NaNs.  */
-  ASSERT (isnanl (roundl (0.0L / 0.0L)));
+  ASSERT (isnanl (roundl (NaNl ())));

   return 0;
 }
diff --git a/tests/test-truncl.c b/tests/test-truncl.c
index aad677d..f8ce551 100644
--- a/tests/test-truncl.c
+++ b/tests/test-truncl.c
@@ -26,6 +26,7 @@

 #include "fpucw.h"
 #include "isnanl-nolibm.h"
+#include "nan.h"

 #define ASSERT(expr) \
   do                                                                        \
@@ -89,7 +90,7 @@ main ()
   ASSERT (truncl (1.0L / 0.0L) == 1.0L / 0.0L);
   ASSERT (truncl (-1.0L / 0.0L) == -1.0L / 0.0L);
   /* NaNs.  */
-  ASSERT (isnanl (truncl (0.0L / 0.0L)));
+  ASSERT (isnanl (truncl (NaNl ())));

   return 0;
 }
-- 
1.6.1.2


reply via email to

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