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 @@ -772,6 +772,13 @@ "Op must be an operand of the recipe"); return false; } + + /// Returns true if the recipe only uses scalars of operand \p Op. + 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) { @@ -1558,6 +1565,13 @@ "Op must be an operand of the recipe"); return isUniform(); } + + /// Returns true if the recipe only uses scalars of operand \p Op. + bool usesScalars(const VPValue *Op) const override { + assert(is_contained(operands(), Op) && + "Op must be an operand of the recipe"); + return true; + } }; /// A recipe for generating conditional branches on the bits of a mask. @@ -1626,6 +1640,13 @@ void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override; #endif + + /// Returns true if the recipe only uses scalars of operand \p Op. + bool usesScalars(const VPValue *Op) const override { + assert(is_contained(operands(), Op) && + "Op must be an operand of the recipe"); + return true; + } }; /// A Recipe for widening load/store operations. @@ -1895,6 +1916,14 @@ VPCanonicalIVPHIRecipe *getCanonicalIV() const; VPValue *getStartValue() const { return getOperand(1); } VPValue *getStepValue() const { return getOperand(2); } + + /// Returns true if the recipe only uses the first lane of operand \p Op. + /// Conservatively returns false. + bool onlyFirstLaneUsed(const VPValue *Op) const override { + assert(is_contained(operands(), Op) && + "Op must be an operand of the recipe"); + return true; + } }; /// VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It