[llvm] [VPlan] Create header phi recipes after initial scalar optimizations. (PR #200920)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 10 05:15:45 PDT 2026
================
@@ -632,19 +632,38 @@ createWidenInductionRecipe(PHINode *Phi, VPPhi *PhiR, VPIRValue *Start,
const InductionDescriptor &IndDesc, VPlan &Plan,
PredicatedScalarEvolution &PSE, Loop &OrigLoop,
DebugLoc DL) {
- [[maybe_unused]] ScalarEvolution &SE = *PSE.getSE();
+ ScalarEvolution &SE = *PSE.getSE();
assert(SE.isLoopInvariant(IndDesc.getStep(), &OrigLoop) &&
"step must be loop invariant");
assert((Plan.getLiveIn(IndDesc.getStartValue()) == Start ||
(SE.isSCEVable(IndDesc.getStartValue()->getType()) &&
- SE.getSCEV(IndDesc.getStartValue()) ==
+ PSE.getSCEV(IndDesc.getStartValue()) ==
vputils::getSCEVExprForVPValue(Start, PSE))) &&
"Start VPValue must match IndDesc's start value");
- VPValue *Step =
- vputils::getOrCreateVPValueForSCEVExpr(Plan, IndDesc.getStep());
-
VPValue *BackedgeVal = PhiR->getOperand(1);
+ // Try to get the versioned step from the induction increment directly.
+ auto GetStep = [&]() -> VPValue * {
+ VPValue *Step;
+ if (match(BackedgeVal, m_Add(m_Specific(PhiR), m_VPValue(Step))))
+ return Step;
+
+ // Pointer induction: scale the GEP index by the source element size.
+ Type *GEPSrcElemTy;
+ ArrayRef<VPValue *> GEPOps;
+ if (match(BackedgeVal, m_GetElementPtr(GEPSrcElemTy, GEPOps)) &&
+ GEPOps.size() == 2 && GEPOps[0] == PhiR) {
+ Type *StepTy = IndDesc.getStep()->getType();
+ const SCEV *Idx = vputils::getSCEVExprForVPValue(GEPOps[1], PSE);
+ if (!isa<SCEVCouldNotCompute>(Idx))
+ return vputils::getOrCreateVPValueForSCEVExpr(
+ Plan, SE.getMulExpr(SE.getTruncateOrSignExtend(Idx, StepTy),
+ SE.getSizeOfExpr(StepTy, GEPSrcElemTy)));
+ }
+ return vputils::getOrCreateVPValueForSCEVExpr(Plan, IndDesc.getStep());
+ };
----------------
fhahn wrote:
Yes that also works, updated, thanks
https://github.com/llvm/llvm-project/pull/200920
More information about the llvm-commits
mailing list