Bug 57363 - IBM long double: adding NaN and number raises inexact exception
Summary: IBM long double: adding NaN and number raises inexact exception
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-05-21 19:42 UTC by Adhemerval Zanella
Modified: 2013-12-03 19:00 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Adhemerval Zanella 2013-05-21 19:42:54 UTC
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;
Comment 1 Richard Henderson 2013-07-02 18:43:38 UTC
(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.
Comment 2 Adhemerval Zanella 2013-07-03 13:43:10 UTC
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.
Comment 3 Ulrich Weigand 2013-11-13 20:59:22 UTC
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?
Comment 4 Ulrich Weigand 2013-12-03 19:00:13 UTC
Fixed.
http://gcc.gnu.org/ml/gcc-cvs/2013-12/msg00087.html