According to Bruno Haible on 12/26/2008 4:33 AM: >> the latest m4 source code, where test-frexpl, test-isnanl, and >> test-vasprintf-posix all failed on an Irix 6.5 host: >> >> checking whether isnanl works... no >> checking where to find the exponent in a 'long double'... word 0 bit 20 >> >> test-isnanl.h:67: assertion failed >> /bin/ksh[10]: 691015 Abort(coredump) >> FAIL: test-isnanl-nolibm > > I fear I cannot do anything about it since I cannot reproduce it. On IRIX 6.5, > all these tests pass for me with CC=gcc, and I get another failure (for -0.0L) > with CC="cc -O". > > Can you debug this a bit?
I'm still looking into the NaN issue. But so far, I've discovered this about -0.0L on Irix 6.2: With 'cc -n32', LDBL_MIN is a compile-time constant; but with 'gcc', I get an error when trying to use it to initialize a global variable (note, however, that it can be used inside the body of a method): foo.c:9: error: initializer element is not constant To work around that, I used 1e-300 as a close approximation to LDBL_MIN; similarly for LDBL_MAX. With this test program: #include <float.h> #include <math.h> #include <stdio.h> #include <string.h> long double x = 1.0L; long double y = -0.0L; long double z = 0.0L; long double yy = -1e-300 * 1e-300; long double yyy = -1e-300 / 1e300; int different_from_plus_zero (long double arg) { return memcmp (&arg, &z, sizeof (z)) != 0; } int main() { printf ("%Lf\n", x / y); printf ("%d\n", x / y < 0); printf ("%d\n", different_from_plus_zero (y)); printf ("%Lf\n", x / yy); printf ("%d\n", x / yy < 0); printf ("%d\n", different_from_plus_zero (yy)); printf ("%Lf\n", x / yyy); printf ("%d\n", x / yyy < 0); printf ("%d\n", different_from_plus_zero (yyy)); { long double x = 1.0L; long double y = -0.0L; printf ("%Lf\n", x / y); printf ("%d\n", x / y < 0); printf ("%d\n", different_from_plus_zero (y)); } #define x 1.0L #define y -0.0L printf ("%Lf\n", x / y); printf ("%d\n", x / y < 0); printf ("%d\n", different_from_plus_zero (y)); #undef y #define y -z printf ("%Lf\n", x / y); printf ("%d\n", x / y < 0); printf ("%d\n", different_from_plus_zero (y)); #undef y #define y (-LDBL_MIN * LDBL_MIN) printf ("%Lf\n", x / y); printf ("%d\n", x / y < 0); printf ("%d\n", different_from_plus_zero (y)); #undef y #define y (-LDBL_MIN / LDBL_MAX) printf ("%Lf\n", x / y); printf ("%d\n", x / y < 0); printf ("%d\n", different_from_plus_zero (y)); return 0; } cc gives the following: inf 0 0 inf 0 0 inf 0 0 -inf 1 1 -inf 1 1 -inf 1 1 -inf 1 1 -inf 1 1 while gcc gives: -inf 1 1 -inf 1 1 -inf 1 1 -inf 1 1 -inf 1 1 -inf 1 1 -inf 1 1 -inf 1 1 My conclusion: cc is buggy when representing -0.0L as a global variable, but any variant that computes -0.0L during the body of a method works. Therefore, we need to scrub gnulib tests to guarantee that we never compute -0.0L except inside a method. For example, m4/signbit.m4 looks okay, whereas tests/test-ceill.c does not. I think the only sane way to work around this is to write a helper function (since Irix cc can compute -0.0L inside a function), then use that function instead of global storage in all of our unit tests. Bruno, do you want to tackle this, or do you want me to take a first shot at it? -- Don't work too hard, make some time for fun as well! Eric Blake e...@byu.net
signature.asc
Description: OpenPGP digital signature