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.