summaryrefslogtreecommitdiff
path: root/gcc/fold-const-call.c
diff options
context:
space:
mode:
authorssaraswati <ssaraswati@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-22 14:04:30 +0000
committerssaraswati <ssaraswati@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-22 14:04:30 +0000
commit9f27d92a0f688fd50e1cf5cfc638cdbaec885a3f (patch)
treeb911e1bd2a2f7a4a924f976f2156da6ea60dc25c /gcc/fold-const-call.c
parentdf3be8f9acb97fcb935ca29690626769fa0a6b9c (diff)
downloadgcc-9f27d92a0f688fd50e1cf5cfc638cdbaec885a3f.tar.gz
This series of patches fix PR61441. This patch avoids various transformations
with signaling NaN operands when flag_signaling_nans is on, to avoid folding which would lose exceptions. Bootstrapped & regression-tested on x86_64-linux-gnu. gcc/ * fold-const.c (const_binop): Convert sNaN to qNaN when flag_signaling_nans is off. (const_unop): Avoid the operation, other than NEGATE and ABS, if flag_signaling_nans is on and the operand is an sNaN. (fold_convert_const_real_from_real): Avoid the operation if flag_signaling_nans is on and the operand is an sNaN. (integer_valued_real_unary_p): Update comment stating it returns false for sNaN values. (integer_valued_real_binary_p, integer_valued_real_call_p): Same. (integer_valued_real_single_p): Same. (integer_valued_real_invalid_p, integer_valued_real_p): Same. * fold-const-call.c (fold_const_pow): Avoid the operation if flag_signaling_nans is on and the operand is an sNaN. (fold_const_builtin_load_exponent) Same. (fold_const_call_sss): Same for CASE_CFN_POWI. * gimple-fold.c (gimple_assign_integer_valued_real_p): Same. (gimple_call_integer_valued_real_p): Same. (gimple_phi_integer_valued_real_p): Same. (gimple_stmt_integer_valued_real_p): Same. * simplify-rtx.c (simplify_const_unary_operation): Avoid the operation if flag_signaling_nans is on and the operand is an sNaN. (simplify_const_binary_operation): Same. * tree-ssa-math-opts.c (gimple_expand_builtin_pow): Avoid the operation if flag_signaling_nans is on and the operand is an sNaN. * gcc.dg/pr61441.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231901 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const-call.c')
-rw-r--r--gcc/fold-const-call.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c
index 94801d23fde..7d1351c3691 100644
--- a/gcc/fold-const-call.c
+++ b/gcc/fold-const-call.c
@@ -512,7 +512,11 @@ fold_const_pow (real_value *result, const real_value *arg0,
|| !real_equal (arg0, &dconst0)))
{
bool inexact = real_powi (result, format, arg0, n1);
- if (flag_unsafe_math_optimizations || !inexact)
+ /* Avoid the folding if flag_signaling_nans is on. */
+ if (flag_unsafe_math_optimizations
+ || (!inexact
+ && !(flag_signaling_nans
+ && REAL_VALUE_ISSIGNALING_NAN (*arg0))))
return true;
}
@@ -541,6 +545,13 @@ fold_const_builtin_load_exponent (real_value *result, const real_value *arg0,
if (wi::les_p (arg1, -max_exp_adj) || wi::ges_p (arg1, max_exp_adj))
return false;
+ /* Don't perform operation if we honor signaling NaNs and
+ operand is a signaling NaN. */
+ if (!flag_unsafe_math_optimizations
+ && flag_signaling_nans
+ && REAL_VALUE_ISSIGNALING_NAN (*arg0))
+ return false;
+
REAL_VALUE_TYPE initial_result;
real_ldexp (&initial_result, arg0, arg1.to_shwi ());
@@ -1202,6 +1213,13 @@ fold_const_call_sss (real_value *result, combined_fn fn,
format));
CASE_CFN_POWI:
+ /* Avoid the folding if flag_signaling_nans is on and
+ operand is a signaling NaN. */
+ if (!flag_unsafe_math_optimizations
+ && flag_signaling_nans
+ && REAL_VALUE_ISSIGNALING_NAN (*arg0))
+ return false;
+
real_powi (result, format, arg0, arg1.to_shwi ());
return true;