Hi! I've committed this patch of Zdenek to fix PR47899 after bootstrap/regtest on x86_64-linux and i686-linux to trunk, pre-approved in the PR. Zdenek, if you want to adjust the ChangeLog entry I've made up or use different e-mail address, just Change it in SVN. kam.uniff.cz domain you've used in your last two commits doesn't resolve...
2011-03-05 Zdenek Dvorak <o...@ucw.cz> 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. --- gcc/cfgloopmanip.c.jj 2010-11-03 10:48:15.000000000 +0100 +++ gcc/cfgloopmanip.c 2011-03-02 13:16:50.171526946 +0100 @@ -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; } --- gcc/testsuite/gcc.dg/pr47899.c.jj 2011-01-16 05:42:39.626675592 +0100 +++ gcc/testsuite/gcc.dg/pr47899.c 2011-03-02 13:23:02.675527008 +0100 @@ -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; +} Jakub