diff options
-rw-r--r-- | llvm/include/llvm/Analysis/MemorySSA.h | 6 | ||||
-rw-r--r-- | llvm/unittests/Analysis/MemorySSA.cpp | 48 |
2 files changed, 52 insertions, 2 deletions
diff --git a/llvm/include/llvm/Analysis/MemorySSA.h b/llvm/include/llvm/Analysis/MemorySSA.h index 93911b7407f..2194e8b10f6 100644 --- a/llvm/include/llvm/Analysis/MemorySSA.h +++ b/llvm/include/llvm/Analysis/MemorySSA.h @@ -381,7 +381,9 @@ public: OptimizedID = getDefiningAccess()->getID(); } - MemoryAccess *getOptimized() const { return Optimized; } + MemoryAccess *getOptimized() const { + return cast_or_null<MemoryAccess>(Optimized); + } bool isOptimized() const { return getOptimized() && getDefiningAccess() && @@ -401,7 +403,7 @@ private: const unsigned ID; unsigned OptimizedID = INVALID_MEMORYACCESS_ID; - MemoryAccess *Optimized = nullptr; + WeakVH Optimized; }; template <> diff --git a/llvm/unittests/Analysis/MemorySSA.cpp b/llvm/unittests/Analysis/MemorySSA.cpp index 326a62efb44..b255b403914 100644 --- a/llvm/unittests/Analysis/MemorySSA.cpp +++ b/llvm/unittests/Analysis/MemorySSA.cpp @@ -951,3 +951,51 @@ TEST_F(MemorySSATest, MoveToBeforeLiveOnEntryInvalidatesCache) { MSSA.getLiveOnEntryDef()) << "(DefA = " << DefA << ")"; } + +TEST_F(MemorySSATest, RemovingDefInvalidatesCache) { + // Create: + // %x = alloca i8 + // %y = alloca i8 + // ; 1 = MemoryDef(liveOnEntry) + // store i8 0, i8* %x + // ; 2 = MemoryDef(1) + // store i8 0, i8* %y + // ; 3 = MemoryDef(2) + // store i8 0, i8* %x + // + // And be sure that MSSA's caching handles the removal of def `1` + // appropriately. + IRBuilder<> B(C); + F = Function::Create( + FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false), + GlobalValue::ExternalLinkage, "F", &M); + + BasicBlock *Entry = BasicBlock::Create(C, "if", F); + B.SetInsertPoint(Entry); + + Value *X = B.CreateAlloca(B.getInt8Ty()); + Value *Y = B.CreateAlloca(B.getInt8Ty()); + StoreInst *StoreX1 = B.CreateStore(B.getInt8(0), X); + StoreInst *StoreY = B.CreateStore(B.getInt8(0), Y); + StoreInst *StoreX2 = B.CreateStore(B.getInt8(0), X); + + setupAnalyses(); + + MemorySSA &MSSA = *Analyses->MSSA; + + auto *DefX1 = cast<MemoryDef>(MSSA.getMemoryAccess(StoreX1)); + auto *DefY = cast<MemoryDef>(MSSA.getMemoryAccess(StoreY)); + auto *DefX2 = cast<MemoryDef>(MSSA.getMemoryAccess(StoreX2)); + + EXPECT_EQ(DefX2->getDefiningAccess(), DefY); + MemoryAccess *X2Clobber = MSSA.getWalker()->getClobberingMemoryAccess(DefX2); + ASSERT_EQ(DefX1, X2Clobber); + + MemorySSAUpdater(&MSSA).removeMemoryAccess(DefX1); + StoreX1->eraseFromParent(); + + EXPECT_EQ(DefX2->getDefiningAccess(), DefY); + EXPECT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(DefX2), + MSSA.getLiveOnEntryDef()) + << "(DefX1 = " << DefX1 << ")"; +} |