https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68067
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> --- Ok, so we transform a - (b - c) to (c - b) + a, that's invalid of course. This also started with GCC 4.3.0. negate_expr_p has case MINUS_EXPR: /* We can't turn -(A-B) into B-A when we honor signed zeros. */ return !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type)) && !HONOR_SIGNED_ZEROS (element_mode (type)) && reorder_operands_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)); and fold_binary: /* A - B -> A + (-B) if B is easily negatable. */ if (negate_expr_p (arg1) && !TYPE_OVERFLOW_SANITIZED (type) && ((FLOAT_TYPE_P (type) /* Avoid this transformation if B is a positive REAL_CST. */ && (TREE_CODE (arg1) != REAL_CST || REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1)))) || INTEGRAL_TYPE_P (type))) return fold_build2_loc (loc, PLUS_EXPR, type, fold_convert_loc (loc, type, arg0), fold_convert_loc (loc, type, negate_expr (arg1))); we can see "!TYPE_OVERFLOW_SANITIZED" here, a clear sign that sth is wrong. I think the PLUS_EXPR case of negate_expr_p has the same issue A + B negated as -B - A or -A - B as as if A == INT_MIN and B == 0 we again get -0 - INT_MIN instead of INT_MIN + 0. Testcase: int main(void) { int a = -1; static int b = -2147483647 - 1; static int c = 0; int t = a - (b + c*-2); if (t != 2147483647) { __builtin_abort(); } return 0; }