https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81097
--- Comment #3 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Well, my fix was
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -850,7 +850,8 @@ split_tree (location_t loc, tree in, tree type, enum
tree_code code,
else if (TREE_CONSTANT (in))
*conp = in;
else if (TREE_CODE (in) == BIT_NOT_EXPR
- && code == PLUS_EXPR)
+ && code == PLUS_EXPR
+ && negate_expr_p (TREE_OPERAND (in, 0)))
{
/* -X - 1 is folded to ~X, undo that here. Do _not_ do this
when IN is constant. */
but it has some fallout it seems.
Also, the comment says
-X - 1 is folded to ~X, undo that here.
but there was not -X - 1, the bit not came from
~x | ~y -> ~(x & y)
in match.pd.