Commit de4b6238 by Sujoy Saraswati Committed by Sujoy Saraswati

This series of patches fix PR61441.

This series of patches fix PR61441. 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.

gcc/
	* 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.

From-SVN: r231872
parent 091534a9
2015-12-21 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.
2015-12-20 Jeff Law <law@redhat.com> 2015-12-20 Jeff Law <law@redhat.com>
PR tree-optimization/64910 PR tree-optimization/64910
...@@ -541,6 +541,10 @@ do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, ...@@ -541,6 +541,10 @@ do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
case CLASS2 (rvc_normal, rvc_inf): case CLASS2 (rvc_normal, rvc_inf):
/* R + Inf = Inf. */ /* R + Inf = Inf. */
*r = *b; *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; r->sign = sign ^ subtract_p;
return false; return false;
...@@ -554,6 +558,10 @@ do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, ...@@ -554,6 +558,10 @@ do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
case CLASS2 (rvc_inf, rvc_normal): case CLASS2 (rvc_inf, rvc_normal):
/* Inf + R = Inf. */ /* Inf + R = Inf. */
*r = *a; *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; return false;
case CLASS2 (rvc_inf, rvc_inf): case CLASS2 (rvc_inf, rvc_inf):
...@@ -676,6 +684,10 @@ do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, ...@@ -676,6 +684,10 @@ do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
case CLASS2 (rvc_nan, rvc_nan): case CLASS2 (rvc_nan, rvc_nan):
/* ANY * NaN = NaN. */ /* ANY * NaN = NaN. */
*r = *b; *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; r->sign = sign;
return false; return false;
...@@ -684,6 +696,10 @@ do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, ...@@ -684,6 +696,10 @@ do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
case CLASS2 (rvc_nan, rvc_inf): case CLASS2 (rvc_nan, rvc_inf):
/* NaN * ANY = NaN. */ /* NaN * ANY = NaN. */
*r = *a; *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; r->sign = sign;
return false; return false;
...@@ -826,6 +842,10 @@ do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, ...@@ -826,6 +842,10 @@ do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
case CLASS2 (rvc_nan, rvc_nan): case CLASS2 (rvc_nan, rvc_nan):
/* ANY / NaN = NaN. */ /* ANY / NaN = NaN. */
*r = *b; *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; r->sign = sign;
return false; return false;
...@@ -834,6 +854,10 @@ do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, ...@@ -834,6 +854,10 @@ do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
case CLASS2 (rvc_nan, rvc_inf): case CLASS2 (rvc_nan, rvc_inf):
/* NaN / ANY = NaN. */ /* NaN / ANY = NaN. */
*r = *a; *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; r->sign = sign;
return false; return false;
...@@ -964,6 +988,10 @@ do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a) ...@@ -964,6 +988,10 @@ do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
case rvc_zero: case rvc_zero:
case rvc_inf: case rvc_inf:
case rvc_nan: 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; break;
case rvc_normal: case rvc_normal:
...@@ -1022,7 +1050,13 @@ real_arithmetic (REAL_VALUE_TYPE *r, int icode, const REAL_VALUE_TYPE *op0, ...@@ -1022,7 +1050,13 @@ real_arithmetic (REAL_VALUE_TYPE *r, int icode, const REAL_VALUE_TYPE *op0,
case MIN_EXPR: case MIN_EXPR:
if (op1->cl == rvc_nan) if (op1->cl == rvc_nan)
{
*r = *op1; *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) else if (do_compare (op0, op1, -1) < 0)
*r = *op0; *r = *op0;
else else
...@@ -1031,7 +1065,13 @@ real_arithmetic (REAL_VALUE_TYPE *r, int icode, const REAL_VALUE_TYPE *op0, ...@@ -1031,7 +1065,13 @@ real_arithmetic (REAL_VALUE_TYPE *r, int icode, const REAL_VALUE_TYPE *op0,
case MAX_EXPR: case MAX_EXPR:
if (op1->cl == rvc_nan) if (op1->cl == rvc_nan)
{
*r = *op1; *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) else if (do_compare (op0, op1, 1) < 0)
*r = *op1; *r = *op1;
else else
...@@ -1162,6 +1202,10 @@ real_ldexp (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0, int exp) ...@@ -1162,6 +1202,10 @@ real_ldexp (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0, int exp)
case rvc_zero: case rvc_zero:
case rvc_inf: case rvc_inf:
case rvc_nan: 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; break;
case rvc_normal: case rvc_normal:
...@@ -2527,7 +2571,7 @@ real_nan (REAL_VALUE_TYPE *r, const char *str, int quiet, ...@@ -2527,7 +2571,7 @@ real_nan (REAL_VALUE_TYPE *r, const char *str, int quiet,
/* Our MSB is always unset for NaNs. */ /* Our MSB is always unset for NaNs. */
r->sig[SIGSZ-1] &= ~SIG_MSB; r->sig[SIGSZ-1] &= ~SIG_MSB;
/* Force quiet or signalling NaN. */ /* Force quiet or signaling NaN. */
r->signalling = !quiet; r->signalling = !quiet;
} }
...@@ -2730,6 +2774,12 @@ real_convert (REAL_VALUE_TYPE *r, format_helper fmt, ...@@ -2730,6 +2774,12 @@ real_convert (REAL_VALUE_TYPE *r, format_helper fmt,
round_for_format (fmt, r); 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. */ /* round_for_format de-normalizes denormals. Undo just that part. */
if (r->cl == rvc_normal) if (r->cl == rvc_normal)
normalize (r); normalize (r);
...@@ -4943,7 +4993,8 @@ real_copysign (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *x) ...@@ -4943,7 +4993,8 @@ real_copysign (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *x)
r->sign = x->sign; 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 signaling NaN. */
bool bool
real_isinteger (const REAL_VALUE_TYPE *c, format_helper fmt) real_isinteger (const REAL_VALUE_TYPE *c, format_helper fmt)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment