Original patch trying to address this was sent in D47624, but that didn't quite
handle things correctly. There are two key principles used to select whether
and how to invalidate SCEV-cached information about loops:
- We must invalidate any info SCEV has cached before unswitching as we may change (or destroy) the loop structure by the act of unswitching, and make it hard to recover everything we want to invalidate within SCEV.
- We need to invalidate all of the loops whose CFGs are mutated by the unswitching. Notably, this isn't the *entire* loop nest, this is every loop contained by the outermost loop reached by an exit block relevant to the unswitch.
And we need to do this even when doing trivial unswitching.
I've added more focused tests that directly check that SCEV starts off with
imprecise information and after unswitching (and simplifying instructions)
re-querying SCEV will produce precise information. These tests also
specifically work to check that an *outer* loop's information becomes precise.
However, the testing here is still a bit imperfect. Crafting test cases that
reliably fail to be analyzed by SCEV before unswitching and succeed afterward
proved ... very, very hard. It took me several hours and careful work to build
these, and I'm not optimistic about necessarily coming up with more to cover
more elaborate possibilities. Fortunately, the code pattern we are testing here
in the pass is really straightforward and reliable.
Thanks to Max Kazantsev for the initial work on this and to Hal Finkel for
helping me talk through approaches to test this stuff even if it didn't come to
much.
Why it is enough? Imagine that you have
Let L be Loop 3 and all exits from L lead to Loop 2. Then, if I understand the code correctly, OuterL will be found as Loop 2 and we invalidate it (and its internals). But what if what we are going to do with Loop 3 also affects trip count in Loop 1?