Hi all,
For IBM long double, adding a normal number to a qNaN raises an inexact
exception. Adding any number to qNaN 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.
This also fixes two GLIBC math issues I'm seeing:
TEST_ff_f (nexttoward, qnan_value, 1.1L, qnan_value, NO_INEXACT_EXCEPTION),
TEST_ff_f (nexttoward, 1.1L, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
Fix tested on PPC32 and PPC64.
---
2013-11-15 Adhemerval Zanella <[email protected]>
* libgcc/config/rs6000/ibm-ldouble.c (__gcc_qadd): Fix add
of normal number and sNaN to not raise an inexact exception.
---
diff --git a/libgcc/config/rs6000/ibm-ldouble.c
b/libgcc/config/rs6000/ibm-ldouble.c
index 28e02e9..7ca900c 100644
--- a/libgcc/config/rs6000/ibm-ldouble.c
+++ b/libgcc/config/rs6000/ibm-ldouble.c
@@ -104,6 +104,8 @@ __gcc_qadd (double a, double aa, double c, double cc)
if (nonfinite (z))
{
+ if (fabs (z) != inf())
+ return z;
z = cc + aa + c + a;
if (nonfinite (z))
return z;