diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -295,6 +295,31 @@ I->eraseFromParent(); } +namespace { +class ExpandedValuesCleaner { + SCEVExpander &Expander; + TargetLibraryInfo *TLI; + SmallVector ExpandedValues; + bool Commit = false; + +public: + ExpandedValuesCleaner(SCEVExpander &Expander, TargetLibraryInfo *TLI) + : Expander(Expander), TLI(TLI) {} + + void add(Value *V) { ExpandedValues.push_back(V); } + + void commit() { Commit = true; } + + ~ExpandedValuesCleaner() { + if (!Commit) { + Expander.clear(); + for (auto *V : ExpandedValues) + RecursivelyDeleteTriviallyDeadInstructions(V, TLI); + } + } +}; +} // namespace + //===----------------------------------------------------------------------===// // // Implementation of LoopIdiomRecognize @@ -908,6 +933,7 @@ BasicBlock *Preheader = CurLoop->getLoopPreheader(); IRBuilder<> Builder(Preheader->getTerminator()); SCEVExpander Expander(*SE, *DL, "loop-idiom"); + ExpandedValuesCleaner EVC(Expander, TLI); Type *DestInt8PtrTy = Builder.getInt8PtrTy(DestAS); Type *IntIdxTy = DL->getIndexType(DestPtr->getType()); @@ -930,6 +956,7 @@ // base pointer and checking the region. Value *BasePtr = Expander.expandCodeFor(Start, DestInt8PtrTy, Preheader->getTerminator()); + EVC.add(BasePtr); // From here on out, conservatively report to the pass manager that we've // changed the IR, even if we later clean up these added instructions. There @@ -941,12 +968,8 @@ Changed = true; if (mayLoopAccessLocation(BasePtr, ModRefInfo::ModRef, CurLoop, BECount, - StoreSize, *AA, Stores)) { - Expander.clear(); - // If we generated new code for the base pointer, clean up. - RecursivelyDeleteTriviallyDeadInstructions(BasePtr, TLI); + StoreSize, *AA, Stores)) return Changed; - } if (avoidLIRForMultiBlockLoop(/*IsMemset=*/true, IsLoopMemset)) return Changed; @@ -1018,34 +1041,10 @@ if (MSSAU && VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); ++NumMemSet; + EVC.commit(); return true; } -namespace { -class ExpandedValuesCleaner { - SCEVExpander &Expander; - TargetLibraryInfo *TLI; - SmallVector ExpandedValues; - bool Commit = false; - -public: - ExpandedValuesCleaner(SCEVExpander &Expander, TargetLibraryInfo *TLI) - : Expander(Expander), TLI(TLI) {} - - void add(Value *V) { ExpandedValues.push_back(V); } - - void commit() { Commit = true; } - - ~ExpandedValuesCleaner() { - if (!Commit) { - Expander.clear(); - for (auto *V : ExpandedValues) - RecursivelyDeleteTriviallyDeadInstructions(V, TLI); - } - } -}; -} // namespace - /// If the stored value is a strided load in the same loop with the same stride /// this may be transformable into a memcpy. This kicks in for stuff like /// for (i) A[i] = B[i];