When looking at a libstdc++ testsuite failure on IRIX 6.5 FAIL: 18_support/numeric_limits/epsilon.cc execution test Assertion failed: EX, file /vol/gcc/src/hg/gcc-4.6-branch/local/libstdc++-v3/testsuite/18_support/numeric_limits/epsilon.cc, line 37 I found that the testcase aborts checking long double LDBL_EPSILON: Program received signal SIGABRT, Aborted. 0x0fa4ac28 in _prctl () from /usr/lib32/libc.so.1 (gdb) where [...] #5 0x0fa756c4 in __assert () at /xlv86/patches/7207/work/irix/lib/libc/libc_n32_M4/gen/assert.c:59 #6 0x10002210 in test_epsilon<long double> () at /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/18_support/numeric_limits/epsilon.cc:37 #7 0x10002108 in main () at /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/18_support/numeric_limits/epsilon.cc:44 While epsilon is printed as 0 here, in mips-sgi-irix6.5/libstdc++-v3/include/limits, I find __LDBL_EPSILON__ is -1.596672247627775849325098170429471e+293 Running the testcase through g++ -g3 -save-temps, epsilon.ii reveals #define __FLT_EPSILON__ 1.19209289550781250000000000000000e-7F #define __DBL_EPSILON__ double(2.22044604925031308084726333618164e-16L) #define __LDBL_EPSILON__ 4.94065645841246544176568792868221e-324L which is obviously bogus. The native <internal/float_core.h> has #define FLT_EPSILON 1.19209290E-07F #define DBL_EPSILON 2.2204460492503131E-16 #define LDBL_EPSILON 1.232595164407830945955825883254353E-32L IRIX 6 uses the IBM double format for long double. As expected, the gcc.target/powerpc/rs6000-ldouble-2.c testcase also FAILs. eps is correctly determined: (gdb) p eps $1 = 2.465190328815661891911651766508707e-32 This can be seen with the following test: $ cat ld.c #include <stdio.h> #include <float.h> int main (void) { printf ("LDBL_EPSILON = %Lg\n", LDBL_EPSILON); return 0; } $ cc -o ld-cc ld.c $ ./ld-cc LDBL_EPSILON = 1.2326e-32 $ ./xgcc -B./ -o ld-gcc ld.c $ ./ld-gcc LDBL_EPSILON = 4.94066e-324
On Tue, 29 Mar 2011, ro at gcc dot gnu.org wrote: > Running the testcase through g++ -g3 -save-temps, epsilon.ii reveals > > #define __FLT_EPSILON__ 1.19209289550781250000000000000000e-7F > #define __DBL_EPSILON__ double(2.22044604925031308084726333618164e-16L) > #define __LDBL_EPSILON__ 4.94065645841246544176568792868221e-324L > > which is obviously bogus. The native <internal/float_core.h> has Why do you think this is bogus? It's correct for IBM long double, where the mantissa bits can be discontiguous, and so the least value greater than 1 that is representable has such discontiguous bits. See PR 19405 and <http://gcc.gnu.org/ml/gcc-patches/2005-01/msg00374.html>.
> Why do you think this is bogus? It's correct for IBM long double, where > the mantissa bits can be discontiguous, and so the least value greater > than 1 that is representable has such discontiguous bits. See PR 19405 > and <http://gcc.gnu.org/ml/gcc-patches/2005-01/msg00374.html>. But why do both that exact testcase and the libstdc++ one fail with this LDFL_EPSILON value on IRIX, and disagree with both the one from the system headers, which is identical to the one found in the gcc.target/powerpc/rs6000-ldouble-2.c test? Rainer
On Wed, 30 Mar 2011, ro at CeBiTec dot Uni-Bielefeld.DE wrote: > --- Comment #2 from ro at CeBiTec dot Uni-Bielefeld.DE <ro at CeBiTec dot Uni-Bielefeld.DE> 2011-03-30 15:16:57 UTC --- > > Why do you think this is bogus? It's correct for IBM long double, where > > the mantissa bits can be discontiguous, and so the least value greater > > than 1 that is representable has such discontiguous bits. See PR 19405 > > and <http://gcc.gnu.org/ml/gcc-patches/2005-01/msg00374.html>. > > But why do both that exact testcase and the libstdc++ one fail with this > LDFL_EPSILON value on IRIX, and disagree with both the one from the > system headers, which is identical to the one found in the > gcc.target/powerpc/rs6000-ldouble-2.c test? Presumably the implementation of long double arithmetic being used on IRIX is less accurate in this case than the one being used on Power. Perhaps it would make sense to look at using darwin-ldouble.c (with function names appropriately adjusted) in some way on IRIX, in place of the code in fp-bit.c. Since IRIX is the only target using the IBM long double support in fp-bit.c, it would then be possible to simplify fp-bit.* by removing all the HALFFRACBITS code. Alternatively, if the format on IRIX is actually defined differently so that the nonzero bits are always within a contiguous set of 106 bits - if that is what IRIX documentation and the IRIX system compiler / libraries always do - then the generic code could be taught about that difference and the code in fp-bit.c might be closer to being correct for that definition than darwin-ldouble.c
I can see the same problem under Linux (gcc110.fsffrance.org). According to the C standard (C99 and C11), the *_EPSILON values are "the difference between 1 and the least value greater than 1 that is representable in the given floating point type, b^(1-p)". Here b = 2 and p = LDBL_MANT_DIG = 106. I think that the C standard is badly worded. It should have said "the difference between 1 and the least floating-point value greater than 1 that is representable in the given type, b^(1-p)". What is regarded as a floating-point value is specified by the standard: see 5.2.4.2.2p2 "A floating-point number (x) is defined by the following model: [...]".
(In reply to Vincent Lefèvre from comment #4) > I can see the same problem under Linux (gcc110.fsffrance.org). In case this wasn't clear, the architecture is also a PowerPC. The double-double format comes from the PowerPC ABI, and isn't directly related to the OS itself (FYI it was also used under Mac OS X / PowerPC). Thus the summary of this bug should be changed to: LDBL_EPSILON is wrong on PowerPC
> --- Comment #5 from Vincent Lefèvre <vincent-gcc at vinc17 dot net> --- > (In reply to Vincent Lefèvre from comment #4) >> I can see the same problem under Linux (gcc110.fsffrance.org). > > In case this wasn't clear, the architecture is also a PowerPC. The > double-double format comes from the PowerPC ABI, and isn't directly related to > the OS itself (FYI it was also used under Mac OS X / PowerPC). > > Thus the summary of this bug should be changed to: > > LDBL_EPSILON is wrong on PowerPC Certainly not: IRIX isn't PowerPC but MIPS! If need be, just refer to the double/double format. Rainer
(In reply to ro@CeBiTec.Uni-Bielefeld.DE from comment #6) > Certainly not: IRIX isn't PowerPC but MIPS! OK, that wasn't clear because the original but report mentioned: "gcc.target/powerpc/rs6000-ldouble-2.c". ^^^^^^^ > If need be, just refer to the double/double format. Yes.
> --- Comment #7 from Vincent Lefèvre <vincent-gcc at vinc17 dot net> --- > (In reply to ro@CeBiTec.Uni-Bielefeld.DE from comment #6) >> Certainly not: IRIX isn't PowerPC but MIPS! > > OK, that wasn't clear because the original but report mentioned: > "gcc.target/powerpc/rs6000-ldouble-2.c". > ^^^^^^^ Right, but that test isn't run on regular testsuite runs on IRIX, although there's nothing powerpc specific in there except for the -mlong-double-128 option which can only be used on powerpc targets. Running it manually on IRIX shows the failure. Rainer
(In reply to Vincent Lefèvre from comment #5) > Thus the summary of this bug should be changed to: > > LDBL_EPSILON is wrong on PowerPC That is already part of PR 61399. Anyways IRIX support was removed in 2012 by r0-115719-gb24513a1a2bb35 for GCC 4.8.0.