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,7 +350,11 @@ /// Build a VPlan using VPRecipes according to the information gather by /// Legal. This method is only used for the legacy inner loop vectorizer. - VPlanPtr + /// \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 buildVPlanWithVPRecipes(VFRange &Range, SmallPtrSetImpl &DeadInstructions); 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 @@ -7647,6 +7647,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 @@ -7684,6 +7690,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; } @@ -8808,7 +8819,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 = buildVPlanWithVPRecipes(SubRange, DeadInstructions)) + VPlans.push_back(std::move(*Plan)); VF = SubRange.End; } } @@ -8939,7 +8951,7 @@ } } -VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes( +std::optional LoopVectorizationPlanner::buildVPlanWithVPRecipes( VFRange &Range, SmallPtrSetImpl &DeadInstructions) { SmallPtrSet *, 1> InterleaveGroups;