On 11/26/2015 01:38 AM, Saraswati, Sujoy (OSTL) wrote:
Hi,
This patch avoids various transformations with signaling NaN operands when
flag_signaling_nans is on, to avoid folding which would lose exceptions. A test
case for this change is also added as part of this patch.
Regards,
Sujoy
2015-11-26 Sujoy Saraswati <sujoy.sarasw...@hpe.com>
PR tree-optimization/61441
* 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 BUILT_IN_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.
PR tree-optimization/61441
* gcc.dg/pr61441.c: New testcase.
===================================================================
diff -u -p a/gcc/fold-const.c b/gcc/fold-const.c
--- a/gcc/fold-const.c 2015-11-25 15:24:49.656116740 +0530
+++ b/gcc/fold-const.c 2015-11-25 15:25:07.712117294 +0530
@@ -1166,9 +1166,21 @@ const_binop (enum tree_code code, tree a
/* If either operand is a NaN, just return it. Otherwise, set up
for floating-point trap; we return an overflow. */
if (REAL_VALUE_ISNAN (d1))
- return arg1;
+ {
+ /* Make resulting NaN value to be qNaN when flag_signaling_nans
+ is off. */
+ d1.signalling = 0;
+ t = build_real (type, d1);
+ return t;
+ }
else if (REAL_VALUE_ISNAN (d2))
- return arg2;
+ {
+ /* Make resulting NaN value to be qNaN when flag_signaling_nans
+ is off. */
+ d2.signalling = 0;
+ t = build_real (type, d2);
+ return t;
+ }
I was a bit worried about this hunk, but by the time we get here we
already know that at least one operand is a sNaN and that we're not
honoring sNaNs.
inexact = real_arithmetic (&value, code, &d1, &d2);
real_convert (&result, mode, &value);
@@ -1538,6 +1550,15 @@ const_binop (enum tree_code code, tree t
tree
const_unop (enum tree_code code, tree type, tree arg0)
{
+ /* Don't perform the operation, other than NEGATE and ABS, if
+ flag_signaling_nans is on and the operand is a NaN. */
+ if (TREE_CODE (arg0) == REAL_CST
+ && HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
+ && REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg0))
+ && code != NEGATE_EXPR
+ && code != ABS_EXPR)
+ return NULL_TREE;
Why let NEGATE_EXPR and ABS_EXPR pass through here? I realize that
these can often be implemented with bit-twiddling, so they're usually
considered special. BUt in this case aren't we just dealing with
constants and wouldn't we want to still express the neg/abs so that we
get a signal when the input value is sNaN rather than collapse down to a
constant?
/* Return true if the floating point result of (CODE OP0) has an
integer value. We also allow +Inf, -Inf and NaN to be considered
- integer values.
+ integer values. Return false for signalling NaN.
s/signalling/signaling/ I think it shows up in multiple places, so
check for it using search/replace.
Also watch for using 8 spaces rather than a tab in your patches. I
think I see occurrences of that mistake in this patch. SO just check
everything you changed to be sure you aren't adding new instances of
that nit.
I think a bit of explanation why you're letting NEGATE/ABS though in
const_unop, fixing the spelling goof and the <tab> instead of 8 spaces
nit need to be addressed before this can be committed.
jeff