On February 6, 2018 9:40:37 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> 
wrote:
>Hi!
>
>As the following testcase shows, dom2 miscompiles floating point x - x
>into 0.0 even when x could be infinity and x - x then a NaN.
>The corresponding match.pd optimization is:
>/* Simplify x - x.
>   This is unsafe for certain floats even in non-IEEE formats.
>   In IEEE, it is unsafe because it does wrong for NaNs.
>   Also note that operand_equal_p is always false if an operand
>   is volatile.  */
>(simplify
> (minus @0 @0)
> (if (!FLOAT_TYPE_P (type) || !HONOR_NANS (type))
>  { build_zero_cst (type); }))
>The patch makes it match what match.pd does.
>We also have:
> /* X / X is one.  */
> (simplify
>  (div @0 @0)
>/* But not for 0 / 0 so that we can get the proper warnings and errors.
>     And not for _Fract types where we can't build 1.  */
>  (if (!integer_zerop (@0) && !ALL_FRACT_MODE_P (TYPE_MODE (type)))
>   { build_one_cst (type); }))
>We can ignore the 0 / 0 case, we have both operands SSA_NAMEs and
>match.pd
>only avoids optimizing away literal 0 / 0, but the rest is valid, some
>fract
>types don't have a way to express 1.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK. 

I wonder why we have to re-implement all this in DOM. there's enough of match 
and simplify interfaces to make it use that? 

Richard. 


>2018-02-06  Jakub Jelinek  <ja...@redhat.com>
>
>       PR tree-optimization/84235
>       * tree-ssa-scopedtables.c
>       (avail_exprs_stack::simplify_binary_operation): Fir MINUS_EXPR, punt
>       if the subtraction is performed in floating point type where NaNs are
>       honored.  For *DIV_EXPR, punt for ALL_FRACT_MODE_Ps where we can't
>       build 1.  Formatting fix.
>
>       * gcc.c-torture/execute/ieee/pr84235.c: New test.
>
>--- gcc/tree-ssa-scopedtables.c.jj     2018-01-03 10:19:54.528533857 +0100
>+++ gcc/tree-ssa-scopedtables.c        2018-02-06 14:58:08.944673984 +0100
>@@ -182,8 +182,15 @@ avail_exprs_stack::simplify_binary_opera
>                     case BIT_AND_EXPR:
>                       return gimple_assign_rhs1 (stmt);
> 
>-                    case BIT_XOR_EXPR:
>                     case MINUS_EXPR:
>+                      /* This is unsafe for certain floats even in non-IEEE
>+                         formats.  In IEEE, it is unsafe because it does
>+                         wrong for NaNs.  */
>+                      if (FLOAT_TYPE_P (result_type)
>+                          && HONOR_NANS (result_type))
>+                        break;
>+                      /* FALLTHRU */
>+                    case BIT_XOR_EXPR:
>                     case TRUNC_MOD_EXPR:
>                     case CEIL_MOD_EXPR:
>                     case FLOOR_MOD_EXPR:
>@@ -195,6 +202,9 @@ avail_exprs_stack::simplify_binary_opera
>                     case FLOOR_DIV_EXPR:
>                     case ROUND_DIV_EXPR:
>                     case EXACT_DIV_EXPR:
>+                      /* Avoid _Fract types where we can't build 1.  */
>+                      if (ALL_FRACT_MODE_P (TYPE_MODE (result_type)))
>+                        break;
>                       return build_one_cst (result_type);
> 
>                     default:
>@@ -204,8 +214,8 @@ avail_exprs_stack::simplify_binary_opera
>               break;
>             }
> 
>-            default:
>-              break;
>+          default:
>+            break;
>           }
>       }
>     }
>--- gcc/testsuite/gcc.c-torture/execute/ieee/pr84235.c.jj      2018-02-06
>15:04:26.528454766 +0100
>+++ gcc/testsuite/gcc.c-torture/execute/ieee/pr84235.c 2018-02-06
>15:05:06.836341334 +0100
>@@ -0,0 +1,11 @@
>+/* PR tree-optimization/84235 */
>+
>+int
>+main ()
>+{
>+  double d = 1.0 / 0.0;
>+  _Bool b = d == d && (d - d) != (d - d);
>+  if (!b)
>+    __builtin_abort ();
>+  return 0;
>+}
>
>       Jakub

Reply via email to