http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58326
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ok, so for one, fix_bb_placements for the case of moved subloop (headers):
if (from->loop_father->header == from)
{
/* Subloop header, maybe move the loop upward. */
if (!fix_loop_placement (from->loop_father, irred_invalidated))
continue;
target_loop = loop_outer (from->loop_father);
}
doesn't include the header (or any of its body BBs in this case) in the
set of loop_closed_ssa_invalidated blocks. At least the header can
use a name defined in the previous outer loop (and I fail to see why
a random loop body block couldn't).
But then, rewrite-into-LC-ssa does
static void
find_uses_to_rename_bb (basic_block bb, bitmap *use_blocks, bitmap need_phis)
{
gimple_stmt_iterator bsi;
edge e;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, bb->succs)
for (bsi = gsi_start_phis (e->dest); !gsi_end_p (bsi); gsi_next (&bsi))
{
gimple phi = gsi_stmt (bsi);
if (! virtual_operand_p (gimple_phi_result (phi)))
find_uses_to_rename_use (bb, PHI_ARG_DEF_FROM_EDGE (phi, e),
use_blocks, need_phis);
}
so for uses in PHIs it considers all destinations of edges out of
"changed" blocks (but not uses in PHIs of the block itself). For
some weird reason. Well - in this case one predecessor is in the
set of changed blocks and one (the one from the backedge) isn't.
Fixing fix_bb_placements to include all blocks of moved sub-loops
in loop_closed_ssa_invalidated fixes the testcases, but still the
above looks odd.