re PR rtl-optimization/47899 (ICE in get_loop_body, at cfgloop.c:831)
authorZdenek Dvorak <ook@ucw.cz>
Sat, 5 Mar 2011 14:28:14 +0000 (15:28 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 5 Mar 2011 14:28:14 +0000 (15:28 +0100)
PR rtl-optimization/47899
* cfgloopmanip.c (fix_bb_placements): Fix first argument
to flow_loop_nested_p when moving the loop upward.

* gcc.dg/pr47899.c: New test.

From-SVN: r170699

gcc/ChangeLog
gcc/cfgloopmanip.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr47899.c [new file with mode: 0644]

index 7a723c8f8bf784fcaf781c0736a19cd64d518063..9fd15c423ba9ad4d0f3226edb48c14f1893bf59c 100644 (file)
@@ -1,3 +1,9 @@
+2011-03-05  Zdenek Dvorak  <ook@ucw.cz>
+
+       PR rtl-optimization/47899
+       * cfgloopmanip.c (fix_bb_placements): Fix first argument
+       to flow_loop_nested_p when moving the loop upward.
+
 2011-03-05  Richard Earnshaw  <rearnsha@arm.com>
 
        PR target/47719
index aa9ab66454e2f5e5e2737ec0f59b7eaf72bc9557..3802f9cff12d5439126d46e9f7d211b811e6e4ed 100644 (file)
@@ -1,5 +1,5 @@
 /* Loop manipulation code for GNU compiler.
-   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -174,7 +174,7 @@ fix_bb_placements (basic_block from,
 {
   sbitmap in_queue;
   basic_block *queue, *qtop, *qbeg, *qend;
-  struct loop *base_loop;
+  struct loop *base_loop, *target_loop;
   edge e;
 
   /* We pass through blocks back-reachable from FROM, testing whether some
@@ -214,12 +214,14 @@ fix_bb_placements (basic_block from,
          /* Subloop header, maybe move the loop upward.  */
          if (!fix_loop_placement (from->loop_father))
            continue;
+         target_loop = loop_outer (from->loop_father);
        }
       else
        {
          /* Ordinary basic block.  */
          if (!fix_bb_placement (from))
            continue;
+         target_loop = from->loop_father;
        }
 
       FOR_EACH_EDGE (e, ei, from->succs)
@@ -248,9 +250,12 @@ fix_bb_placements (basic_block from,
              && (nca == base_loop
                  || nca != pred->loop_father))
            pred = pred->loop_father->header;
-         else if (!flow_loop_nested_p (from->loop_father, pred->loop_father))
+         else if (!flow_loop_nested_p (target_loop, pred->loop_father))
            {
-             /* No point in processing it.  */
+             /* If PRED is already higher in the loop hierarchy than the
+                TARGET_LOOP to that we moved FROM, the change of the position
+                of FROM does not affect the position of PRED, so there is no
+                point in processing it.  */
              continue;
            }
 
index 8b09c9915ff3b23e895ef13da1a1e03b2e0590a7..6edf8e279156a61ab8e3f2c3fa37330e743ffca5 100644 (file)
@@ -1,5 +1,8 @@
 2011-03-05  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/47899
+       * gcc.dg/pr47899.c: New test.
+
        * gcc.dg/torture/pr47968.c: Ignore warnings.
 
        PR tree-optimization/47967
diff --git a/gcc/testsuite/gcc.dg/pr47899.c b/gcc/testsuite/gcc.dg/pr47899.c
new file mode 100644 (file)
index 0000000..c83bb85
--- /dev/null
@@ -0,0 +1,26 @@
+/* PR rtl-optimization/47899 */
+/* { dg-do compile } */
+/* { dg-options "-O -funroll-loops" } */
+
+extern unsigned int a, b, c;
+extern int d;
+
+static int
+foo (void)
+{
+lab:
+  if (b)
+    for (d = 0; d >= 0; d--)
+      if (a || c)
+       for (; c; c++)
+         ;
+      else
+       goto lab;
+}
+
+int
+main ()
+{
+  foo ();
+  return 0;
+}