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.

Reply via email to