On Mon, 28 Nov 2016, Richard Biener wrote: > > The following fixes an optimization regression noted in PR78546 where > moving patterns from forwprop to match.pd missed one variant. > > Bootstrap & regtest running on x86_64-unknown-linux-gnu.
The following is what I have applied (note the fix, the transform obviously need to transform to CST + A). I've adjusted surrounding patterns to use different CST names in comments. Richard. 2016-11-29 Richard Biener <rguent...@suse.de> PR middle-end/78546 * match.pd: Add CST1 - (CST2 - A) -> CST3 + A missing case. * gcc.dg/tree-ssa/forwprop-36.c: New testcase. Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 242952) +++ gcc/match.pd (working copy) @@ -1195,7 +1195,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (minus @0 (minus @0 @1)) @1) - /* (A +- CST) +- CST -> A + CST */ + /* (A +- CST1) +- CST2 -> A + CST3 */ (for outer_op (plus minus) (for inner_op (plus minus) (simplify @@ -1208,7 +1208,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (cst && !TREE_OVERFLOW (cst)) (inner_op @0 { cst; } )))))) - /* (CST - A) +- CST -> CST - A */ + /* (CST1 - A) +- CST2 -> CST3 - A */ (for outer_op (plus minus) (simplify (outer_op (minus CONSTANT_CLASS_P@1 @0) CONSTANT_CLASS_P@2) @@ -1216,6 +1216,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (cst && !TREE_OVERFLOW (cst)) (minus { cst; } @0))))) + /* CST1 - (CST2 - A) -> CST3 + A */ + (simplify + (minus CONSTANT_CLASS_P@1 (minus CONSTANT_CLASS_P@2 @0)) + (with { tree cst = const_binop (MINUS_EXPR, type, @1, @2); } + (if (cst && !TREE_OVERFLOW (cst)) + (plus { cst; } @0)))) + /* ~A + A -> -1 */ (simplify (plus:c (bit_not @0) @0) Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c (revision 0) +++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c (working copy) @@ -0,0 +1,24 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O -fdump-tree-cddce1" } */ + +typedef unsigned __int128 u128; + +u128 a, b; + +static inline u128 +foo (u128 p1) +{ + p1 += ~b; + return -p1; +} + +int +main () +{ + u128 x = foo (~0x7fffffffffffffff); + if (x != 0x8000000000000001) + __builtin_abort(); + return 0; +} + +/* { dg-final { scan-tree-dump "if \\(b.0_\[0-9\]+ != 0\\)" "cddce1" } } */