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? 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