https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81227
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- As input we get: (gdb) p debug_tree (val1) <plus_expr 0x7ffff6d884b0 type <integer_type 0x7ffff6d572a0 public QI size <integer_cst 0x7ffff6c3fdc8 constant 8> unit size <integer_cst 0x7ffff6c3fde0 constant 1> align 8 symtab 0 alias set -1 canonical type 0x7ffff6d572a0 precision 1 min <integer_cst 0x7ffff6d6a270 -1> max <integer_cst 0x7ffff6d6a288 0>> arg 0 <ssa_name 0x7ffff6c4ac18 type <integer_type 0x7ffff6d572a0> visited def_stmt _9 = b.a; version 9> arg 1 <integer_cst 0x7ffff6d6a738 type <integer_type 0x7ffff6d572a0> constant public overflow -1>> that's from trying to set a symbolic range where we try to build if (TYPE_PRECISION (TREE_TYPE (min)) == 1 && !TYPE_UNSIGNED (TREE_TYPE (min))) min = fold_build2 (MINUS_EXPR, TREE_TYPE (min), min, build_int_cst (TREE_TYPE (min), -1)); thus _9 - -1 but that's folded to _9 + -1(OVF) via /* A - B -> A + (-B) if B is easily negatable. */ (simplify (minus @0 negate_expr_p@1) (if (!FIXED_POINT_TYPE_P (type)) (plus @0 (negate @1)))) and (match negate_expr_p INTEGER_CST (if ((INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type)) || (!TYPE_OVERFLOW_SANITIZED (type) && may_negate_without_overflow_p (t))))) uncovering the old issue that implementation defined "overflow" still causes TREE_OVERFLOW to be set. I suppose the above (copied from fold-const.c negate_expr_p) should eventually not say that MSB only unsigned is easily negated. Or fold_negate_const should not do case INTEGER_CST: { bool overflow; wide_int val = wi::neg (arg0, &overflow); t = force_fit_type (type, val, 1, (overflow | TREE_OVERFLOW (arg0)) && !TYPE_UNSIGNED (type)); but check && ! TYPE_OVERFLOW_WRAPS (type) here. OTOH int_const_binop looks at the sign of the type only as well. IMHO simplifying and aligning fold-const.c and match.pd here w/o changing when we set TREE_OVERFLOW makes sense: Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 249435) +++ gcc/fold-const.c (working copy) @@ -383,9 +383,6 @@ negate_expr_p (tree t) switch (TREE_CODE (t)) { case INTEGER_CST: - if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type)) - return true; - /* Check that -CST will not overflow type. */ return may_negate_without_overflow_p (t); case BIT_NOT_EXPR: Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 249435) +++ gcc/match.pd (working copy) @@ -834,10 +834,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* A few cases of fold-const.c negate_expr_p predicate. */ (match negate_expr_p INTEGER_CST - (if ((INTEGRAL_TYPE_P (type) - && TYPE_OVERFLOW_WRAPS (type)) - || (!TYPE_OVERFLOW_SANITIZED (type) - && may_negate_without_overflow_p (t))))) + (if (may_negate_without_overflow_p (t)))) (match negate_expr_p FIXED_CST) (match negate_expr_p