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 @@ -9610,9 +9610,8 @@ auto *IVR = getParent()->getPlan()->getCanonicalIV(); PHINode *CanonicalIV = cast(State.get(IVR, 0)); - if (all_of(users(), [this](const VPUser *U) { - return cast(U)->usesScalars(this); - })) { + if (all_of(users(), + [this](const VPUser *U) { return U->usesScalars(this); })) { // This is the normalized GEP that starts counting at zero. Value *PtrInd = State.Builder.CreateSExtOrTrunc( CanonicalIV, IndDesc.getStep()->getType()); 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 @@ -761,22 +761,6 @@ bool mayReadOrWriteMemory() const { return mayReadFromMemory() || mayWriteToMemory(); } - - /// Returns true if the recipe only uses the first lane of operand \p Op. - /// Conservatively returns false. - virtual bool onlyFirstLaneUsed(const VPValue *Op) const { - assert(is_contained(operands(), Op) && - "Op must be an operand of the recipe"); - return false; - } - - /// Returns true if the recipe uses scalars of operand \p Op. Conservatively - /// returns if only first (scalar) lane is used, as default. - virtual bool usesScalars(const VPValue *Op) const { - assert(is_contained(operands(), Op) && - "Op must be an operand of the recipe"); - return onlyFirstLaneUsed(Op); - } }; inline bool VPUser::classof(const VPDef *Def) { @@ -1425,9 +1409,8 @@ "Op must be an operand of the recipe"); // Recursing through Blend recipes only, must terminate at header phi's the // latest. - return all_of(users(), [this](VPUser *U) { - return cast(U)->onlyFirstLaneUsed(this); - }); + return all_of(users(), + [this](VPUser *U) { return U->onlyFirstLaneUsed(this); }); } }; diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -998,7 +998,7 @@ // TODO: Split off the case that all users of a pointer phi are scalar // from the VPWidenPointerInductionRecipe. if (all_of(WidenPhi->users(), [WidenPhi](const VPUser *U) { - return cast(U)->usesScalars(WidenPhi); + return U->usesScalars(WidenPhi); })) continue; @@ -1769,9 +1769,8 @@ } bool vputils::onlyFirstLaneUsed(VPValue *Def) { - return all_of(Def->users(), [Def](VPUser *U) { - return cast(U)->onlyFirstLaneUsed(Def); - }); + return all_of(Def->users(), + [Def](VPUser *U) { return U->onlyFirstLaneUsed(Def); }); } VPValue *vputils::getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr, diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -440,13 +440,12 @@ // SetVector to ensure the list of users doesn't contain duplicates. SetVector Users(IV->user_begin(), IV->user_end()); for (VPUser *U : Users) { - VPRecipeBase *R = cast(U); - if (!R->usesScalars(IV)) + if (!U->usesScalars(IV)) continue; - for (unsigned I = 0, E = R->getNumOperands(); I != E; I++) { - if (R->getOperand(I) != IV) + for (unsigned I = 0, E = U->getNumOperands(); I != E; I++) { + if (U->getOperand(I) != IV) continue; - R->setOperand(I, Steps); + U->setOperand(I, Steps); } } } diff --git a/llvm/lib/Transforms/Vectorize/VPlanValue.h b/llvm/lib/Transforms/Vectorize/VPlanValue.h --- a/llvm/lib/Transforms/Vectorize/VPlanValue.h +++ b/llvm/lib/Transforms/Vectorize/VPlanValue.h @@ -287,6 +287,22 @@ /// Method to support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const VPDef *Recipe); + + /// Returns true if the VPUser uses scalars of operand \p Op. Conservatively + /// returns if only first (scalar) lane is used, as default. + virtual bool usesScalars(const VPValue *Op) const { + assert(is_contained(operands(), Op) && + "Op must be an operand of the recipe"); + return onlyFirstLaneUsed(Op); + } + + /// Returns true if the VPUser only uses the first lane of operand \p Op. + /// Conservatively returns false. + virtual bool onlyFirstLaneUsed(const VPValue *Op) const { + assert(is_contained(operands(), Op) && + "Op must be an operand of the recipe"); + return false; + } }; /// This class augments a recipe with a set of VPValues defined by the recipe.