It is common to have conditional exits within a loop which are known not to be taken on some iterations, but not necessarily all. This patches extends our reasoning around guaranteed to execute (used when establishing whether it's safe to dereference a location from the preheader) to handle the case where an exit is known not to be taken on the first iteration and the instruction of interest *is* known to be taken on the first iteration.
This case comes up in two major ways:
- If we have a range check which we've been unable to eliminate, we frequently know that it doesn't fail on the first iteration.
- Pass ordering. We may have a check which will be eliminated through some sequence of other passes, but depending on the exact pass sequence we might never actually do so or we might miss other optimizations from passes run before the check is finally eliminated.
The initial version (here) is implemented via InstSimplify. At the moment, it catches a few cases, but misses a lot too. I added test cases for missing cases in InstSimplify which I'll follow up on separately. Longer term, we should probably wire SCEV through to here to get much smarted loop aware simplification of the first iteration predicate.
I think we do have SCEV logic to handle this case, but it maybe much weaker than InstSimplify. What we need is something along these lines but getMin instead of getExact for a given exiting block.
For every ExitBlock that Inst does not dominate, get the exiting block which is its single Predecessor (bail out if more than one). Then we just call this SCEV routine. Right now, since it only returns the "exact" count, we maybe usually returning CouldNotCompute.