https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81297
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- So we fold (plus -1 -2147483648) with type 'int' and TYPE_OVERFLOW_WRAPS. That gets int_const_binop to set TREE_OVERFLOW (because generally fold only looks at the SIGN and not TYPE_OVERFLOW_* when setting TREE_OVERFLOW). The unfortunate thing here is that the overflow prevails in sth non-constant at the end. But recursively walking all trees to weed out TREE_OVERFLOW after each folding to non-constant looks awkward (and might even lead to more folding!?). Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 250725) +++ gcc/fold-const.c (working copy) @@ -9107,8 +9107,8 @@ expr_not_equal_to (tree t, const wide_in Return the folded expression if folding is successful. Otherwise, return NULL_TREE. */ -tree -fold_binary_loc (location_t loc, +static tree +fold_binary_loc_1 (location_t loc, enum tree_code code, tree type, tree op0, tree op1) { enum tree_code_class kind = TREE_CODE_CLASS (code); @@ -11177,6 +11177,31 @@ fold_binary_loc (location_t loc, } /* switch (code) */ } +static tree +drop_tree_overflow_r (tree *expr_p, int *ws, void *) +{ + if (TREE_OVERFLOW_P (*expr_p)) + { + *expr_p = drop_tree_overflow (*expr_p); + *ws = 0; + } + else if (! EXPR_P (*expr_p)) + *ws = 0; + return NULL_TREE; +} + +tree +fold_binary_loc (location_t loc, + enum tree_code code, tree type, tree op0, tree op1) +{ + tree res = fold_binary_loc_1 (loc, code, type, op0, op1); + if (res && ! TREE_CONSTANT (res)) + walk_tree (&res, drop_tree_overflow_r, NULL, NULL); + + return res; +} + + /* Callback for walk_tree, looking for LABEL_EXPR. Return *TP if it is a LABEL_EXPR; otherwise return NULL_TREE. Do not check the subtrees of GOTO_EXPR. */ note we're not properly re-building/folding subtrees here so fold checking might be unhappy. It's also not clear that just ignoring TREE_CONSTANT exprs is enough if you consider folding two non-constant but with dropped overflow parts to a constant afterwards... So I'm going to remove the assert in VRP that I added mainly for the -fstrict-overflow removal as a sanity check.