From ff0ec4f42ea035253684183a0e8de9d87ef7111a Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Tue, 18 Apr 2023 10:29:17 +0100 Subject: [PATCH] Recommit "[VPlan] Unify Value2VPValue and VPExternalDefs maps (NFCI)." This reverts the revert commit 8c2276f89887d0a27298a1bbbd2181fa54bbb509. The updated patch re-orders the getDefiningRecipe check in getVPalue to avoid a use-after-free. Original commit message: Before this patch, a VPlan contained 2 mappings for Values -> VPValue: 1) Value2VPValue and 2) VPExternalDefs. This duplication is unnecessary and there are already cases where external defs are added to Value2VPValue. This patch replaces all uses of VPExternalDefs with Value2VPValue. It clarifies the naming of getOrAddVPValue (to getOrAddExternalVPValue) and addVPValue (to addExternalVPValue). At the moment, this is NFC, but will enable additional simplifications in D147783. Depends on D147891. Reviewed By: Ayal Differential Revision: https://reviews.llvm.org/D147892 --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 53 +++++++--------- llvm/lib/Transforms/Vectorize/VPlan.cpp | 10 ++-- llvm/lib/Transforms/Vectorize/VPlan.h | 70 +++++++--------------- llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp | 4 +- llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp | 26 ++++---- .../Transforms/Vectorize/VPlanHCFGTest.cpp | 2 +- llvm/unittests/Transforms/Vectorize/VPlanTest.cpp | 4 +- 7 files changed, 67 insertions(+), 102 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index d96daf0..daebffb 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8147,7 +8147,7 @@ VPValue *VPRecipeBuilder::createEdgeMask(BasicBlock *Src, BasicBlock *Dst, if (OrigLoop->isLoopExiting(Src)) return EdgeMaskCache[Edge] = SrcMask; - VPValue *EdgeMask = Plan.getOrAddVPValue(BI->getCondition()); + VPValue *EdgeMask = Plan.getVPValueOrAddLiveIn(BI->getCondition()); assert(EdgeMask && "No Edge Mask found for condition"); if (BI->getSuccessor(0) != Dst) @@ -8158,7 +8158,7 @@ VPValue *VPRecipeBuilder::createEdgeMask(BasicBlock *Src, BasicBlock *Dst, // 'select i1 SrcMask, i1 EdgeMask, i1 false'. // The select version does not introduce new UB if SrcMask is false and // EdgeMask is poison. Using 'and' here introduces undefined behavior. - VPValue *False = Plan.getOrAddVPValue( + VPValue *False = Plan.getVPValueOrAddLiveIn( ConstantInt::getFalse(BI->getCondition()->getType())); EdgeMask = Builder.createSelect(SrcMask, EdgeMask, False, BI->getDebugLoc()); @@ -8277,22 +8277,11 @@ VPRecipeBase *VPRecipeBuilder::tryToWidenMemory(Instruction *I, /// Creates a VPWidenIntOrFpInductionRecpipe for \p Phi. If needed, it will also /// insert a recipe to expand the step for the induction recipe. -static VPWidenIntOrFpInductionRecipe *createWidenInductionRecipes( - PHINode *Phi, Instruction *PhiOrTrunc, VPValue *Start, - const InductionDescriptor &IndDesc, LoopVectorizationCostModel &CM, - VPlan &Plan, ScalarEvolution &SE, Loop &OrigLoop, VFRange &Range) { - // Returns true if an instruction \p I should be scalarized instead of - // vectorized for the chosen vectorization factor. - auto ShouldScalarizeInstruction = [&CM](Instruction *I, ElementCount VF) { - return CM.isScalarAfterVectorization(I, VF) || - CM.isProfitableToScalarize(I, VF); - }; - - bool NeedsScalarIVOnly = LoopVectorizationPlanner::getDecisionAndClampRange( - [&](ElementCount VF) { - return ShouldScalarizeInstruction(PhiOrTrunc, VF); - }, - Range); +static VPWidenIntOrFpInductionRecipe * +createWidenInductionRecipes(PHINode *Phi, Instruction *PhiOrTrunc, + VPValue *Start, const InductionDescriptor &IndDesc, + VPlan &Plan, ScalarEvolution &SE, Loop &OrigLoop, + VFRange &Range) { assert(IndDesc.getStartValue() == Phi->getIncomingValueForBlock(OrigLoop.getLoopPreheader())); assert(SE.isLoopInvariant(IndDesc.getStep(), &OrigLoop) && @@ -8301,12 +8290,10 @@ static VPWidenIntOrFpInductionRecipe *createWidenInductionRecipes( VPValue *Step = vputils::getOrCreateVPValueForSCEVExpr(Plan, IndDesc.getStep(), SE); if (auto *TruncI = dyn_cast(PhiOrTrunc)) { - return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc, TruncI, - !NeedsScalarIVOnly); + return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc, TruncI); } assert(isa(PhiOrTrunc) && "must be a phi node here"); - return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc, - !NeedsScalarIVOnly); + return new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, IndDesc); } VPRecipeBase *VPRecipeBuilder::tryToOptimizeInductionPHI( @@ -8315,7 +8302,7 @@ VPRecipeBase *VPRecipeBuilder::tryToOptimizeInductionPHI( // Check if this is an integer or fp induction. If so, build the recipe that // produces its scalar and vector values. if (auto *II = Legal->getIntOrFpInductionDescriptor(Phi)) - return createWidenInductionRecipes(Phi, Phi, Operands[0], *II, CM, Plan, + return createWidenInductionRecipes(Phi, Phi, Operands[0], *II, Plan, *PSE.getSE(), *OrigLoop, Range); // Check if this is pointer induction. If so, build the recipe for it. @@ -8354,9 +8341,9 @@ VPWidenIntOrFpInductionRecipe *VPRecipeBuilder::tryToOptimizeInductionTruncate( auto *Phi = cast(I->getOperand(0)); const InductionDescriptor &II = *Legal->getIntOrFpInductionDescriptor(Phi); - VPValue *Start = Plan.getOrAddVPValue(II.getStartValue()); - return createWidenInductionRecipes(Phi, I, Start, II, CM, Plan, - *PSE.getSE(), *OrigLoop, Range); + VPValue *Start = Plan.getVPValueOrAddLiveIn(II.getStartValue()); + return createWidenInductionRecipes(Phi, I, Start, II, Plan, *PSE.getSE(), + *OrigLoop, Range); } return nullptr; } @@ -8487,7 +8474,7 @@ VPWidenCallRecipe *VPRecipeBuilder::tryToWidenCall(CallInst *CI, if (Legal->isMaskRequired(CI)) Mask = createBlockInMask(CI->getParent(), *Plan); else - Mask = Plan->getOrAddVPValue(ConstantInt::getTrue( + Mask = Plan->getVPValueOrAddLiveIn(ConstantInt::getTrue( IntegerType::getInt1Ty(Variant->getFunctionType()->getContext()))); VFShape Shape = VFShape::get(*CI, VariantVF, /*HasGlobalPred=*/true); @@ -8539,8 +8526,8 @@ VPRecipeBase *VPRecipeBuilder::tryToWiden(Instruction *I, if (CM.isPredicatedInst(I)) { SmallVector Ops(Operands.begin(), Operands.end()); VPValue *Mask = createBlockInMask(I->getParent(), *Plan); - VPValue *One = - Plan->getOrAddExternalDef(ConstantInt::get(I->getType(), 1u, false)); + VPValue *One = Plan->getVPValueOrAddLiveIn( + ConstantInt::get(I->getType(), 1u, false)); auto *SafeRHS = new VPInstruction(Instruction::Select, {Mask, Ops[1], One}, I->getDebugLoc()); @@ -8761,7 +8748,7 @@ void LoopVectorizationPlanner::buildVPlansWithVPRecipes(ElementCount MinVF, static void addCanonicalIVRecipes(VPlan &Plan, Type *IdxTy, DebugLoc DL, TailFoldingStyle Style) { Value *StartIdx = ConstantInt::get(IdxTy, 0); - auto *StartV = Plan.getOrAddVPValue(StartIdx); + auto *StartV = Plan.getVPValueOrAddLiveIn(StartIdx); // Add a VPCanonicalIVPHIRecipe starting at 0 to the header. auto *CanonicalIVPHI = new VPCanonicalIVPHIRecipe(StartV, DL); @@ -8877,7 +8864,7 @@ static void addUsersInExitBlock(VPBasicBlock *HeaderVPBB, for (PHINode &ExitPhi : ExitBB->phis()) { Value *IncomingValue = ExitPhi.getIncomingValueForBlock(ExitingBB); - VPValue *V = Plan.getOrAddVPValue(IncomingValue, true); + VPValue *V = Plan.getVPValueOrAddLiveIn(IncomingValue); Plan.addLiveOut(&ExitPhi, V); } } @@ -8988,7 +8975,7 @@ std::optional LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes( SmallVector Operands; auto *Phi = dyn_cast(Instr); if (Phi && Phi->getParent() == OrigLoop->getHeader()) { - Operands.push_back(Plan->getOrAddVPValue( + Operands.push_back(Plan->getVPValueOrAddLiveIn( Phi->getIncomingValueForBlock(OrigLoop->getLoopPreheader()))); } else { auto OpRange = Plan->mapToVPValues(Instr->operands()); @@ -10477,7 +10464,7 @@ bool LoopVectorizePass::processLoop(Loop *L) { IndPhi, *ID, {EPI.MainLoopIterationCountCheck}); } assert(ResumeV && "Must have a resume value"); - VPValue *StartVal = BestEpiPlan.getOrAddExternalDef(ResumeV); + VPValue *StartVal = BestEpiPlan.getVPValueOrAddLiveIn(ResumeV); cast(&R)->setStartValue(StartVal); } diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index 4655399..f185c9a 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -591,14 +591,12 @@ VPlan::~VPlan() { VPBlockBase::deleteCFG(Entry); } - for (VPValue *VPV : VPValuesToFree) + for (VPValue *VPV : VPLiveInsToFree) delete VPV; if (TripCount) delete TripCount; if (BackedgeTakenCount) delete BackedgeTakenCount; - for (auto &P : VPExternalDefs) - delete P.second; } VPActiveLaneMaskPHIRecipe *VPlan::getActiveLaneMaskPhi() { @@ -641,7 +639,7 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV, // needs to be changed from zero to the value after the main vector loop. // FIXME: Improve modeling for canonical IV start values in the epilogue loop. if (CanonicalIVStartValue) { - VPValue *VPV = getOrAddExternalDef(CanonicalIVStartValue); + VPValue *VPV = getVPValueOrAddLiveIn(CanonicalIVStartValue); auto *IV = getCanonicalIV(); assert(all_of(IV->users(), [](const VPUser *U) { @@ -1131,9 +1129,9 @@ bool vputils::onlyFirstLaneUsed(VPValue *Def) { VPValue *vputils::getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr, ScalarEvolution &SE) { if (auto *E = dyn_cast(Expr)) - return Plan.getOrAddExternalDef(E->getValue()); + return Plan.getVPValueOrAddLiveIn(E->getValue()); if (auto *E = dyn_cast(Expr)) - return Plan.getOrAddExternalDef(E->getValue()); + return Plan.getVPValueOrAddLiveIn(E->getValue()); VPBasicBlock *Preheader = Plan.getEntry()->getEntryBasicBlock(); VPExpandSCEVRecipe *Step = new VPExpandSCEVRecipe(Expr, SE); diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index ec75c02..3b71a5b 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1140,22 +1140,20 @@ class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe { PHINode *IV; TruncInst *Trunc; const InductionDescriptor &IndDesc; - bool NeedsVectorIV; public: VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, - const InductionDescriptor &IndDesc, - bool NeedsVectorIV) + const InductionDescriptor &IndDesc) : VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start), IV(IV), - Trunc(nullptr), IndDesc(IndDesc), NeedsVectorIV(NeedsVectorIV) { + Trunc(nullptr), IndDesc(IndDesc) { addOperand(Step); } VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, const InductionDescriptor &IndDesc, - TruncInst *Trunc, bool NeedsVectorIV) + TruncInst *Trunc) : VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, Trunc, Start), - IV(IV), Trunc(Trunc), IndDesc(IndDesc), NeedsVectorIV(NeedsVectorIV) { + IV(IV), Trunc(Trunc), IndDesc(IndDesc) { addOperand(Step); } @@ -1209,9 +1207,6 @@ public: const Type *getScalarType() const { return Trunc ? Trunc->getType() : IV->getType(); } - - /// Returns true if a vector phi needs to be created for the induction. - bool needsVectorIV() const { return NeedsVectorIV; } }; class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe { @@ -2233,10 +2228,6 @@ class VPlan { /// Holds the name of the VPlan, for printing. std::string Name; - /// Holds all the external definitions created for this VPlan. External - /// definitions must be immutable and hold a pointer to their underlying IR. - DenseMap VPExternalDefs; - /// Represents the trip count of the original loop, for folding /// the tail. VPValue *TripCount = nullptr; @@ -2252,9 +2243,9 @@ class VPlan { /// VPlan. Value2VPValueTy Value2VPValue; - /// Contains all VPValues that been allocated by addVPValue directly and need - /// to be free when the plan's destructor is called. - SmallVector VPValuesToFree; + /// Contains all the external definitions created for this VPlan. External + /// definitions are VPValues that hold a pointer to their underlying IR. + SmallVector VPLiveInsToFree; /// Indicates whether it is safe use the Value2VPValue mapping or if the /// mapping cannot be used any longer, because it is stale. @@ -2334,50 +2325,35 @@ public: void setName(const Twine &newName) { Name = newName.str(); } - /// Get the existing or add a new external definition for \p V. - VPValue *getOrAddExternalDef(Value *V) { - auto I = VPExternalDefs.insert({V, nullptr}); - if (I.second) - I.first->second = new VPValue(V); - return I.first->second; - } - - void addVPValue(Value *V) { - assert(Value2VPValueEnabled && - "IR value to VPValue mapping may be out of date!"); - assert(V && "Trying to add a null Value to VPlan"); - assert(!Value2VPValue.count(V) && "Value already exists in VPlan"); - VPValue *VPV = new VPValue(V); - Value2VPValue[V] = VPV; - VPValuesToFree.push_back(VPV); - } - void addVPValue(Value *V, VPValue *VPV) { - assert(Value2VPValueEnabled && "Value2VPValue mapping may be out of date!"); + assert((Value2VPValueEnabled || !VPV->getDefiningRecipe()) && + "Value2VPValue mapping may be out of date!"); assert(V && "Trying to add a null Value to VPlan"); assert(!Value2VPValue.count(V) && "Value already exists in VPlan"); Value2VPValue[V] = VPV; } /// Returns the VPValue for \p V. \p OverrideAllowed can be used to disable - /// checking whether it is safe to query VPValues using IR Values. + /// /// checking whether it is safe to query VPValues using IR Values. VPValue *getVPValue(Value *V, bool OverrideAllowed = false) { - assert((OverrideAllowed || isa(V) || Value2VPValueEnabled) && - "Value2VPValue mapping may be out of date!"); assert(V && "Trying to get the VPValue of a null Value"); assert(Value2VPValue.count(V) && "Value does not exist in VPlan"); + assert((Value2VPValueEnabled || OverrideAllowed || + !Value2VPValue[V]->getDefiningRecipe()) && + "Value2VPValue mapping may be out of date!"); return Value2VPValue[V]; } - /// Gets the VPValue or adds a new one (if none exists yet) for \p V. \p - /// OverrideAllowed can be used to disable checking whether it is safe to - /// query VPValues using IR Values. - VPValue *getOrAddVPValue(Value *V, bool OverrideAllowed = false) { - assert((OverrideAllowed || isa(V) || Value2VPValueEnabled) && - "Value2VPValue mapping may be out of date!"); + /// Gets the VPValue for \p V or adds a new live-in (if none exists yet) for + /// \p V. + VPValue *getVPValueOrAddLiveIn(Value *V) { assert(V && "Trying to get or add the VPValue of a null Value"); - if (!Value2VPValue.count(V)) - addVPValue(V); + if (!Value2VPValue.count(V)) { + VPValue *VPV = new VPValue(V); + VPLiveInsToFree.push_back(VPV); + addVPValue(V, VPV); + } + return getVPValue(V); } @@ -2403,7 +2379,7 @@ public: iterator_range>> mapToVPValues(User::op_range Operands) { std::function Fn = [this](Value *Op) { - return getOrAddVPValue(Op); + return getVPValueOrAddLiveIn(Op); }; return map_range(Operands, Fn); } diff --git a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp index 952ce72..10fefae 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp @@ -196,7 +196,7 @@ VPValue *PlainCFGBuilder::getOrCreateVPOperand(Value *IRVal) { // A and B: Create VPValue and add it to the pool of external definitions and // to the Value->VPValue map. - VPValue *NewVPVal = Plan.getOrAddExternalDef(IRVal); + VPValue *NewVPVal = Plan.getVPValueOrAddLiveIn(IRVal); IRDef2VPValue[IRVal] = NewVPVal; return NewVPVal; } @@ -272,7 +272,7 @@ VPBasicBlock *PlainCFGBuilder::buildPlainCFG() { for (auto &I : *ThePreheaderBB) { if (I.getType()->isVoidTy()) continue; - IRDef2VPValue[&I] = Plan.getOrAddExternalDef(&I); + IRDef2VPValue[&I] = Plan.getVPValueOrAddLiveIn(&I); } // Create empty VPBB for Loop H so that we can link PH->H. VPBlockBase *HeaderVPBB = getOrCreateVPBB(TheLoop->getHeader()); diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index 8aa968f..c657b76 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -52,11 +52,10 @@ void VPlanTransforms::VPInstructionsToVPRecipes( if (auto *VPPhi = dyn_cast(&Ingredient)) { auto *Phi = cast(VPPhi->getUnderlyingValue()); if (const auto *II = GetIntOrFpInductionDescriptor(Phi)) { - VPValue *Start = Plan->getOrAddVPValue(II->getStartValue()); + VPValue *Start = Plan->getVPValueOrAddLiveIn(II->getStartValue()); VPValue *Step = vputils::getOrCreateVPValueForSCEVExpr(*Plan, II->getStep(), SE); - NewRecipe = - new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, *II, true); + NewRecipe = new VPWidenIntOrFpInductionRecipe(Phi, Start, Step, *II); } else { Plan->addVPValue(Phi, VPPhi); continue; @@ -68,13 +67,15 @@ void VPlanTransforms::VPInstructionsToVPRecipes( // Create VPWidenMemoryInstructionRecipe for loads and stores. if (LoadInst *Load = dyn_cast(Inst)) { NewRecipe = new VPWidenMemoryInstructionRecipe( - *Load, Plan->getOrAddVPValue(getLoadStorePointerOperand(Inst)), + *Load, + Plan->getVPValueOrAddLiveIn(getLoadStorePointerOperand(Inst)), nullptr /*Mask*/, false /*Consecutive*/, false /*Reverse*/); } else if (StoreInst *Store = dyn_cast(Inst)) { NewRecipe = new VPWidenMemoryInstructionRecipe( - *Store, Plan->getOrAddVPValue(getLoadStorePointerOperand(Inst)), - Plan->getOrAddVPValue(Store->getValueOperand()), nullptr /*Mask*/, - false /*Consecutive*/, false /*Reverse*/); + *Store, + Plan->getVPValueOrAddLiveIn(getLoadStorePointerOperand(Inst)), + Plan->getVPValueOrAddLiveIn(Store->getValueOperand()), + nullptr /*Mask*/, false /*Consecutive*/, false /*Reverse*/); } else if (GetElementPtrInst *GEP = dyn_cast(Inst)) { NewRecipe = new VPWidenGEPRecipe(GEP, Plan->mapToVPValues(GEP->operands())); @@ -472,7 +473,10 @@ void VPlanTransforms::removeRedundantCanonicalIVs(VPlan &Plan) { // everything WidenNewIV's users need. That is, WidenOriginalIV will // generate a vector phi or all users of WidenNewIV demand the first lane // only. - if (WidenOriginalIV->needsVectorIV() || + if (any_of(WidenOriginalIV->users(), + [WidenOriginalIV](VPUser *U) { + return !U->usesScalars(WidenOriginalIV); + }) || vputils::onlyFirstLaneUsed(WidenNewIV)) { WidenNewIV->replaceAllUsesWith(WidenOriginalIV); WidenNewIV->eraseFromParent(); @@ -600,9 +604,9 @@ void VPlanTransforms::optimizeForVFAndUF(VPlan &Plan, ElementCount BestVF, return; LLVMContext &Ctx = SE.getContext(); - auto *BOC = - new VPInstruction(VPInstruction::BranchOnCond, - {Plan.getOrAddExternalDef(ConstantInt::getTrue(Ctx))}); + auto *BOC = new VPInstruction( + VPInstruction::BranchOnCond, + {Plan.getVPValueOrAddLiveIn(ConstantInt::getTrue(Ctx))}); Term->eraseFromParent(); ExitingVPBB->appendRecipe(BOC); Plan.setVF(BestVF); diff --git a/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp index e8c84cc..f6f283a 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp @@ -96,7 +96,7 @@ TEST_F(VPlanHCFGTest, testBuildHCFGInnerLoop) { #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) // Add an external value to check we do not print the list of external values, // as this is not required with the new printing. - Plan->addVPValue(&*F->arg_begin()); + Plan->getVPValueOrAddLiveIn(&*F->arg_begin()); std::string FullDump; raw_string_ostream OS(FullDump); Plan->printDOT(OS); diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp index 903e823..606d8d0 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp @@ -1203,8 +1203,8 @@ TEST(VPRecipeTest, dump) { BinaryOperator::CreateAdd(UndefValue::get(Int32), UndefValue::get(Int32)); AI->setName("a"); SmallVector Args; - VPValue *ExtVPV1 = Plan.getOrAddExternalDef(ConstantInt::get(Int32, 1)); - VPValue *ExtVPV2 = Plan.getOrAddExternalDef(ConstantInt::get(Int32, 2)); + VPValue *ExtVPV1 = Plan.getVPValueOrAddLiveIn(ConstantInt::get(Int32, 1)); + VPValue *ExtVPV2 = Plan.getVPValueOrAddLiveIn(ConstantInt::get(Int32, 2)); Args.push_back(ExtVPV1); Args.push_back(ExtVPV2); VPWidenRecipe *WidenR = -- 2.7.4