If we know that some check will not be executed on the last iteration, we can use this
fact to eliminate its check.
Marking as Needs Changes purely to indicate I'm holding off on reviewing this in depth until changes this is built upon have all landed. Please refresh at that point.
Max, have you looked at SCEV->isLoopInvariantPredicate? It tries to handle some of the same reasoning. It might be useable directly here, or if not, can the logic maybe be consolidated in one place rather than two? I have not looked at this in depth yet, but that'll be the question I'm asking myself when reviewing this in detail.
I think we better avoid adding SkipLastIter parameter since we should be able to cover all cases with existing MaxIter and it just unnecessarily complicates the API.
Let's move this to the caller.
I suggest to adjust MaxIter here. It should greatly simplify the logic in this loop.
Please rework the comment so it is crystal clear that we actually call OptimizeCond for both MaxIter and MaxIter -1. And the reason is implementation limitation in SCEV which is unable to prove that MaxIter-1 < MaxIter.
NIT1: please list all captured values explicitly. Maybe capture SkipLastIter by value?
This lambda may be called twice with SkipLastIter equal to true for each exit. As a result MaxIter may be decremented by 2 for particular exit.