For IBM long double, adding a normal number to a NaN raises an inexact exception. Adding any number to NaN should not raise any exception. The following testcase triggers the issue (the testcase is meant to run a gnu compatible libc): -------------------------------------------------------------- $ cat gcc_testcase.c #include <math.h> #include <fenv.h> #include <stdio.h> double sum (double x, long double y) { return x + y; } int main () { feenableexcept (FE_INEXACT); double x = __builtin_nan (""); long double y = 1.1L; printf ("%e\n", sum (x, y)); return 0; } $ gcc -O3 -m64 -fno-inline gcc_testcase.c -o gcc_testcase -lm $ ./gcc_testcase Floating point exception (core dumped) -------------------------------------------------------------- The issue is in __gcc_qadd implementation at libgcc/config/rs6000/ibm-ldouble.c, if the number if non finite, there is not check if it a NaN before actually summing all the components. A possible solution would be to add an extra test and return the first sum if the number if not infinity: Index: libgcc/config/rs6000/ibm-ldouble.c =================================================================== --- libgcc/config/rs6000/ibm-ldouble.c (revision 199159) +++ libgcc/config/rs6000/ibm-ldouble.c (working copy) @@ -104,6 +104,8 @@ if (nonfinite (z)) { + if (z != inf()) + return z; z = cc + aa + c + a; if (nonfinite (z)) return z;
(In reply to Adhemerval Zanella from comment #0) > Adding any number to NaN should not raise any exception. Not quite true -- QNaN should not raise any exception, but SNaN should raise Invalid.
You are correct and I meant in my first comment QNaN for the NaN work. And I believe the patch is still correct: for IBM long double SNaN will be represented by first double being the NaN (the second double is ignored) and the first sum (z = a + c) will trigger exception if any.
Hi Adhemerval, I'm also seeing that this patch fixes some glibc failures. What's the status of this? Were you planning to submit it for inclusion? B.t.w. I'm wondering if we don't need to use + if (fabs (z) != inf()) + return z; instead; z could still be minus infinity, right?
Fixed. http://gcc.gnu.org/ml/gcc-cvs/2013-12/msg00087.html