When moving tree-ssa-forwprop.c:associate_plusminus to match.pd patterns a single-use restriction escaped my eye. It is indeed important for non-simplifications like (ptr p+ off1) p+ off2 -> ptr p+ (off1 + off2) to not un-CSE. The association is most useful to enable later re-association as reassoc isn't able to associate pointer-plus chains but only unsigned integer arithmetic.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2014-11-20 Richard Biener <rguent...@suse.de> PR middle-end/63962 * match.pd ((p +p off1) +p off2 -> (p +p (off1 + off2))): Guard with single-use operand 0. * gcc.dg/tree-ssa/forwprop-30.c: New testcase. Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 217767) +++ gcc/match.pd (working copy) @@ -370,8 +370,9 @@ (define_operator_list inverted_tcc_compa /* Associate (p +p off1) +p off2 as (p +p (off1 + off2)). */ (simplify - (pointer_plus (pointer_plus @0 @1) @3) - (pointer_plus @0 (plus @1 @3))) + (pointer_plus (pointer_plus@2 @0 @1) @3) + (if (TREE_CODE (@2) != SSA_NAME || has_single_use (@2)) + (pointer_plus @0 (plus @1 @3)))) /* Pattern match tem1 = (long) ptr1; Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-30.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/forwprop-30.c (revision 0) +++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-30.c (working copy) @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +int *p; +int *foo (int *q, int i, int j) +{ + p = q + i; + return p + j; +} + +/* We shouldn't associate (q + i) + j to q + (i + j) here as we + need q + i as well. */ + +/* { dg-final { scan-tree-dump-times "\\+" 2 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */