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 @@ -8051,8 +8051,7 @@ assert(!Range.isEmpty() && "Trying to test an empty VF range."); bool PredicateAtRangeStart = Predicate(Range.Start); - for (ElementCount TmpVF = Range.Start * 2; - ElementCount::isKnownLT(TmpVF, Range.End); TmpVF *= 2) + for (ElementCount TmpVF : VFRange(Range.Start * 2, Range.End)) if (Predicate(TmpVF) != PredicateAtRangeStart) { Range.End = TmpVF; break; @@ -8906,8 +8905,7 @@ // so this function is better to be conservative, rather than to split // it up into different VPlans. bool IVUpdateMayOverflow = false; - for (ElementCount VF = Range.Start; - ElementCount::isKnownLT(VF, Range.End); VF *= 2) + for (ElementCount VF : Range) IVUpdateMayOverflow |= !isIndvarOverflowCheckKnownFalse(&CM, VF); Instruction *DLInst = @@ -9052,8 +9050,7 @@ } } - for (ElementCount VF = Range.Start; ElementCount::isKnownLT(VF, Range.End); - VF *= 2) + for (ElementCount VF : Range) Plan->addVF(VF); Plan->setName("Initial VPlan"); @@ -9088,8 +9085,7 @@ VPlanHCFGBuilder HCFGBuilder(OrigLoop, LI, *Plan); HCFGBuilder.buildHierarchicalCFG(); - for (ElementCount VF = Range.Start; ElementCount::isKnownLT(VF, Range.End); - VF *= 2) + for (ElementCount VF : Range) Plan->addVF(VF); SmallPtrSet DeadInstructions; diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -99,6 +99,36 @@ assert(isPowerOf2_32(Start.getKnownMinValue()) && "Expected Start to be a power of 2"); } + + /// Iterator to iterate over vectorization factors in a VFRange. + class iterator + : public iterator_facade_base { + ElementCount VF; + + public: + iterator(ElementCount VF) : VF(VF) {} + + bool operator==(const iterator &Other) const { return VF == Other.VF; } + + ElementCount operator*() const { return VF; } + + iterator &operator++() { + VF *= 2; + return *this; + } + }; + + iterator begin() { return iterator(Start); } + iterator end() { + ElementCount EndVF = End; + // Make sure the end iterator is a power-of-2 so != comparisons with end + // work as expected. + if (!isPowerOf2_64(End.getKnownMinValue())) + EndVF = ElementCount::get(NextPowerOf2(End.getKnownMinValue()), + End.isScalable()); + return iterator(EndVF); + } }; using VPlanPtr = std::unique_ptr;