-----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 e...@byu.net -----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 <e...@byu.net> 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 <e...@byu.net> --- 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 <e...@byu.net> - Bruno Haible <br...@clisp.org> + + 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 <e...@byu.net> + Bruno Haible <br...@clisp.org> 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