From: Richard Biener Date: Thu, 23 Nov 2017 09:05:11 +0000 (+0000) Subject: re PR tree-optimization/23094 (store ccp, or store copy prop misses an optimization) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d7a160a45ea7ed09247788c708721c2813cf0007;p=gcc.git re PR tree-optimization/23094 (store ccp, or store copy prop misses an optimization) 2017-11-23 Richard Biener PR tree-optimization/23094 * tree-ssa-sccvn.c (vuse_ssa_val): Handle VN_TOP when we come here from walking over backedges in the first iteration. (vn_reference_lookup_3): Skip clobbers that store the same value. * gcc.dg/tree-ssa/ssa-fre-61.c: New testcase. From-SVN: r255093 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7cabfd66b93..837fa394218 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-11-23 Richard Biener + + PR tree-optimization/23094 + * tree-ssa-sccvn.c (vuse_ssa_val): Handle VN_TOP when we + come here from walking over backedges in the first iteration. + (vn_reference_lookup_3): Skip clobbers that store the same value. + 2017-11-23 Richard Biener PR tree-optimization/81403 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3dd20d14b68..ff35bcaf32f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-11-23 Richard Biener + + PR tree-optimization/23094 + * gcc.dg/tree-ssa/ssa-fre-61.c: New testcase. + 2017-11-23 Richard Biener PR tree-optimization/83089 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c new file mode 100644 index 00000000000..a4d9a7194bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c @@ -0,0 +1,43 @@ +/* { dg-do link } */ +/* { dg-options "-O -fdump-tree-fre1-details" } */ + +void link_error (void); + +void test1 (int *p, int *q) +{ + *p = 1; + *q = 1; + if (*p != 1) + link_error (); +} + +void test2 (int *p, int *q, int t) +{ + *p = t; + *q = t; + if (*p != t) + link_error (); +} + +void test3 (int *q, int *p) +{ + int tem = *p; + *q = tem; + if (*p != tem) + link_error (); +} + +char a[4]; +struct A { char a[4]; }; +void test4 (struct A *p) +{ + a[0] = p->a[0]; + a[0] = p->a[0]; + a[0] = p->a[0]; +} + +int main() { return 0; } + +/* { dg-final { scan-tree-dump-times "Replaced \\\*p" 3 "fre1" } } */ +/* { dg-final { scan-tree-dump-times "Replaced p_.\\(D\\)->" 2 "fre1" } } */ +/* { dg-final { scan-tree-dump-times "Deleted redundant store a\\\[0\\\]" 2 "fre1" } } */ diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index f5bc28efa70..d0ff30199e6 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -345,7 +345,12 @@ vuse_ssa_val (tree x) do { - x = SSA_VAL (x); + tree tem = SSA_VAL (x); + /* stmt walking can walk over a backedge and reach code we didn't + value-number yet. */ + if (tem == VN_TOP) + return x; + x = tem; } while (SSA_NAME_IN_FREE_LIST (x)); @@ -1868,6 +1873,39 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, ao_ref_init (&lhs_ref, lhs); lhs_ref_ok = true; } + + /* If we reach a clobbering statement try to skip it and see if + we find a VN result with exactly the same value as the + possible clobber. In this case we can ignore the clobber + and return the found value. + Note that we don't need to worry about partial overlapping + accesses as we then can use TBAA to disambiguate against the + clobbering statement when looking up a load (thus the + VN_WALKREWRITE guard). */ + if (vn_walk_kind == VN_WALKREWRITE + && is_gimple_reg_type (TREE_TYPE (lhs)) + && types_compatible_p (TREE_TYPE (lhs), vr->type)) + { + tree *saved_last_vuse_ptr = last_vuse_ptr; + /* Do not update last_vuse_ptr in vn_reference_lookup_2. */ + last_vuse_ptr = NULL; + tree saved_vuse = vr->vuse; + hashval_t saved_hashcode = vr->hashcode; + void *res = vn_reference_lookup_2 (ref, + gimple_vuse (def_stmt), 0, vr); + /* Need to restore vr->vuse and vr->hashcode. */ + vr->vuse = saved_vuse; + vr->hashcode = saved_hashcode; + last_vuse_ptr = saved_last_vuse_ptr; + if (res && res != (void *)-1) + { + vn_reference_t vnresult = (vn_reference_t) res; + if (vnresult->result + && operand_equal_p (vnresult->result, + gimple_assign_rhs1 (def_stmt), 0)) + return res; + } + } } else if (gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL) && gimple_call_num_args (def_stmt) <= 4)