Hi Jeff,
On 10 October 2016 at 23:06, Jeff Law <l...@redhat.com> wrote: > > > So if we have an equality conditional between A & B, we record into our > const/copy tables A = B and B = A. > > This helps us discover some of the more obscure equivalences. But it also > creates problems with an expression like > > A ^ B > > Where we might cprop the first operand generating > > B ^ B > > Then the second generating > > B ^ A > > ANd we've lost the folding opportunity. At first I'd tried folding after > each propagation step, but that turns into a bit of a nightmare because of > changes in the underlying structure of the gimple statement and cycles that > may develop if we re-build the operand cache after folding. > > This approach is simpler and should catch all these cases for binary > operators. We just track the last copy propagated argument and refuse to > ping-pong propagations. > > It fixes the tests from 71947 and 77647 without regressing (obviously). I've > included an xfailed test for a more complex situation that we don't > currently handle (would require backtracking from the equality comparison > through the logicals that feed the equality comparison). > FWIW, this test is XPASS on arm-none-linux-gnueabihf --with-cpu=cortex-a5 --with-fpu=vfpv3-d16-fp16: Christophe > Bootstrapped and regression tested on x86_64. Applied to the trunk. > > > commit 6223e6e425b6de916f0330b9dbe5698765d4a73c > Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4> > Date: Mon Oct 10 20:40:59 2016 +0000 > > PR tree-optimization/71947 > * tree-ssa-dom.c (cprop_into_stmt): Avoid replacing A with B, then > B with A within a single statement. > > PR tree-optimization/71947 > * gcc.dg/tree-ssa/pr71947-1.c: New test. > * gcc.dg/tree-ssa/pr71947-2.c: New test. > * gcc.dg/tree-ssa/pr71947-3.c: New test. > * gcc.dg/tree-ssa/pr71947-4.c: New test. > * gcc.dg/tree-ssa/pr71947-5.c: New test. > * gcc.dg/tree-ssa/pr71947-6.c: New test. > > git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@240947 > 138bc75d-0d04-0410-961f-82ee72b054a4 > > diff --git a/gcc/ChangeLog b/gcc/ChangeLog > index 1738bc7..16e25bf 100644 > --- a/gcc/ChangeLog > +++ b/gcc/ChangeLog > @@ -1,3 +1,9 @@ > +2016-10-10 Jeff Law <l...@redhat.com> > + > + PR tree-optimization/71947 > + * tree-ssa-dom.c (cprop_into_stmt): Avoid replacing A with B, then > + B with A within a single statement. > + > 2016-10-10 Bill Schmidt <wschm...@linux.vnet.ibm.com> > > PR tree-optimization/77824 > diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog > index 04966cf..e31bcc6 100644 > --- a/gcc/testsuite/ChangeLog > +++ b/gcc/testsuite/ChangeLog > @@ -1,3 +1,13 @@ > +2016-10-10 Jeff Law <l...@redhat.com> > + > + PR tree-optimization/71947 > + * gcc.dg/tree-ssa/pr71947-1.c: New test. > + * gcc.dg/tree-ssa/pr71947-2.c: New test. > + * gcc.dg/tree-ssa/pr71947-3.c: New test. > + * gcc.dg/tree-ssa/pr71947-4.c: New test. > + * gcc.dg/tree-ssa/pr71947-5.c: New test. > + * gcc.dg/tree-ssa/pr71947-6.c: New test. > + > 2016-10-10 Thomas Koenig <tkoe...@gcc.gnu.org> > > PR fortran/77915 > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-1.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-1.c > new file mode 100644 > index 0000000..b033495 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-1.c > @@ -0,0 +1,19 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ > + > + > +int f(int x, int y) > +{ > + int ret; > + > + if (x == y) > + ret = x ^ y; > + else > + ret = 1; > + > + return ret; > +} > + > +/* { dg-final { scan-tree-dump "Folded to: ret_\[0-9\]+ = 0;" "dom2" } } > */ > + > + > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-2.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-2.c > new file mode 100644 > index 0000000..de8f88b > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-2.c > @@ -0,0 +1,16 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ > + > + > +int f(int x, int y) > +{ > + int ret; > + if (x == y) > + ret = x - y; > + else > + ret = 1; > + > + return ret; > +} > + > +/* { dg-final { scan-tree-dump "Folded to: ret_\[0-9\]+ = 0;" "dom2" } } > */ > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-3.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-3.c > new file mode 100644 > index 0000000..e79847f > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-3.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ > + > +int f(int x, int y) > +{ > + int ret = 10; > + if (x == y) > + ret = x - y; > + return ret; > +} > + > +/* { dg-final { scan-tree-dump "Folded to: ret_\[0-9\]+ = 0;" "dom2" } } > */ > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-4.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-4.c > new file mode 100644 > index 0000000..a881f0d > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-4.c > @@ -0,0 +1,22 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ > + > + > + > +static inline long load(long *p) > +{ > + long ret; > + asm ("movq %1,%0\n\t" : "=r" (ret) : "m" (*p)); > + if (ret != *p) > + __builtin_unreachable(); > + return ret; > +} > + > +long foo(long *mem) > +{ > + long ret; > + ret = load(mem); > + return ret + *mem; > +} > + > +/* { dg-final { scan-tree-dump "Folded to: _\[0-9\]+ = _\[0-9\]+ \\* 2" > "dom2" } } */ > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-5.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-5.c > new file mode 100644 > index 0000000..fa679f0 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-5.c > @@ -0,0 +1,21 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ > + > + > +static inline long load(long *p) > +{ > + long ret; > + asm ("movq %1,%0\n\t" : "=r" (ret) : "m" (*p)); > + if (ret != *p) > + __builtin_unreachable(); > + return ret; > +} > + > +long foo(long *mem) > +{ > + long ret; > + ret = load(mem); > + return ret - *mem; > +} > + > +/* { dg-final { scan-tree-dump "Folded to: _\[0-9\]+ = 0;" "dom2" } } */ > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71947-6.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-6.c > new file mode 100644 > index 0000000..9cb89cb > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71947-6.c > @@ -0,0 +1,16 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom-details" } */ > + > + > +int f(int x, int y, int a, int b) > +{ > + int ret = 10; > + if (a == x > + && b == y > + && a == b) > + ret = x - y; > + > + return ret; > +} > + > +/* { dg-final { scan-tree-dump "Folded to: ret_\[0-9\]+ = 0;" "dom2" { > xfail *-*-* } } } */ > diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c > index b007388..5376ff9 100644 > --- a/gcc/tree-ssa-dom.c > +++ b/gcc/tree-ssa-dom.c > @@ -1731,9 +1731,26 @@ cprop_into_stmt (gimple *stmt) > { > use_operand_p op_p; > ssa_op_iter iter; > + tree last_copy_propagated_op = NULL; > > FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_USE) > - cprop_operand (stmt, op_p); > + { > + tree old_op = USE_FROM_PTR (op_p); > + > + /* If we have A = B and B = A in the copy propagation tables > + (due to an equality comparison), avoid substituting B for A > + then A for B in the trivially discovered cases. This allows > + optimization of statements were A and B appear as input > + operands. */ > + if (old_op != last_copy_propagated_op) > + { > + cprop_operand (stmt, op_p); > + > + tree new_op = USE_FROM_PTR (op_p); > + if (new_op != old_op && TREE_CODE (new_op) == SSA_NAME) > + last_copy_propagated_op = new_op; > + } > + } > } > > /* Optimize the statement in block BB pointed to by iterator SI >