[llvm] [LV] Add initial legality checks for early exit loops with side effects (PR #145663)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 9 05:32:10 PDT 2025
================
@@ -1813,6 +1840,113 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
"backedge taken count: "
<< *SymbolicMaxBTC << '\n');
UncountableExitingBB = SingleUncountableExitingBlock;
+ UncountableExitWithSideEffects = HasSideEffects;
+ return true;
+}
+
+bool LoopVectorizationLegality::canUncountableExitConditionLoadBeMoved(
+ BasicBlock *ExitingBlock) {
+ LoadInst *CriticalUncountableExitConditionLoad = nullptr;
+
+ // Try to find a load in the critical path for the uncountable exit condition.
+ // This is currently matching about the simplest form we can, expecting
+ // only one in-loop load, the result of which is directly compared against
+ // a loop-invariant value.
+ // FIXME: We're insisting on a single use for now, because otherwise we will
+ // need to make PHI nodes for other users. That can be done once the initial
+ // transform code lands.
+ auto *Br = cast<BranchInst>(ExitingBlock->getTerminator());
+
+ using namespace llvm::PatternMatch;
+ Value *L = nullptr;
+ Value *R = nullptr;
+ if (!match(Br->getCondition(),
+ m_OneUse(m_ICmp(m_OneUse(m_Value(L)), (m_Value(R)))))) {
+ reportVectorizationFailure(
+ "Early exit loop with store but no supported condition load",
+ "NoConditionLoadForEarlyExitLoop", ORE, TheLoop);
+ return false;
+ }
+
+ // FIXME: Don't rely on operand ordering for the comparison.
+ if (!TheLoop->isLoopInvariant(R)) {
+ reportVectorizationFailure(
+ "Early exit loop with store but no supported condition load",
+ "NoConditionLoadForEarlyExitLoop", ORE, TheLoop);
+ return false;
+ }
+
+ if (auto *Load = dyn_cast<LoadInst>(L)) {
+ // Make sure that the load address is not loop invariant; we want an
+ // address calculation that we can rotate to the next vector iteration.
+ const SCEV *PtrScev = PSE.getSE()->getSCEV(Load->getPointerOperand());
+ if (PSE.getSE()->isLoopInvariant(PtrScev, TheLoop)) {
----------------
fhahn wrote:
It would probably be safer to check for !AddRec here instead of bailing out on `isLoopInvariant`, which may not be able to identify all invariant cases.
This way we also don't rely on an implementation detail of `isDereferenceableAndAlignedInLoop` (the check for the pointer being an AddRec, i.e. there's nothing fundamental preventing it to look through things like pointer selects).
https://github.com/llvm/llvm-project/pull/145663
More information about the llvm-commits
mailing list