The following reverts the proper part of the loop depth dependent
copy-propagation restriction patch.  The canonicalization that
record_equality does is important for correctness when threading
over backedges (that must be accidential?  I can't see how it
might not be possible to trigger this without the change).

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
Release-checking bootstrap on x86_64-unknown-linux-gnu in progress,
bootstrap on i586-linux-gnu in progress.

Richard.

2014-07-14  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/61757
        PR tree-optimization/61783
        * tree-ssa-dom.c (record_equality): Revert canonicalization
        change and add comment.
        (propagate_rhs_into_lhs): Revert previous fix, removing
        loop depth restriction again.

        * gcc.dg/torture/pr61757.c: New testcase.

Index: gcc/testsuite/gcc.dg/torture/pr61757.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr61757.c      (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr61757.c      (working copy)
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+struct X { void *p; int res; } a[32];
+
+int foo (unsigned i, unsigned n, void *q)
+{
+  if (i + 1 < n && q == a[i + 1].p)
+    {
+      do {
+         ++i;
+      } while (i < n && q == a[i].p);
+      --i;
+      return a[i].res;
+    }
+  else
+    return a[i].res;
+}
+
+int main ()
+{
+  int x;
+  a[0].p = &x;
+  a[0].res = -1;
+  a[1].p = &x;
+  a[1].res = 1;
+  a[2].p = (void *)0;
+  a[2].res = 0;
+  if (foo (0, 3, &x) != 1)
+    abort ();
+  return 0;
+}
Index: gcc/tree-ssa-dom.c
===================================================================
--- gcc/tree-ssa-dom.c  (revision 212510)
+++ gcc/tree-ssa-dom.c  (working copy)
@@ -1589,6 +1589,33 @@ record_const_or_copy (tree x, tree y)
   record_const_or_copy_1 (x, y, prev_x);
 }
 
+/* Return the loop depth of the basic block of the defining statement of X.
+   This number should not be treated as absolutely correct because the loop
+   information may not be completely up-to-date when dom runs.  However, it
+   will be relatively correct, and as more passes are taught to keep loop info
+   up to date, the result will become more and more accurate.  */
+
+static int
+loop_depth_of_name (tree x)
+{
+  gimple defstmt;
+  basic_block defbb;
+
+  /* If it's not an SSA_NAME, we have no clue where the definition is.  */
+  if (TREE_CODE (x) != SSA_NAME)
+    return 0;
+
+  /* Otherwise return the loop depth of the defining statement's bb.
+     Note that there may not actually be a bb for this statement, if the
+     ssa_name is live on entry.  */
+  defstmt = SSA_NAME_DEF_STMT (x);
+  defbb = gimple_bb (defstmt);
+  if (!defbb)
+    return 0;
+
+  return bb_loop_depth (defbb);
+}
+
 /* Similarly, but assume that X and Y are the two operands of an EQ_EXPR.
    This constrains the cases in which we may treat this as assignment.  */
 
@@ -1608,7 +1635,10 @@ record_equality (tree x, tree y)
      long as we canonicalize on one value.  */
   if (is_gimple_min_invariant (y))
     ;
-  else if (is_gimple_min_invariant (x))
+  else if (is_gimple_min_invariant (x)
+          /* ???  When threading over backedges the following is important
+             for correctness.  See PR61757.  */
+          || (loop_depth_of_name (x) <= loop_depth_of_name (y)))
     prev_x = x, x = y, y = prev_x, prev_x = prev_y;
   else if (prev_x && is_gimple_min_invariant (prev_x))
     x = y, y = prev_x, prev_x = prev_y;
@@ -2638,33 +2668,6 @@ get_lhs_or_phi_result (gimple stmt)
     gcc_unreachable ();
 }
 
-/* Return the loop depth of the basic block of the defining statement of X.
-   This number should not be treated as absolutely correct because the loop
-   information may not be completely up-to-date when dom runs.  However, it
-   will be relatively correct, and as more passes are taught to keep loop info
-   up to date, the result will become more and more accurate.  */
-
-static int
-loop_depth_of_name (tree x)
-{
-  gimple defstmt;
-  basic_block defbb;
-
-  /* If it's not an SSA_NAME, we have no clue where the definition is.  */
-  if (TREE_CODE (x) != SSA_NAME)
-    return 0;
-
-  /* Otherwise return the loop depth of the defining statement's bb.
-     Note that there may not actually be a bb for this statement, if the
-     ssa_name is live on entry.  */
-  defstmt = SSA_NAME_DEF_STMT (x);
-  defbb = gimple_bb (defstmt);
-  if (!defbb)
-    return 0;
-
-  return bb_loop_depth (defbb);
-}
-
 /* Propagate RHS into all uses of LHS (when possible).
 
    RHS and LHS are derived from STMT, which is passed in solely so
@@ -2680,8 +2683,7 @@ static void
 propagate_rhs_into_lhs (gimple stmt, tree lhs, tree rhs, bitmap 
interesting_names)
 {
   /* First verify that propagation is valid.  */
-  if (may_propagate_copy (lhs, rhs)
-      && loop_depth_of_name (lhs) >= loop_depth_of_name (rhs))
+  if (may_propagate_copy (lhs, rhs))
     {
       use_operand_p use_p;
       imm_use_iterator iter;

Reply via email to