re PR tree-optimization/23094 (store ccp, or store copy prop misses an optimization)
authorRichard Biener <rguenther@suse.de>
Thu, 23 Nov 2017 09:05:11 +0000 (09:05 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 23 Nov 2017 09:05:11 +0000 (09:05 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index 7cabfd66b936b002f07bcf0763e3e81d1ca64e2d..837fa3942184d99dc500e90ae7aa9ea6692810a1 100644 (file)
@@ -1,3 +1,10 @@
+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
index 3dd20d14b68f9884e50bbd4da5371843abf00057..ff35bcaf32f77224746e6e134f24267a36c5bcc2 100644 (file)
@@ -1,3 +1,8 @@
+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
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 (file)
index 0000000..a4d9a71
--- /dev/null
@@ -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" } } */
index f5bc28efa7096bc2843faf7f544f7ad0897ef140..d0ff30199e617b6967776dd4780b2a9851531001 100644 (file)
@@ -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)