The following patch fixes PR64357 (or papers over some latent issue).
We were not protecting a certain aspect of simple latches properly
(a simple latch should belong to its loop).

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2015-01-12  Richard Biener  <rguent...@suse.de>

        PR middle-end/64357
        * tree-cfg.c (gimple_can_merge_blocks_p): Protect simple
        latches properly.

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

Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c      (revision 219446)
+++ gcc/tree-cfg.c      (working copy)
@@ -1723,11 +1727,13 @@ gimple_can_merge_blocks_p (basic_block a
     }
 
   /* Protect simple loop latches.  We only want to avoid merging
-     the latch with the loop header in this case.  */
+     the latch with the loop header or with a block in another
+     loop in this case.  */
   if (current_loops
       && b->loop_father->latch == b
       && loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES)
-      && b->loop_father->header == a)
+      && (b->loop_father->header == a
+         || b->loop_father != a->loop_father))
     return false;
 
   /* It must be possible to eliminate all phi nodes in B.  If ssa form
Index: gcc/testsuite/gcc.dg/torture/pr64357.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr64357.c      (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr64357.c      (working copy)
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+
+int a, b, c, d, e, f;
+
+long long
+fn1 (int p)
+{
+  return p ? p : 1;
+}
+
+static int
+fn2 ()
+{
+lbl:
+  for (; f;)
+    return 0;
+  for (;;)
+    {
+      for (b = 0; b; ++b)
+       if (d)
+         goto lbl;
+      c = e;
+    }
+}
+
+void
+fn3 ()
+{
+  for (; a; a = fn1 (a))
+    {
+      fn2 ();
+      e = 0;
+    }
+}

Reply via email to