Index: llvm/trunk/include/llvm/Analysis/MemorySSA.h =================================================================== --- llvm/trunk/include/llvm/Analysis/MemorySSA.h +++ llvm/trunk/include/llvm/Analysis/MemorySSA.h @@ -793,6 +793,7 @@ friend class MemorySSAPrinterLegacyPass; friend class MemorySSAUpdater; + void verifyPrevDefInPhis(Function &F) const; void verifyDefUses(Function &F) const; void verifyDomination(Function &F) const; void verifyOrdering(Function &F) const; Index: llvm/trunk/lib/Analysis/MemorySSA.cpp =================================================================== --- llvm/trunk/lib/Analysis/MemorySSA.cpp +++ llvm/trunk/lib/Analysis/MemorySSA.cpp @@ -49,6 +49,7 @@ #include "llvm/Support/raw_ostream.h" #include #include +#include #include #include #include @@ -1852,6 +1853,7 @@ verifyDomination(F); verifyOrdering(F); verifyDominationNumbers(F); + verifyPrevDefInPhis(F); // Previously, the verification used to also verify that the clobberingAccess // cached by MemorySSA is the same as the clobberingAccess found at a later // query to AA. This does not hold true in general due to the current fragility @@ -1864,6 +1866,46 @@ // example, see test4 added in D51960. } +void MemorySSA::verifyPrevDefInPhis(Function &F) const { +#ifndef NDEBUG + for (const BasicBlock &BB : F) { + if (MemoryPhi *Phi = getMemoryAccess(&BB)) { + for (unsigned I = 0, E = Phi->getNumIncomingValues(); I != E; ++I) { + auto *Pred = Phi->getIncomingBlock(I); + auto *IncAcc = Phi->getIncomingValue(I); + // If Pred has no unreachable predecessors, get last def looking at + // IDoms. If, while walkings IDoms, any of these has an unreachable + // predecessor, then the expected incoming def is LoE. + if (auto *DTNode = DT->getNode(Pred)) { + while (DTNode) { + if (auto *DefList = getBlockDefs(DTNode->getBlock())) { + auto *LastAcc = &*(--DefList->end()); + assert(LastAcc == IncAcc && + "Incorrect incoming access into phi."); + break; + } + DTNode = DTNode->getIDom(); + } + assert((DTNode || IncAcc == getLiveOnEntryDef()) && + "Expected LoE inc"); + } else if (auto *DefList = getBlockDefs(Pred)) { + // If Pred has unreachable predecessors, but has at least a Def, the + // incoming access can be the last Def in Pred, or it could have been + // optimized to LoE. + auto *LastAcc = &*(--DefList->end()); + assert((LastAcc == IncAcc || IncAcc == getLiveOnEntryDef()) && + "Incorrect incoming access into phi."); + } else { + // If Pred has unreachable predecessors and no Defs, incoming access + // should be LoE. + assert(IncAcc == getLiveOnEntryDef() && "Expected LoE inc"); + } + } + } + } +#endif +} + /// Verify that all of the blocks we believe to have valid domination numbers /// actually have valid domination numbers. void MemorySSA::verifyDominationNumbers(const Function &F) const { Index: llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp =================================================================== --- llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp +++ llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp @@ -1074,7 +1074,7 @@ // Now reinsert it into the IR and do whatever fixups needed. if (auto *MD = dyn_cast(What)) - insertDef(MD); + insertDef(MD, true); else insertUse(cast(What)); Index: llvm/trunk/test/Analysis/MemorySSA/unreachable.ll =================================================================== --- llvm/trunk/test/Analysis/MemorySSA/unreachable.ll +++ llvm/trunk/test/Analysis/MemorySSA/unreachable.ll @@ -0,0 +1,31 @@ +; RUN: opt -licm -enable-mssa-loop-dependency -verify-memoryssa %s -S | FileCheck %s +; REQUIRES: asserts +; Ensure verification doesn't fail with unreachable blocks. + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-grtev4-linux-gnu" + +declare dso_local void @f() + +; CHECK-LABEL: @foo +define dso_local void @foo() { +entry: + br i1 undef, label %if.then, label %if.end + +if.then: ; preds = %entry + br label %try.cont + +if.end: ; preds = %entry +; 1 = MemoryDef(liveOnEntry) + call void @f() + br label %try.cont + +catch: ; No predecessors! +; 2 = MemoryDef(liveOnEntry) + call void @f() + br label %try.cont + +try.cont: ; preds = %if.end, %catch, %if.then +; 3 = MemoryPhi({if.then,liveOnEntry},{if.end,1},{catch,liveOnEntry}) + ret void +}