aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2017-11-23 09:05:11 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2017-11-23 09:05:11 +0000
commitd7a160a45ea7ed09247788c708721c2813cf0007 (patch)
treed8b5404eccbb222d1e6e5d2a067adec60e607835 /gcc
parentbb9ec14d414a51c3461510f3cddfcafe11b35ee1 (diff)
downloadgcc-d7a160a45ea7ed09247788c708721c2813cf0007.zip
gcc-d7a160a45ea7ed09247788c708721c2813cf0007.tar.gz
gcc-d7a160a45ea7ed09247788c708721c2813cf0007.tar.bz2
re PR tree-optimization/23094 (store ccp, or store copy prop misses an optimization)
2017-11-23 Richard Biener <rguenther@suse.de> 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c43
-rw-r--r--gcc/tree-ssa-sccvn.c40
4 files changed, 94 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7cabfd6..837fa39 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2017-11-23 Richard Biener <rguenther@suse.de>
+ 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 <rguenther@suse.de>
+
PR tree-optimization/81403
* tree-ssa-pre.c (get_representative_for): Add parameter specifying
a block we need a leader relative to.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3dd20d1..ff35bca 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2017-11-23 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/23094
+ * gcc.dg/tree-ssa/ssa-fre-61.c: New testcase.
+
+2017-11-23 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/83089
* gcc.dg/pr83089.c: Require pthread.
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 0000000..a4d9a71
--- /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 f5bc28e..d0ff301 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)