Index: include/llvm/Analysis/MemorySSA.h =================================================================== --- include/llvm/Analysis/MemorySSA.h +++ include/llvm/Analysis/MemorySSA.h @@ -774,6 +774,9 @@ /// all uses, uses appear in the right places). This is used by unit tests. void verifyMemorySSA() const; + /// Check clobber sanity for an access. + void checkClobberSanityAccess(const MemoryAccess *MA) const; + /// Used in various insertion functions to specify whether we are talking /// about the beginning or end of a block. enum InsertionPlace { Beginning, End }; @@ -788,6 +791,7 @@ void verifyDomination(Function &F) const; void verifyOrdering(Function &F) const; void verifyDominationNumbers(const Function &F) const; + void verifyClobberSanity(const Function &F) const; // This is used by the use optimizer and updater. AccessList *getWritableBlockAccesses(const BasicBlock *BB) const { Index: lib/Analysis/MemorySSA.cpp =================================================================== --- lib/Analysis/MemorySSA.cpp +++ lib/Analysis/MemorySSA.cpp @@ -377,13 +377,14 @@ /// \param Start The MemoryAccess that we want to walk from. /// \param ClobberAt A clobber for Start. /// \param StartLoc The MemoryLocation for Start. -/// \param MSSA The MemorySSA isntance that Start and ClobberAt belong to. +/// \param MSSA The MemorySSA instance that Start and ClobberAt belong to. /// \param Query The UpwardsMemoryQuery we used for our search. /// \param AA The AliasAnalysis we used for our search. -static void LLVM_ATTRIBUTE_UNUSED -checkClobberSanity(MemoryAccess *Start, MemoryAccess *ClobberAt, - const MemoryLocation &StartLoc, const MemorySSA &MSSA, - const UpwardsMemoryQuery &Query, AliasAnalysis &AA) { +static void checkClobberSanity(MemoryAccess *Start, MemoryAccess *ClobberAt, + const MemoryLocation &StartLoc, + const MemorySSA &MSSA, + const UpwardsMemoryQuery &Query, + AliasAnalysis &AA) { assert(MSSA.dominates(ClobberAt, Start) && "Clobber doesn't dominate start?"); if (MSSA.isLiveOnEntryDef(Start)) { @@ -429,6 +430,10 @@ // We should never hit liveOnEntry, unless it's the clobber. assert(!MSSA.isLiveOnEntryDef(MA) && "Hit liveOnEntry before clobber?"); + // If Start is a Def, skip self. + if (MA == Start) + continue; + if (auto *MD = dyn_cast(MA)) { (void)MD; assert(!instructionClobbersQuery(MD, MAP.second, Query.Inst, AA) @@ -1683,6 +1688,34 @@ verifyOrdering(F); verifyDominationNumbers(F); Walker->verify(this); + verifyClobberSanity(F); +} + +/// Check sanity of the clobbering instruction for access MA. +void MemorySSA::checkClobberSanityAccess(const MemoryAccess *MA) const { + if (const auto *MUD = dyn_cast(MA)) { + if (!MUD->isOptimized()) + return; + auto *I = MUD->getMemoryInst(); + auto Loc = MemoryLocation::getOrNone(I); + if (Loc == None) + return; + auto *Clobber = MUD->getOptimized(); + UpwardsMemoryQuery Q(I, MUD); + checkClobberSanity(const_cast(MUD), Clobber, *Loc, *this, Q, *AA); + } +} + +void MemorySSA::verifyClobberSanity(const Function &F) const { +#if !defined(NDEBUG) && defined(EXPENSIVE_CHECKS) + for (const BasicBlock &BB : F) { + const AccessList *Accesses = getBlockAccesses(&BB); + if (!Accesses) + continue; + for (const MemoryAccess &MA : *Accesses) + checkClobberSanityAccess(&MA); + } +#endif } /// Verify that all of the blocks we believe to have valid domination numbers