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

--- Comment #5 from Jeffrey A. Law <law at redhat dot com> ---
So digging a bit deeper.  When we leave threading we've exposed a new natural
loop.  However, there is still an irreducible loop in the CFG.  The CFG and the
cached loop information are conservatively correct at this point.

Later the mergephi pass finds a forwarder block with a PHI node.  It squashes
out that forwarder block.  Obviously when we remove a forwarder block, we
redirect all the incoming edges to the destination of the forwarder block.

In this particular case, redirecting those edges results in the remaining
irreducible loop becoming a natural loop.  We're actually likely still OK at
this point.  But.....

It turns out the target of that forwarder block is itself also a forwarder
block that forwards into one of the natural loops.  So mergephi gladly squashes
out that forwarder block, redirecting all the incoming edges into the loop.

Now we've taken the loop nest exposed by the first mergephi transformation and
turned it into a single loop with multiple latches -- which means the iteration
information we had stored for the loop is no longer valid.

Later loop unrolling uses that invalid iteration information and we get
incorrect code.

We can likely invalidate the cached information, but ISTM that there's a
reasonable chance we're going to be playing whack-a-mole with this stuff.

Reply via email to