[backport gcc-4.8/trunk r194899 ] gcc/ 2013-01-04 Richard Biener PR middle-end/55863 * fold-const.c (split_tree): Undo -X - 1 to ~X folding for reassociation. gcc/testsuite/ 2013-01-04 Richard Biener PR middle-end/55863 * gcc.dg/fold-reassoc-2.c: New testcase. --- gcc-4.7.2/gcc/fold-const.c.~1~ 2012-06-01 19:03:19.000000000 +0200 +++ gcc-4.7.2/gcc/fold-const.c 2013-01-05 13:33:54.000000000 +0100 @@ -836,6 +836,13 @@ split_tree (tree in, enum tree_code code if (neg_var_p) var = negate_expr (var); } + else if (TREE_CODE (in) == BIT_NOT_EXPR + && code == PLUS_EXPR) + { + /* -X - 1 is folded to ~X, undo that here. */ + *minus_litp = build_one_cst (TREE_TYPE (in)); + var = negate_expr (TREE_OPERAND (in, 0)); + } else if (TREE_CONSTANT (in)) *conp = in; else --- gcc-4.7.2/gcc/testsuite/gcc.dg/fold-reassoc-2.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.2/gcc/testsuite/gcc.dg/fold-reassoc-2.c 2013-01-05 13:33:54.000000000 +0100 @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-original" } */ + +int foo (int i) +{ + return (i + 2) - (i + 1); +} +int bar (int i) +{ + return (i + 2) + ~i; +} + +/* { dg-final { scan-tree-dump "return 1;" "original" } } */ +/* { dg-final { cleanup-tree-dump "original" } } */