[PATCH] D75746: [LoopVectorizer] Simplify branch in the remainder loop for trivial cases

Ayal Zaks via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 14 07:29:11 PDT 2020


Ayal added a comment.

Eliminating a redundant back-edge is clearly good. It would be better if such a special-case cleanup could be handled by some subsequent optimization, and possibly generalized. Note however that the remainder loop may or may not be considered subject for further optimization: LV currently disables unrolling the remainder loop following r231631, OTOH it may be worth vectorizing according to D30247 <https://reviews.llvm.org/D30247>. If desired, optimizations other than vectorization should preferably be taken care of by subsequent passes such as indvars and loop-unroll. LV knows that the trip count of the remainder loop is at most VF*UF, in the absence of overflows and runtime guards, and can make an effort to convey this bound, if GVN and IPSCCP fail to pick it up (referring to PR44547). Unfortunately, introducing an `llvm.assume()` seems insufficient - perhaps it could be made to work?

LV originally tries to keep the control of the remainder loop intact, adjusting only the starting values of its phi's, including that of its iv. If this control is going to be modified, by hacking its latch branch, another alternative is to replace it altogether with a new canonical `{0, +1, %TripCount}` iv (as done for the vector loop), possibly following a `%TripCount = urem %ComputedTripCount, VF*UF` which conveys this upper bound clearly. Somewhat akin to how `truncateToMinimalBitwidths()` conveys minimal bitwidths.



================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:3107
+  // If VFxUF is 2 and vector loop is not skipped then remainder executes once.
+  if (VF * UF == 2 && !areSafetyChecksAdded()) {
+    if (BasicBlock *Latch = OrigLoop->getLoopLatch())
----------------
danilaml wrote:
> I think this check is enough unless there are other cases in which "remainder loop has `N % (VF*UF)` iterations doesn't hold.
Note that the trip count of the remainder loop may be **equal** to VF*UF, when loop `requiresScalarEpilogue()`; so in the above special case of VF*UF==2 remainder loop may iterate once **or twice**.

Note that `emitMinimumIterationCountCheck()` also takes care of the case where adding 1 to the backedge-taken count overflows, leading to an incorrect trip count of zero; here too "remainder" loop iterates (much) more than once.


================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:3109
+    if (BasicBlock *Latch = OrigLoop->getLoopLatch())
+      if (BranchInst *BI = dyn_cast_or_null<BranchInst>(Latch->getTerminator()))
+        BI->setCondition(Builder.getInt1(BI->getSuccessor(0) == LoopExitBlock));
----------------
`BI` is aka `ScalarLatchBr`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75746/new/

https://reviews.llvm.org/D75746





More information about the llvm-commits mailing list