]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
2015-11-23 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 23 Nov 2015 15:21:32 +0000 (15:21 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 23 Nov 2015 15:21:32 +0000 (15:21 +0000)
PR tree-optimization/68465
* tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children):
Also record equalities from multiple predecessor blocks if
only one non-backedge exists.

* gcc.dg/tree-ssa/ssa-fre-52.c: New testcase.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-52.c [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index 1fcb0f530bf121ec773ed3c45a20638bdab686a0..61cbac92610e9ed2319369bfb06a9bc95a17fbf8 100644 (file)
@@ -1,3 +1,10 @@
+2015-11-23  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/68465
+       * tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children):
+       Also record equalities from multiple predecessor blocks if
+       only one non-backedge exists.
+
 2015-11-23  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        PR target/68363
index e14bebf5acf92765a59a002f90b62509b0d6dc6b..dd7f96a8faaccb1abfaba0c8261bd0868ddf00af 100644 (file)
@@ -1,3 +1,8 @@
+2015-11-23  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/68465
+       * gcc.dg/tree-ssa/ssa-fre-52.c: New testcase.
+
 2015-11-23  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        PR target/68363
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-52.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-52.c
new file mode 100644 (file)
index 0000000..8b607d5
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1" } */
+
+void bar ();
+void foo (int n)
+{
+  if (n > 0)
+    {
+      int j = 0;
+      do
+       {
+         if (n > 0)
+           {
+             int i = 0;
+             do
+               {
+                 bar ();
+               }
+             while (i < n);
+           }
+       }
+      while (j < n);
+    }
+}
+
+/* { dg-final { scan-tree-dump-times "if" 1 "fre1" } } */
index 2ac382842d3610a6686413c050e26331690eabca..9a55b5b51613c70e062d947dc5a5464df8dcc54a 100644 (file)
@@ -4357,20 +4357,34 @@ sccvn_dom_walker::before_dom_children (basic_block bb)
 
   /* If we have a single predecessor record the equivalence from a
      possible condition on the predecessor edge.  */
-  if (single_pred_p (bb))
+  edge pred_e = NULL;
+  FOR_EACH_EDGE (e, ei, bb->preds)
+    {
+      /* Ignore simple backedges from this to allow recording conditions
+         in loop headers.  */
+      if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
+       continue;
+      if (! pred_e)
+       pred_e = e;
+      else
+       {
+         pred_e = NULL;
+         break;
+       }
+    }
+  if (pred_e)
     {
-      edge e = single_pred_edge (bb);
       /* Check if there are multiple executable successor edges in
         the source block.  Otherwise there is no additional info
         to be recorded.  */
       edge e2;
-      FOR_EACH_EDGE (e2, ei, e->src->succs)
-       if (e2 != e
+      FOR_EACH_EDGE (e2, ei, pred_e->src->succs)
+       if (e2 != pred_e
            && e2->flags & EDGE_EXECUTABLE)
          break;
       if (e2 && (e2->flags & EDGE_EXECUTABLE))
        {
-         gimple *stmt = last_stmt (e->src);
+         gimple *stmt = last_stmt (pred_e->src);
          if (stmt
              && gimple_code (stmt) == GIMPLE_COND)
            {
@@ -4378,11 +4392,11 @@ sccvn_dom_walker::before_dom_children (basic_block bb)
              tree lhs = gimple_cond_lhs (stmt);
              tree rhs = gimple_cond_rhs (stmt);
              record_conds (bb, code, lhs, rhs,
-                           (e->flags & EDGE_TRUE_VALUE) != 0);
+                           (pred_e->flags & EDGE_TRUE_VALUE) != 0);
              code = invert_tree_comparison (code, HONOR_NANS (lhs));
              if (code != ERROR_MARK)
                record_conds (bb, code, lhs, rhs,
-                             (e->flags & EDGE_TRUE_VALUE) == 0);
+                             (pred_e->flags & EDGE_TRUE_VALUE) == 0);
            }
        }
     }