[llvm] [LV] Use SCEV to compute final value of complex induction variables (PR #195059)
Mel Chen via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 02:24:10 PDT 2026
================
@@ -1148,8 +1148,43 @@ optimizeLatchExitInductionUser(VPlan &Plan, VPValue *Op,
return nullptr;
}
+static VPValue *optimizeLatchExitIVUserViaSCEV(VPlan &Plan, VPValue *Op,
+ PredicatedScalarEvolution &PSE,
+ VPValue *ResumeTC,
+ const Loop *L) {
+ VPValue *Incoming;
+ if (!match(Op, m_ExtractLastLaneOfLastPart(m_VPValue(Incoming))))
+ return nullptr;
+
+ const SCEV *IncomingSCEV = vputils::getSCEVExprForVPValue(Incoming, PSE, L);
+ const SCEV *Start, *Step;
+ if (!match(IncomingSCEV, m_scev_AffineAddRec(m_SCEV(Start), m_SCEV(Step),
+ m_SpecificLoop(L))))
+ return nullptr;
+
+ // TODO: Start value can be defined be a VPExpandSCEVRecipe after
+ // VPDerivedIVRecipe supports a general VPValue as the start value.
+ VPIRValue *StartIRV = vputils::getVPIRValueForSCEVExpr(Plan, Start);
+ if (!StartIRV)
+ return nullptr;
+
+ Type *StartTy = StartIRV->getType();
+ assert(StartTy->isIntOrPtrTy() && "The type must be SCEVable");
+ InductionDescriptor::InductionKind Kind =
+ StartTy->isPointerTy() ? InductionDescriptor::IK_PtrInduction
+ : InductionDescriptor::IK_IntInduction;
+ VPValue *StepVPV = vputils::getOrCreateVPValueForSCEVExpr(Plan, Step);
+ VPBuilder Builder(cast<VPInstruction>(Op));
+ Type *TCTy = ResumeTC->getScalarType();
+ VPValue *ExitCount = Builder.createOverflowingOp(
+ Instruction::Sub, {ResumeTC, Plan.getConstantInt(TCTy, 1)},
+ {/*HasNUW=*/true, /*HasNSW=*/false}, DebugLoc::getUnknown());
+ return Builder.createDerivedIV(Kind, /*FPBinOp=*/nullptr, StartIRV, ExitCount,
----------------
Mel-Chen wrote:
I think separate patches would feel cleaner, but combining them is fine too.
c1b59e332eb10648a820b99370f5a6e93d7d777f
https://github.com/llvm/llvm-project/pull/195059
More information about the llvm-commits
mailing list