Index: include/llvm/Analysis/MemorySSAUpdater.h =================================================================== --- include/llvm/Analysis/MemorySSAUpdater.h +++ include/llvm/Analysis/MemorySSAUpdater.h @@ -198,6 +198,12 @@ /// deleted after this call. void removeBlocks(const SmallPtrSetImpl &DeadBlocks); + /// Reset optimized for uses of a given instruction, if those uses have + /// MemoryAccesses. This should be called when the instruction is about to be + /// replaced, since its replacement may change the clobber (e.g., simplify to + /// undef). + void resetOptimizeUses(const Instruction *I); + /// Get handle on MemorySSA. MemorySSA* getMemorySSA() const { return MSSA; } Index: lib/Analysis/MemorySSAUpdater.cpp =================================================================== --- lib/Analysis/MemorySSAUpdater.cpp +++ lib/Analysis/MemorySSAUpdater.cpp @@ -607,6 +607,25 @@ } } +void MemorySSAUpdater::resetOptimizeUses(const Instruction *I) { + SmallVector Worklist; + for (const auto *Usr : I->users()) + if (auto *UsrI = dyn_cast(Usr)) + Worklist.push_back(UsrI); + + for (unsigned It = 0; It < Worklist.size(); ++It) { + if (auto *MA = MSSA->getMemoryAccess(Worklist[It])) { + auto *MUD = cast(MA); + if (MUD->isOptimized()) + MUD->resetOptimized(); + } else { + for (const auto *Usr : Worklist[It]->users()) + if (auto *UsrI = dyn_cast(Usr)) + Worklist.push_back(UsrI); + } + } +} + MemoryAccess *MemorySSAUpdater::createMemoryAccessInBB( Instruction *I, MemoryAccess *Definition, const BasicBlock *BB, MemorySSA::InsertionPlace Point) {