This fixes PR61964, we have to rely on structural equality when determining equivalency of non-register LHS.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2014-07-31 Richard Biener <rguent...@suse.de> PR tree-optimization/61964 * tree-ssa-tail-merge.c (gimple_equal_p): Handle non-SSA LHS solely by structural equality. * gcc.dg/torture/pr61964.c: New testcase. Index: gcc/tree-ssa-tail-merge.c =================================================================== --- gcc/tree-ssa-tail-merge.c (revision 213317) +++ gcc/tree-ssa-tail-merge.c (working copy) @@ -1161,17 +1168,9 @@ gimple_equal_p (same_succ same_succ, gim lhs2 = gimple_get_lhs (s2); if (TREE_CODE (lhs1) != SSA_NAME && TREE_CODE (lhs2) != SSA_NAME) - { - /* If the vdef is the same, it's the same statement. */ - if (vn_valueize (gimple_vdef (s1)) - == vn_valueize (gimple_vdef (s2))) - return true; - - /* Test for structural equality. */ - return (operand_equal_p (lhs1, lhs2, 0) - && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1), - gimple_assign_rhs1 (s2))); - } + return (operand_equal_p (lhs1, lhs2, 0) + && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1), + gimple_assign_rhs1 (s2))); else if (TREE_CODE (lhs1) == SSA_NAME && TREE_CODE (lhs2) == SSA_NAME) return vn_valueize (lhs1) == vn_valueize (lhs2); Index: gcc/testsuite/gcc.dg/torture/pr61964.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr61964.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr61964.c (working copy) @@ -0,0 +1,33 @@ +/* { dg-do run } */ + +extern void abort (void); + +struct node { struct node *next, *prev; } node; +struct head { struct node *first; } heads[5]; +int k = 2; +struct head *head = &heads[2]; + +static int __attribute__((noinline)) +foo() +{ + node.prev = (void *)head; + head->first = &node; + + struct node *n = head->first; + struct head *h = &heads[k]; + + if (n->prev == (void *)h) + h->first = n->next; + else + n->prev->next = n->next; + + n->next = h->first; + return n->next == &node; +} + +int main() +{ + if (foo ()) + abort (); + return 0; +}