summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-19 10:44:58 +0000
committervries <vries@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-19 10:44:58 +0000
commitcac6d71bd751aa072e989241cab8f7f917cd2dc3 (patch)
tree37b8a91d895a605dcdce91289d14dca2c4b9d0b0
parent82e62318caf5927f83bdaaa3205c9f27641a26ea (diff)
downloadgcc-cac6d71bd751aa072e989241cab8f7f917cd2dc3.tar.gz
Fix tail-merge pass for dead type-unsafe code
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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/pr51879-12.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr62167-run.c47
-rw-r--r--gcc/testsuite/gcc.dg/pr62167.c50
-rw-r--r--gcc/tree-ssa-tail-merge.c6
6 files changed, 118 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ff9fe1e8b57..9169e354e8e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 08a6c234acc..35cb09ce4d3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.dg/pr51879-12.c b/gcc/testsuite/gcc.dg/pr51879-12.c
index 8126505f384..85e2687da17 100644
--- a/gcc/testsuite/gcc.dg/pr51879-12.c
+++ b/gcc/testsuite/gcc.dg/pr51879-12.c
@@ -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
index 00000000000..37214a3ecee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr62167-run.c
@@ -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
index 00000000000..f8c31a0792f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr62167.c
@@ -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" } } */
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index 303bd5e4c4a..16519853b0e 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -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: