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 @@ -684,6 +684,9 @@ static inline bool classof(const VPUser *U) { return U->getVPUserID() == VPUser::VPUserID::Recipe; } + + /// Returns true if the recipe may have side-effects. + bool mayHaveSideEffects() const; }; inline bool VPUser::classof(const VPDef *Def) { 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 @@ -510,6 +510,30 @@ } #endif +bool VPRecipeBase::mayHaveSideEffects() const { + switch (getVPDefID()) { + case VPBlendSC: + case VPBranchOnMaskSC: + case VPWidenSC: + case VPWidenGEPSC: + case VPReductionSC: + case VPWidenSelectSC: { + const Instruction *I = + dyn_cast_or_null(getVPValue()->getUnderlyingValue()); + (void)I; + assert((!I || !I->mayHaveSideEffects()) && + "underlying instruction has side-effects"); + return false; + } + case VPReplicateSC: { + auto *R = cast(this); + return R->getUnderlyingInstr()->mayHaveSideEffects(); + } + default: + return true; + } +} + void VPRecipeBase::insertBefore(VPRecipeBase *InsertPos) { assert(!Parent && "Recipe already in some VPBasicBlock"); assert(InsertPos->getParent() &&