diff mbox

Fix 61441 [4/5] Produce quiet NaN for real value operations

Message ID 5379BA8D7E9D7E4D87BF6749A92854C248FC90E3@G4W3297.americas.hpqcorp.net
State New
Headers show

Commit Message

Sujoy Saraswati Nov. 26, 2015, 8:34 a.m. UTC
Hi,
 This patch makes resulting NaN values to be quiet NaN for real value operations, irrespective of the flag_signaling_nans flag. The caller has the responsibility to avoid the operation if flag_signaling_nans is on.
Regards,
Sujoy

    2015-11-26  Sujoy Saraswati <sujoy.saraswati@hpe.com>

            PR tree-optimization/61441
            * real.c (do_add): Make resulting NaN value to be qNaN.
             (do_multiply, do_divide, do_fix_trunc): Same.
             (real_arithmetic, real_ldexp, real_convert): Same.
             (real_isinteger): Updated comment stating it returns false for sNaN.
diff mbox

Patch

===================================================================
diff -u -p a/gcc/real.c b/gcc/real.c
--- a/gcc/real.c        2015-11-25 10:35:29.059583459 +0530
+++ b/gcc/real.c        2015-11-25 15:07:53.604085529 +0530
@@ -541,6 +541,10 @@  do_add (REAL_VALUE_TYPE *r, const REAL_V
     case CLASS2 (rvc_normal, rvc_inf):
       /* R + Inf = Inf.  */
       *r = *b;
+      /* Make resulting NaN value to be qNaN. The caller has the
+         responsibility to avoid the operation if flag_signaling_nans
+         is on.  */
+      r->signalling = 0;
       r->sign = sign ^ subtract_p;
       return false;

@@ -554,6 +558,10 @@  do_add (REAL_VALUE_TYPE *r, const REAL_V
     case CLASS2 (rvc_inf, rvc_normal):
       /* Inf + R = Inf.  */
       *r = *a;
+      /* Make resulting NaN value to be qNaN. The caller has the
+         responsibility to avoid the operation if flag_signaling_nans
+         is on.  */
+      r->signalling = 0;
       return false;

     case CLASS2 (rvc_inf, rvc_inf):
@@ -676,6 +684,10 @@  do_multiply (REAL_VALUE_TYPE *r, const R
     case CLASS2 (rvc_nan, rvc_nan):
       /* ANY * NaN = NaN.  */
       *r = *b;
+      /* Make resulting NaN value to be qNaN. The caller has the
+         responsibility to avoid the operation if flag_signaling_nans
+         is on.  */
+      r->signalling = 0;
       r->sign = sign;
       return false;

@@ -684,6 +696,10 @@  do_multiply (REAL_VALUE_TYPE *r, const R
     case CLASS2 (rvc_nan, rvc_inf):
       /* NaN * ANY = NaN.  */
       *r = *a;
+      /* Make resulting NaN value to be qNaN. The caller has the
+         responsibility to avoid the operation if flag_signaling_nans
+         is on.  */
+      r->signalling = 0;
       r->sign = sign;
       return false;

@@ -826,6 +842,10 @@  do_divide (REAL_VALUE_TYPE *r, const REA
     case CLASS2 (rvc_nan, rvc_nan):
       /* ANY / NaN = NaN.  */
       *r = *b;
+      /* Make resulting NaN value to be qNaN. The caller has the
+         responsibility to avoid the operation if flag_signaling_nans
+         is on.  */
+      r->signalling = 0;
       r->sign = sign;
       return false;

@@ -834,6 +854,10 @@  do_divide (REAL_VALUE_TYPE *r, const REA
     case CLASS2 (rvc_nan, rvc_inf):
       /* NaN / ANY = NaN.  */
       *r = *a;
+      /* Make resulting NaN value to be qNaN. The caller has the
+         responsibility to avoid the operation if flag_signaling_nans
+         is on.  */
+      r->signalling = 0;
       r->sign = sign;
       return false;

@@ -964,6 +988,10 @@  do_fix_trunc (REAL_VALUE_TYPE *r, const
     case rvc_zero:
     case rvc_inf:
     case rvc_nan:
+      /* Make resulting NaN value to be qNaN. The caller has the
+         responsibility to avoid the operation if flag_signaling_nans
+         is on.  */
+      r->signalling = 0;
       break;

     case rvc_normal:
@@ -1022,7 +1050,13 @@  real_arithmetic (REAL_VALUE_TYPE *r, int

     case MIN_EXPR:
       if (op1->cl == rvc_nan)
+      {
        *r = *op1;
+        /* Make resulting NaN value to be qNaN. The caller has the
+           responsibility to avoid the operation if flag_signaling_nans
+           is on.  */
+        r->signalling = 0;
+      }
       else if (do_compare (op0, op1, -1) < 0)
        *r = *op0;
       else
@@ -1031,7 +1065,13 @@  real_arithmetic (REAL_VALUE_TYPE *r, int

     case MAX_EXPR:
       if (op1->cl == rvc_nan)
+      {
        *r = *op1;
+        /* Make resulting NaN value to be qNaN. The caller has the
+           responsibility to avoid the operation if flag_signaling_nans
+           is on.  */
+        r->signalling = 0;
+      }
       else if (do_compare (op0, op1, 1) < 0)
        *r = *op1;
       else
@@ -1162,6 +1202,10 @@  real_ldexp (REAL_VALUE_TYPE *r, const RE
     case rvc_zero:
     case rvc_inf:
     case rvc_nan:
+      /* Make resulting NaN value to be qNaN. The caller has the
+         responsibility to avoid the operation if flag_signaling_nans
+         is on.  */
+      r->signalling = 0;
       break;

     case rvc_normal:
@@ -2731,6 +2775,12 @@  real_convert (REAL_VALUE_TYPE *r, format

   round_for_format (fmt, r);

+  /* Make resulting NaN value to be qNaN. The caller has the
+     responsibility to avoid the operation if flag_signaling_nans
+     is on.  */
+  if (r->cl == rvc_nan)
+    r->signalling = 0;
+
   /* round_for_format de-normalizes denormals.  Undo just that part.  */
   if (r->cl == rvc_normal)
     normalize (r);
@@ -4944,7 +4994,8 @@  real_copysign (REAL_VALUE_TYPE *r, const
   r->sign = x->sign;
 }

-/* Check whether the real constant value given is an integer.  */
+/* Check whether the real constant value given is an integer.
+   Returns false for signalling NaN.  */

 bool
 real_isinteger (const REAL_VALUE_TYPE *c, format_helper fmt)