Fix tail-merge pass for dead type-unsafe code
authorvries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Nov 2014 10:44:58 +0000 (10:44 +0000)
committervries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Nov 2014 10:44:58 +0000 (10:44 +0000)
2014-11-19  Tom de Vries  <tom@codesourcery.com>

PR tree-optimization/62167
* tree-ssa-tail-merge.c (stmt_local_def): Handle statements with vuse
conservatively.
(gimple_equal_p): Don't use vn_valueize to compare for lhs equality of
assigns.

* gcc.dg/pr51879-12.c: Add xfails.
* gcc.dg/pr62167-run.c: New test.
* gcc.dg/pr62167.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217761 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr51879-12.c
gcc/testsuite/gcc.dg/pr62167-run.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr62167.c [new file with mode: 0644]
gcc/tree-ssa-tail-merge.c

index ff9fe1e..9169e35 100644 (file)
@@ -1,3 +1,11 @@
+2014-11-19  Tom de Vries  <tom@codesourcery.com>
+
+       PR tree-optimization/62167
+       * tree-ssa-tail-merge.c (stmt_local_def): Handle statements with vuse
+       conservatively.
+       (gimple_equal_p): Don't use vn_valueize to compare for lhs equality of
+       assigns.
+
 2014-11-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/63915
index 08a6c23..35cb09c 100644 (file)
@@ -1,3 +1,10 @@
+2014-11-19  Tom de Vries  <tom@codesourcery.com>
+
+       PR tree-optimization/62167
+       * gcc.dg/pr51879-12.c: Add xfails.
+       * gcc.dg/pr62167-run.c: New test.
+       * gcc.dg/pr62167.c: New test.
+
 2014-11-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/63915
index 8126505..85e2687 100644 (file)
@@ -24,6 +24,6 @@ foo (int y)
   baz (a);
 }
 
-/* { dg-final { scan-tree-dump-times "bar \\(" 1 "pre"} } */
-/* { dg-final { scan-tree-dump-times "bar2 \\(" 1 "pre"} } */
+/* { dg-final { scan-tree-dump-times "bar \\(" 1 "pre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "bar2 \\(" 1 "pre" { xfail *-*-* } } } */
 /* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/pr62167-run.c b/gcc/testsuite/gcc.dg/pr62167-run.c
new file mode 100644 (file)
index 0000000..37214a3
--- /dev/null
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ftree-tail-merge" } */
+
+struct node
+{
+  struct node *next;
+  struct node *prev;
+};
+
+struct node node;
+
+struct head
+{
+  struct node *first;
+};
+
+struct head heads[5];
+
+int k = 2;
+
+struct head *head = &heads[2];
+
+int
+main ()
+{
+  struct node *p;
+
+  node.next = (void*)0;
+
+  node.prev = (void *)head;
+
+  head->first = &node;
+
+  struct node *n = head->first;
+
+  struct head *h = &heads[k];
+
+  heads[2].first = n->next;
+
+  if ((void*)n->prev == (void *)h)
+    p = h->first;
+  else
+    /* Dead tbaa-unsafe load from ((struct node *)&heads[2])->next.  */
+    p = n->prev->next;
+
+  return !(p == (void*)0);
+}
diff --git a/gcc/testsuite/gcc.dg/pr62167.c b/gcc/testsuite/gcc.dg/pr62167.c
new file mode 100644 (file)
index 0000000..f8c31a0
--- /dev/null
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-tail-merge -fdump-tree-pre" } */
+
+struct node
+{
+  struct node *next;
+  struct node *prev;
+};
+
+struct node node;
+
+struct head
+{
+  struct node *first;
+};
+
+struct head heads[5];
+
+int k = 2;
+
+struct head *head = &heads[2];
+
+int
+main ()
+{
+  struct node *p;
+
+  node.next = (void*)0;
+
+  node.prev = (void *)head;
+
+  head->first = &node;
+
+  struct node *n = head->first;
+
+  struct head *h = &heads[k];
+
+  heads[2].first = n->next;
+
+  if ((void*)n->prev == (void *)h)
+    p = h->first;
+  else
+    /* Dead tbaa-unsafe load from ((struct node *)&heads[2])->next.  */
+    p = n->prev->next;
+
+  return !(p == (void*)0);
+}
+
+/* { dg-final { scan-tree-dump-not "Removing basic block" "pre"} } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
index 303bd5e..1651985 100644 (file)
@@ -326,7 +326,8 @@ stmt_local_def (gimple stmt)
 
   if (gimple_vdef (stmt) != NULL_TREE
       || gimple_has_side_effects (stmt)
-      || gimple_could_trap_p_1 (stmt, false, false))
+      || gimple_could_trap_p_1 (stmt, false, false)
+      || gimple_vuse (stmt) != NULL_TREE)
     return false;
 
   def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF);
@@ -1175,7 +1176,8 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
                                                 gimple_assign_rhs1 (s2)));
       else if (TREE_CODE (lhs1) == SSA_NAME
               && TREE_CODE (lhs2) == SSA_NAME)
-       return vn_valueize (lhs1) == vn_valueize (lhs2);
+       return operand_equal_p (gimple_assign_rhs1 (s1),
+                               gimple_assign_rhs1 (s2), 0);
       return false;
 
     case GIMPLE_COND: