From de4b6238e7501adbb9cec02005d7605c1dbeb398 Mon Sep 17 00:00:00 2001 From: Sujoy Saraswati Date: Mon, 21 Dec 2015 07:59:30 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 8 ++++++++ gcc/real.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 2 deletions(-) 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) -- 2.30.2