https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124810

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue is that as we process two loop children that are siblings, all edges
to the latch of the loop vanish, and we hit

bool 
remove_path (edge e, bool *irred_invalidated,
             bitmap loop_closed_ssa_invalidated)
{   
...
  /* It may happen that by removing path we remove one or more loops
     we belong to.  In this case first unloop the loops, then proceed
     normally.   We may assume that e->dest is not a header of any loop,
     as it now has exactly one predecessor.  */
  for (l = e->src->loop_father; loop_outer (l); l = f)
    {
      f = loop_outer (l);
      if (dominated_by_p (CDI_DOMINATORS, l->latch, e->dest))
        unloop (l, irred_invalidated, loop_closed_ssa_invalidated);
    }

but!  The loop body of the outer loop is already wrecked upon removal
of the edge from the first loop to the latch of the outer loop.  So
the two inner loops that are processed by unloop_loops have one
exit each to the outer loop latch (and another exit to outside of the
outer loop).  Once the last exit from an inner loop to an outer loop
is elided we have to re-parent that loops BBs which we fail to do.

I think we try(?) with

  /* Fix placements of basic blocks inside loops and the placement of
     loops in the loop tree.  */
  fix_bb_placements (from, irred_invalidated, loop_closed_ssa_invalidated);
  fix_loop_placements (from->loop_father, irred_invalidated,
                       loop_closed_ssa_invalidated);

but somehow this does not work.

Reply via email to