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 @@ -7806,14 +7806,15 @@ if (auto Recipe = RecipeBuilder.tryToCreateWidenRecipe(Instr, Range, Plan)) { - // Check if the recipe can be converted to a VPValue. We need the extra - // down-casting step until VPRecipeBase inherits from VPValue. - VPValue *MaybeVPValue = Recipe->toVPValue(); - if (!Instr->getType()->isVoidTy() && MaybeVPValue) { - if (NeedDef.contains(Instr)) - Plan->addOrReplaceVPValue(Instr, MaybeVPValue); + for (auto *Def : Recipe->defined_values()) { + auto *UV = Def->getUnderlyingValue(); + if (UV->getType()->isVoidTy()) + continue; + + if (NeedDef.contains(UV)) + Plan->addOrReplaceVPValue(UV, Def); else - Plan->addVPValue(Instr, MaybeVPValue); + Plan->addVPValue(UV, Def); } RecipeBuilder.setRecipe(Instr, Recipe); 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 @@ -707,7 +707,7 @@ /// While as any Recipe it may generate a sequence of IR instructions when /// executed, these instructions would always form a single-def expression as /// the VPInstruction is also a single def-use vertex. -class VPInstruction : public VPValue, public VPUser, public VPRecipeBase { +class VPInstruction : public VPRecipeBase, public VPUser, public VPValue { friend class VPlanSlp; public: @@ -733,12 +733,12 @@ public: VPInstruction(unsigned Opcode, ArrayRef Operands) - : VPValue(VPValue::VPInstructionSC), VPUser(Operands), - VPRecipeBase(VPRecipeBase::VPInstructionSC), Opcode(Opcode) {} + : VPRecipeBase(VPRecipeBase::VPInstructionSC), VPUser(Operands), + VPValue(VPValue::VPInstructionSC, nullptr, this), Opcode(Opcode) {} VPInstruction(unsigned Opcode, ArrayRef Operands) - : VPValue(VPValue::VPInstructionSC), VPUser({}), - VPRecipeBase(VPRecipeBase::VPInstructionSC), Opcode(Opcode) { + : VPRecipeBase(VPRecipeBase::VPInstructionSC), VPUser({}), + VPValue(VPValue::VPInstructionSC, nullptr, this), Opcode(Opcode) { for (auto *I : Operands) addOperand(I->getVPValue()); } 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 @@ -68,10 +68,6 @@ // for multiple underlying IRs (Polly?) by providing a new VPlan front-end, // back-end and analysis information for the new IR. - /// Return the underlying Value attached to this VPValue. - Value *getUnderlyingValue() { return UnderlyingVal; } - const Value *getUnderlyingValue() const { return UnderlyingVal; } - // Set \p Val as the underlying Value of this VPValue. void setUnderlyingValue(Value *Val) { assert(!UnderlyingVal && "Underlying Value is already set."); @@ -79,6 +75,10 @@ } public: + /// Return the underlying Value attached to this VPValue. + Value *getUnderlyingValue() { return UnderlyingVal; } + const Value *getUnderlyingValue() const { return UnderlyingVal; } + /// An enumeration for keeping track of the concrete subclass of VPValue that /// are actually instantiated. Values of this enumeration are kept in the /// SubclassID field of the VPValue objects. They are used for concrete