This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix 61441 [4/5] Produce quiet NaN for real value operations
- From: "Saraswati, Sujoy (OSTL)" <sujoy dot saraswati at hpe dot com>
- To: Joseph Myers <joseph at codesourcery dot com>, Sujoy Saraswati <ssaraswati at gmail dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Richard Biener <richard dot guenther at gmail dot com>
- Date: Thu, 26 Nov 2015 08:34:51 +0000
- Subject: Fix 61441 [4/5] Produce quiet NaN for real value operations
- Authentication-results: sourceware.org; auth=none
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 -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)