This is an archive of the discontinued LLVM Phabricator instance.

[LoopUnroll] Explicitly specify exit to unroll against (NFCI)
AbandonedPublic

Authored by nikic on May 24 2021, 7:13 AM.

Details

Summary

Loop unrolling is usually performed against an exit for which additional information is known, such as a trip count, trip multiple or runtime-enforced trip multiple. This exit receives special treatment, because it can be folded on some or all iterations.

Currently, this exit is not explicitly provided to the unrolling implementation. Instead it assumes that this must be either the unique exit, or the latch exit. For D102635 (where the latch is non-exiting) this results in missed folding opportunities, because unrolling doesn't know which exit the trip count refers to. For D102982 (where the latch can be exiting) it results in miscompiles, because it assumes the wrong exit.

This patch addresses the problem by explicitly providing the ExitingBlock to unrolling. Currently, this shouldn't have any effect, but would have an effect in conjunction with D102635/D102982.

Diff Detail

Event Timeline

nikic created this revision.May 24 2021, 7:13 AM
nikic requested review of this revision.May 24 2021, 7:13 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 24 2021, 7:13 AM

Not sure if this would work or not, but if the implementation allows, I might suggest computing the symbolic exit count for each loop upfront (before unrolling starts). Once you have that, there's a couple of cases:

  • If Exit EC > UC, branch folds to untaken.
  • If Exit EC == UC, then branch folds to untaken on all but one iteration, and taken on that iteration.
  • If Exit EC < UC, we can clamp the UC.

Doing this as symbolic comparisons in the unroll implementation (as opposed to passing in a flag) seems likely to be more robust.

mkazantsev added inline comments.May 25 2021, 10:11 PM
llvm/lib/Transforms/Utils/LoopUnroll.cpp
352

I don't really understand the implications of this change. We'll process a different exit in case of non-zero peeled count than passed in param. Is this intentional? Could you please explain?

According to the comment, it looks like we can just assert that ExitingBlock == L->getLoopLatch(), but I never understood subtleties of unrolling code.

nikic planned changes to this revision.May 26 2021, 12:35 PM

I'll experiment with a variant that performs folding of all exits using SCEV information inside unrolling, to possibly remove the need for passing in a trip count entirely.

nikic abandoned this revision.Jun 19 2021, 12:34 AM

No longer needed, UnrollLoop() is no longer passed TripCount/TripMultiple for a specific exit.