This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR23094


This fixes an old missed optimization in alias disambiguation during
SCCVN.  We can skip a clobbering stmt if that is a store with exactly
the same value as a preceeding redundancy.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

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.

Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c	(revision 255054)
+++ gcc/tree-ssa-sccvn.c	(working copy)
@@ -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
 	  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)
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c	(working copy)
@@ -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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]