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

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ok, so we record a correct upper bound for a loop but then later thread1 makes
a mess of the loop structures, introducing multiple back-edges by mashing
an outer loop of said loop into it, making the number of iteration upper
bound obviously incorrect.

And it is CFG cleanup which introduces those multiple back-edges, mashing
the two loops!  It does this by treating the outer loop header as "forwarder".

Now we could detect this situation in redirect_edge_and_branch or avoid this
loop smashing (in the end loop init will disambiguate the latches again if
requested, re-creating the outer loop).  I think we at least want such
smashing late (more aggressive cleanup was introduced because otherwise
we create worse initial RTL and assembler).

The issue is how to detect this reliably in redirect_edge_and_branch given
it has to work when LOOPS_NEED_FIXUP is set ... we have to reset niter
info and estimates / upper bound whenever we redirect a latch - of both
the source and destination loop.  With LOOPS_NEED_FIXUP we only can rely
on headers (well, not even that, and all other cfghook loop fixup stuff
has a similar issue).  The other option is to simply wipe niter info whenever
we fixup loops (loop fixup is unfortunately a global thing).

I believe I saw this issue on another PR as well.

Reply via email to