From: Sujoy Saraswati Date: Mon, 21 Dec 2015 07:59:30 +0000 (+0000) Subject: This series of patches fix PR61441. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=de4b6238e7501adbb9cec02005d7605c1dbeb398;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 733c2898d25..44da7a6d38b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-12-21 Sujoy Saraswati + + 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 PR tree-optimization/64910 diff --git a/gcc/real.c b/gcc/real.c index 17d79c287f5..8c9aefe0698 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -541,6 +541,10 @@ do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a, 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_VALUE_TYPE *a, 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 REAL_VALUE_TYPE *a, 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 REAL_VALUE_TYPE *a, 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 REAL_VALUE_TYPE *a, 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 REAL_VALUE_TYPE *a, 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 REAL_VALUE_TYPE *a) 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 icode, const REAL_VALUE_TYPE *op0, 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 icode, const REAL_VALUE_TYPE *op0, 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 REAL_VALUE_TYPE *op0, int exp) 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: @@ -2527,7 +2571,7 @@ real_nan (REAL_VALUE_TYPE *r, const char *str, int quiet, /* Our MSB is always unset for NaNs. */ r->sig[SIGSZ-1] &= ~SIG_MSB; - /* Force quiet or signalling NaN. */ + /* Force quiet or signaling NaN. */ r->signalling = !quiet; } @@ -2730,6 +2774,12 @@ real_convert (REAL_VALUE_TYPE *r, format_helper fmt, 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); @@ -4943,7 +4993,8 @@ real_copysign (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *x) 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 real_isinteger (const REAL_VALUE_TYPE *c, format_helper fmt)