This is an archive of the discontinued LLVM Phabricator instance.

[LoopPeel] Check for non-LCSSA form loops
Needs RevisionPublic

Authored by anna on Jan 28 2022, 7:36 AM.

Details

Summary

Currently, the way loop peeling is done, it requires LCSSA form.
We need to add this as a check in canPeel (similar to the requirement
for LoopSimplifyForm in canPeel). Without the check if we peel
non-LCSSA loops, we end up breaking SSA form on uses outside the loop.
This cannot be seen upstream because all uses of loop peeling is done on
LCSSA form loops.

Added a unit test for this.

Diff Detail

Event Timeline

anna created this revision.Jan 28 2022, 7:36 AM
anna requested review of this revision.Jan 28 2022, 7:36 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 28 2022, 7:36 AM
mkazantsev requested changes to this revision.EditedJan 31 2022, 1:15 AM

This patch does not account for the fact that DT and LI can both be nullptr. I think it may be reasonable to lift this restriction, but so far the pass supports this case. If you can't go w/o DT and LI, then we first need to rework the pass in a way that it always expects DT and LI to be provided.

llvm/lib/Transforms/Scalar/LoopFuse.cpp
195

Loop peeling pass is not guaranteed to be provided with DT and LI. They can both be (and sometimes are) nullptr, at least in old PM.

llvm/lib/Transforms/Utils/LoopPeel.cpp
748

This should also work for DT == nullptr, see checks below (line 764).

This revision now requires changes to proceed.Jan 31 2022, 1:15 AM

Basic idea looks reasonable, though we appear to have bit of cleanup to do before this can reasonably land.

llvm/lib/Transforms/Scalar/LoopFuse.cpp
195

Max, your comment may be correct for LoopPeeling (haven't checked yet), but the LoopFuze code does appear to require DT and LI today. As such, they can't be null along this particular codepath.

llvm/lib/Transforms/Utils/LoopPeel.cpp
748

Chasing through the code, I think the handling for nullptr DT is simply dead. It definitely used to be supported, but it looks like the callers (both fuse and unroll) now require DT.

I also see some code which looks like it would crash if a null DT was actually passed in.

Anna, could you do a cleanup which folded the DT null checks and asserted it was never null? I think we need that before we can land this one.

llvm/unittests/Transforms/Utils/LoopPeelTest.cpp
1

Any reason this can't be a lit test? Strongly preferred.

anna added inline comments.Jan 31 2022, 2:05 PM
llvm/lib/Transforms/Utils/LoopPeel.cpp
748

Yes, I'll do the cleanup. Note that the only use case of concern maybe downstream users with peeling without DT? But we definitely need DT to make this change.

llvm/unittests/Transforms/Utils/LoopPeelTest.cpp
1

Currently, Loop peeling is not a pass in itself and the passes which use it in upstream requires LCSSA form or constructs it (LoopUnroll).

Now, that I mention it, I don't see LCSSA being a requirement in loop Fusion. So, maybe I can construct a testcase with fusion.

mkazantsev added inline comments.Jan 31 2022, 9:30 PM
llvm/lib/Transforms/Scalar/LoopFuse.cpp
195

Then the first step would be to replace DominatorTree * with DominatorTree & to be adamant. Now this fact is at least not obvious.

llvm/lib/Transforms/Utils/LoopPeel.cpp
748

I vaguely remember that we've seen some real cases of null DT while working on some peeling patch. Maybe it only happens in unit tests, though. I don't mind if we rework this code so that DT is always non-null, but let's clearly state it (and replace pointer with reference).

mkazantsev added inline comments.Jan 31 2022, 9:31 PM
llvm/unittests/Transforms/Utils/LoopPeelTest.cpp
1

I think LoopUnroll can be forced to only do peeling by setting relevant options.

reames added inline comments.Feb 1 2022, 9:41 AM
llvm/lib/Transforms/Scalar/LoopFuse.cpp
195

The first step is to add asserts, run tests, and check them in if nothing fails. The *second* step is to convert the assert into a refactoring change to use references where possible.

llvm/lib/Transforms/Utils/LoopPeel.cpp
748

I vaguely remember this too. That's why I want asserts to find our counter example if one exists. :)

anna added inline comments.Feb 1 2022, 1:17 PM
llvm/lib/Transforms/Utils/LoopPeel.cpp
748

DT is definitely non-null and we have an (unintentional) assert for this at line 915 already :). This makes the code cleanup here simpler.

fhahn added inline comments.Feb 2 2022, 1:18 AM
llvm/lib/Transforms/Utils/LoopPeel.cpp
748

Thanks for pushing on this cleanup!