https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79389
--- Comment #17 from Jeffrey A. Law <law at redhat dot com> ---
Note this was extracted from the main motivator for path splitting, so it's
probably wise to make sure we get this right.
The key is blob of code:
for ()
{
...
if (bufferstep)
outputbuffer = (delta << 4) & 0xf0;
else
*outp++ = (delta & 0x0f) | outputbuffer;
bufferstep = !bufferstep;
}
Path splitting essentially turns that into:
for ()
{
...
if (bufferstep)
{
outputbuffer = (delta << 4) & 0xf0;
bufferstep = !bufferstep;
}
else
{
*outp++ = (delta & 0x0f) | outputbuffer;
bufferstep = !bufferstep;
}
}
DOM should know that bufferstep has the range [0,1] and thus can record a path
sensitive equivalence for bufferstep on both arms resulting in:
for ()
{
...
if (bufferstep)
{
outputbuffer = (delta << 4) & 0xf0;
bufferstep = 0;
}
else
{
*outp++ = (delta & 0x0f) | outputbuffer;
bufferstep = 1;
}
}
And we propagate the assignment to bufferstep away into a PHI node.
As long as we preserve that (simplification of the xor), we're good.
Long term we'd like to thread the if (bufferstep) test since bufferstep is just
a flip-flop and the state for every iteration can be known at compile time.
BUt that's a future TODO. Again, preserve the ability to simplify the
assignment to bufferstep at the bottom of the loop and we're good.