https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103406
--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> --- And the -nan vs. nan is because we fold x + -y to x - y: /* We can't reassociate at all for saturating types. */ (if (!TYPE_SATURATING (type)) /* Contract negates. */ /* A + (-B) -> A - B */ (simplify (plus:c @0 (convert? (negate @1))) /* Apply STRIP_NOPS on the negate. */ (if (tree_nop_conversion_p (type, TREE_TYPE (@1)) && !TYPE_OVERFLOW_SANITIZED (type)) (with { tree t1 = type; if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type) != TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1))) t1 = TYPE_OVERFLOW_WRAPS (type) ? type : TREE_TYPE (@1); } (convert (minus (convert:t1 @0) (convert:t1 @1)))))) all the negate contracting misses HONOR_SIGNED_ZEROS/HONOR_NANS checking? Not sure if they are really a problem for signed zeros? If so we should try to get a testcase for that as well. diff --git a/gcc/match.pd b/gcc/match.pd index 5adcd6bd02c..9cdd113e02c 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2471,7 +2473,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (plus:c @0 (convert? (negate @1))) /* Apply STRIP_NOPS on the negate. */ (if (tree_nop_conversion_p (type, TREE_TYPE (@1)) - && !TYPE_OVERFLOW_SANITIZED (type)) + && !TYPE_OVERFLOW_SANITIZED (type) + && (!FLOAT_TYPE_P (type) || !tree_expr_maybe_nan_p (@1))) (with { tree t1 = type; @@ -2484,7 +2487,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (minus @0 (convert? (negate @1))) (if (tree_nop_conversion_p (type, TREE_TYPE (@1)) - && !TYPE_OVERFLOW_SANITIZED (type)) + && !TYPE_OVERFLOW_SANITIZED (type) + && (!FLOAT_TYPE_P (type) || !tree_expr_maybe_nan_p (@1))) (with { tree t1 = type; btw, that doesn't fix it since combine will happily contract the negate as well: - 10: {r88:DF=-r83:DF;use r89:V2DF;clobber flags:CC;} - REG_DEAD r89:V2DF - REG_UNUSED flags:CC - 11: r90:DF=r88:DF+r83:DF - REG_DEAD r88:DF + 9: NOTE_INSN_DELETED + 10: NOTE_INSN_DELETED + 11: r90:DF=r83:DF-r83:DF