[llvm] [LoopPeel] Implement initial peeling off the last loop iteration. (PR #139551)
Eli Friedman via llvm-commits
llvm-commits at lists.llvm.org
Wed May 21 16:04:50 PDT 2025
================
@@ -325,19 +326,71 @@ static unsigned peelToTurnInvariantLoadsDerefencebale(Loop &L,
return 0;
}
-// Return the number of iterations to peel off that make conditions in the
-// body true/false. For example, if we peel 2 iterations off the loop below,
-// the condition i < 2 can be evaluated at compile time.
+bool llvm::canPeelLastIteration(const Loop &L, ScalarEvolution &SE) {
+ const SCEV *BTC = SE.getBackedgeTakenCount(&L);
+ Value *Inc;
+ CmpPredicate Pred;
+ BasicBlock *Succ1;
+ BasicBlock *Succ2;
+ // The loop must execute at least 2 iterations to guarantee that peeled
+ // iteration executes.
+ // TODO: Add checks during codegen.
+ if (isa<SCEVCouldNotCompute>(BTC) ||
+ !SE.isKnownPredicate(CmpInst::ICMP_UGT, BTC, SE.getZero(BTC->getType())))
+ return false;
+
+ // Check if the exit condition of the loop can be adjusted by the peeling
+ // codegen. For now, it must
+ // * exit via the latch,
+ // * the exit condition must be a NE/EQ compare of an induction with step
+ // of 1.
+ BasicBlock *Latch = L.getLoopLatch();
+ return Latch && Latch == L.getExitingBlock() &&
+ match(Latch->getTerminator(),
+ m_Br(m_ICmp(Pred, m_Value(Inc), m_Value()), m_BasicBlock(Succ1),
+ m_BasicBlock(Succ2))) &&
+ ((Pred == CmpInst::ICMP_EQ && Succ2 == L.getHeader()) ||
+ (Pred == CmpInst::ICMP_NE && Succ1 == L.getHeader())) &&
+ isa<SCEVAddRecExpr>(SE.getSCEV(Inc)) &&
----------------
efriedma-quic wrote:
Just spotted this while looking at the followup, but... do you need to check that the AddRec is for the correct loop? It can't be for a subloop, I think, but it could be for a parent loop. (Not sure this has any practical effect given the current usage of canPeelLastIteration().)
Also, do you need to check the RHS is invariant?
https://github.com/llvm/llvm-project/pull/139551
More information about the llvm-commits
mailing list