diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h --- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h +++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h @@ -350,9 +350,12 @@ /// Build a VPlan using VPRecipes according to the information gather by /// Legal. This method is only used for the legacy inner loop vectorizer. - VPlanPtr - buildVPlanWithVPRecipes(VFRange &Range, - SmallPtrSetImpl &DeadInstructions); + /// \p Range's largest included VF is restricted to the maximum VF the + /// returned VPlan is valid for. If no VPlan can be built for the input range, + /// set the largest included VF to the maximum VF for which no plan could be + /// built. + std::optional tryToBuildVPlanWithVPRecipes( + VFRange &Range, SmallPtrSetImpl &DeadInstructions); /// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive, /// according to the information gathered by Legal when it checked if it is diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -7555,6 +7555,12 @@ LLVM_DEBUG(dbgs() << "LV: Using user VF " << UserVF << ".\n"); CM.collectInLoopReductions(); buildVPlansWithVPRecipes(UserVF, UserVF); + if (!hasPlanWithVF(UserVF)) { + LLVM_DEBUG(dbgs() << "LV: No VPlan could be built for " << UserVF + << ".\n"); + return std::nullopt; + } + LLVM_DEBUG(printPlans(dbgs())); return {{UserVF, 0, 0}}; } else @@ -7592,6 +7598,11 @@ // Select the optimal vectorization factor. VectorizationFactor VF = CM.selectVectorizationFactor(VFCandidates); assert((VF.Width.isScalar() || VF.ScalarCost > 0) && "when vectorizing, the scalar cost must be non-zero."); + if (!hasPlanWithVF(VF.Width)) { + LLVM_DEBUG(dbgs() << "LV: No VPlan could be built for " << VF.Width + << ".\n"); + return std::nullopt; + } return VF; } @@ -8668,7 +8679,8 @@ auto MaxVFPlusOne = MaxVF.getWithIncrement(1); for (ElementCount VF = MinVF; ElementCount::isKnownLT(VF, MaxVFPlusOne);) { VFRange SubRange = {VF, MaxVFPlusOne}; - VPlans.push_back(buildVPlanWithVPRecipes(SubRange, DeadInstructions)); + if (auto Plan = tryToBuildVPlanWithVPRecipes(SubRange, DeadInstructions)) + VPlans.push_back(std::move(*Plan)); VF = SubRange.End; } } @@ -8799,7 +8811,7 @@ } } -VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes( +std::optional LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes( VFRange &Range, SmallPtrSetImpl &DeadInstructions) { SmallPtrSet *, 1> InterleaveGroups;