Index: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp =================================================================== --- llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -2489,6 +2489,7 @@ // Make a new scheduling region, i.e. all existing ScheduleData is not // in the new region yet. ++SchedulingRegionID; + NoCalls = true; } ScheduleData *getScheduleData(Value *V) { @@ -2706,6 +2707,10 @@ // Make sure that the initial SchedulingRegionID is greater than the // initial SchedulingRegionID in ScheduleData (which is 0). int SchedulingRegionID = 1; + + /// Indicates that no CallInst found in the tree and we don't need to + /// calculate spill cost. + bool NoCalls = true; }; /// Attaches the BlockScheduling structures to basic blocks. @@ -5569,10 +5574,13 @@ } // Debug information does not impact spill cost. - if ((isa(&*PrevInstIt) && - !isa(&*PrevInstIt)) && - &*PrevInstIt != PrevInst) - NumCalls++; + if (isa(&*PrevInstIt)) { + auto *II = dyn_cast(&*PrevInstIt); + if (!isa(&*PrevInstIt) && + !(&*PrevInstIt)->isLifetimeStartOrEnd() && + (!II || !II->isAssumeLikeIntrinsic())) + NumCalls++; + } ++PrevInstIt; } @@ -5736,7 +5744,13 @@ } } - InstructionCost SpillCost = getSpillCost(); + bool NoCallInst = all_of(BlocksSchedules, + [](const decltype(BlocksSchedules)::value_type &BS) { + return BS.second->NoCalls; + }); + + InstructionCost SpillCost = NoCallInst ? 0 : getSpillCost(); + assert((!NoCallInst || getSpillCost() == 0) && "Incorrect spill cost"); Cost += SpillCost + ExtractCost; if (FirstUsers.size() == 1) { int Limit = ShuffleMask.front().size() * 2; @@ -7472,6 +7486,12 @@ } CurrentLoadStore = SD; } + if (isa(I)) { + auto *II = dyn_cast(I); + if (!isa(I) && !I->isLifetimeStartOrEnd() && + (!II || !II->isAssumeLikeIntrinsic())) + NoCalls = false; + } } if (NextLoadStore) { if (CurrentLoadStore)