Hi!

As I wrote earlier today on gcc-patches, pr61441.c started failing
on i?86-linux when -fsignaling-nans argument has been added to it.

I believe this is because the simplify_const_unary_operation
changes in r231901 were broken, when the operand is a sNaN and
-fsignaling-nans, we want to avoid folding FLOAT_TRUNCATE, FLOAT_EXTEND
and FIX of a sNaN, not just return it unmodified (this is in a switch
that optionally modifies the real value just to create another CONST_DOUBLE
usually in a different mode out from it.  This patch instead
returns NULL, which means no simplification.

Bootstrapped/regtested on x86_64-linux and i686-linux, fixes pr61441.c
on the latter, ok for trunk?

2017-02-20  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/61441
        * simplify-rtx.c (simplify_const_unary_operation): For
        -fsignaling-nans and sNaN operand, return NULL_RTX rather than
        the sNaN unmodified.

--- gcc/simplify-rtx.c.jj       2017-01-01 12:45:37.000000000 +0100
+++ gcc/simplify-rtx.c  2017-02-20 20:02:33.446251366 +0100
@@ -1889,23 +1889,26 @@ simplify_const_unary_operation (enum rtx
        case FLOAT_TRUNCATE:
          /* Don't perform the operation if flag_signaling_nans is on
             and the operand is a signaling NaN.  */
-         if (!(HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d)))
-           d = real_value_truncate (mode, d);
+         if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
+           return NULL_RTX;
+         d = real_value_truncate (mode, d);
          break;
        case FLOAT_EXTEND:
-         /* All this does is change the mode, unless changing
-            mode class.  */
          /* Don't perform the operation if flag_signaling_nans is on
             and the operand is a signaling NaN.  */
-         if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op))
-             && !(HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d)))
+         if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
+           return NULL_RTX;
+         /* All this does is change the mode, unless changing
+            mode class.  */
+         if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
            real_convert (&d, mode, &d);
          break;
        case FIX:
          /* Don't perform the operation if flag_signaling_nans is on
             and the operand is a signaling NaN.  */
-         if (!(HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d)))
-           real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
+         if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
+           return NULL_RTX;
+         real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
          break;
        case NOT:
          {

        Jakub

Reply via email to