diff mbox

[PR,57363] IBM long double: adding qNaN and number raises inexact exception

Message ID 52861ACD.5050000@linux.vnet.ibm.com
State New
Headers show

Commit Message

Adhemerval Zanella Nov. 15, 2013, 12:59 p.m. UTC
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  <azanella@linux.vnet.ibm.com>

	* libgcc/config/rs6000/ibm-ldouble.c (__gcc_qadd): Fix add
 	of normal number and sNaN to not raise an inexact exception.

---
diff mbox

Patch

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;