[llvm] [VPlan] Implement VPlan-based unit-strideness speculation (PR #182595)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 31 00:09:41 PDT 2026
================
@@ -5521,6 +5531,184 @@ void VPlanTransforms::makeMemOpWideningDecisions(VPlan &Plan, VFRange &Range,
});
}
+void VPlanTransforms::multiversionForUnitStridedMemOps(
+ VPlan &Plan, VPCostContext &CostCtx, VPRecipeBuilder &RecipeBuilder,
+ VFRange &Range, SmallVectorImpl<VPInstruction *> &MemOps) {
+ ScalarEvolution *SE = CostCtx.PSE.getSE();
+ PredicatedScalarEvolution StrideMVPSE(*SE, const_cast<Loop &>(*CostCtx.L));
+ SCEVUnionPredicate StridePredicates({}, *SE);
+
+ for (VPInstruction *VPI : MemOps) {
+ auto *PtrOp = VPI->getOpcode() == Instruction::Load ? VPI->getOperand(0)
+ : VPI->getOperand(1);
+
+ const SCEV *PtrSCEV =
+ vputils::getSCEVExprForVPValue(PtrOp, CostCtx.PSE, CostCtx.L);
+ const SCEV *Start, *Stride;
+
+ if (!match(PtrSCEV, m_scev_AffineAddRec(m_SCEV(Start), m_SCEV(Stride),
+ m_SpecificLoop(CostCtx.L))))
+ continue;
+
+ Type *ScalarTy = VPI->getOpcode() == Instruction::Load
+ ? VPI->getScalarType()
+ : VPI->getOperand(0)->getScalarType();
+
+ if (VPI->getMask()) {
+ Instruction *I = VPI->getUnderlyingInstr();
+ bool IsLoad = VPI->getOpcode() == Instruction::Load;
+ if (!LoopVectorizationPlanner::getDecisionAndClampRange(
+ [&](ElementCount VF) -> bool {
+ return CostCtx.Config.isLegalMaskedLoadOrStore(
+ IsLoad, ScalarTy, getLoadStoreAlignment(I),
+ getLoadStoreAddressSpace(I));
+ },
+ Range))
+ continue;
+ }
+
----------------
lukel97 wrote:
That makes sense. Can we add a comment to explain that. Also since this will clamp the VF, should we move this down further after the SCEV checks? Maybe beside the backedge check which also clamps VF
https://github.com/llvm/llvm-project/pull/182595
More information about the llvm-commits
mailing list