[llvm] [LV] Optimize FindLast recurrences to FindIV (NFCI). (PR #177870)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 2 04:08:10 PST 2026
================
@@ -5349,3 +5349,96 @@ void VPlanTransforms::addExitUsersForFirstOrderRecurrences(VPlan &Plan,
}
}
}
+
+void VPlanTransforms::optimizeFindIVReductions(VPlan &Plan,
+ PredicatedScalarEvolution &PSE,
+ Loop &L) {
+ ScalarEvolution &SE = *PSE.getSE();
+ VPRegionBlock *VectorLoopRegion = Plan.getVectorLoopRegion();
+
+ // Helper lambda to check if the IV range excludes the sentinel value.
+ auto CheckSentinel = [&SE](const SCEV *IVSCEV, bool IsFindLast,
+ bool Signed) -> std::optional<APInt> {
+ unsigned BW = IVSCEV->getType()->getScalarSizeInBits();
+ APInt Sentinel =
+ IsFindLast
+ ? (Signed ? APInt::getSignedMinValue(BW) : APInt::getMinValue(BW))
+ : (Signed ? APInt::getSignedMaxValue(BW) : APInt::getMaxValue(BW));
+
+ ConstantRange IVRange =
+ Signed ? SE.getSignedRange(IVSCEV) : SE.getUnsignedRange(IVSCEV);
+ if (!IVRange.contains(Sentinel))
+ return Sentinel;
+ return std::nullopt;
+ };
+
+ for (VPRecipeBase &Phi :
+ make_early_inc_range(VectorLoopRegion->getEntryBasicBlock()->phis())) {
+ auto *PhiR = dyn_cast<VPReductionPHIRecipe>(&Phi);
+ if (!PhiR || !RecurrenceDescriptor::isFindLastRecurrenceKind(
+ PhiR->getRecurrenceKind()))
+ continue;
+
+ // Get the IV from the backedge value of the reduction phi.
+ // The backedge value should be a select between the phi and the IV.
+ VPValue *BackedgeVal = PhiR->getBackedgeValue();
+ VPValue *TrueVal, *FalseVal;
+ if (!match(BackedgeVal,
+ m_Select(m_VPValue(), m_VPValue(TrueVal), m_VPValue(FalseVal))))
+ continue;
+
+ // The non-phi operand of the select is the IV.
+ VPValue *IV = (TrueVal == PhiR) ? FalseVal : TrueVal;
+
+ const SCEV *IVSCEV = vputils::getSCEVExprForVPValue(IV, PSE, &L);
+ const SCEV *Step;
+ if (!match(IVSCEV, m_scev_AffineAddRec(m_SCEV(), m_SCEV(Step))))
+ continue;
+
+ // Determine direction from SCEV step.
+ // Positive step means FindLast (ascending), negative means FindFirst.
+ if (!SE.isKnownNonZero(Step))
+ continue;
+
+ bool IsFindLast = SE.isKnownPositive(Step);
+ bool UseSigned = true;
+ std::optional<APInt> SentinelVal = CheckSentinel(IVSCEV, IsFindLast, true);
+ if (!SentinelVal) {
+ SentinelVal = CheckSentinel(IVSCEV, IsFindLast, false);
----------------
fhahn wrote:
updated thanks
https://github.com/llvm/llvm-project/pull/177870
More information about the llvm-commits
mailing list