summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlina Sbirlea <asbirlea@google.com>2019-07-31 17:41:04 +0000
committerAlina Sbirlea <asbirlea@google.com>2019-07-31 17:41:04 +0000
commit63e97fa0b3e91eaee9ece2a2b50b568995e84fb8 (patch)
tree4343324b3896edf6ad15a127da9050d2888c161d
parentb206c3e3e4de860b28d7d1c306b56ee860bda371 (diff)
downloadbcm5719-llvm-63e97fa0b3e91eaee9ece2a2b50b568995e84fb8.tar.gz
bcm5719-llvm-63e97fa0b3e91eaee9ece2a2b50b568995e84fb8.zip
[MemorySSA] Add additional verification for phis.
Summary: Verify that the incoming defs into phis are the last defs from the respective incoming blocks. When moving blocks, insertDef must RenameUses. Adding this verification makes GVNHoist tests fail that uncovered this issue. Reviewers: george.burgess.iv Subscribers: jlebar, Prazek, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63147 llvm-svn: 367451
-rw-r--r--llvm/include/llvm/Analysis/MemorySSA.h1
-rw-r--r--llvm/lib/Analysis/MemorySSA.cpp42
-rw-r--r--llvm/lib/Analysis/MemorySSAUpdater.cpp2
-rw-r--r--llvm/test/Analysis/MemorySSA/unreachable.ll31
4 files changed, 75 insertions, 1 deletions
diff --git a/llvm/include/llvm/Analysis/MemorySSA.h b/llvm/include/llvm/Analysis/MemorySSA.h
index 282290b899b..e89bf26a723 100644
--- a/llvm/include/llvm/Analysis/MemorySSA.h
+++ b/llvm/include/llvm/Analysis/MemorySSA.h
@@ -793,6 +793,7 @@ protected:
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;
diff --git a/llvm/lib/Analysis/MemorySSA.cpp b/llvm/lib/Analysis/MemorySSA.cpp
index 5df56ddd8e3..ed4b6456232 100644
--- a/llvm/lib/Analysis/MemorySSA.cpp
+++ b/llvm/lib/Analysis/MemorySSA.cpp
@@ -49,6 +49,7 @@
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
+#include <cstdlib>
#include <iterator>
#include <memory>
#include <utility>
@@ -1852,6 +1853,7 @@ void MemorySSA::verifyMemorySSA() const {
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 @@ void MemorySSA::verifyMemorySSA() const {
// 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 {
diff --git a/llvm/lib/Analysis/MemorySSAUpdater.cpp b/llvm/lib/Analysis/MemorySSAUpdater.cpp
index 42bbe7483b2..7fea41a8a53 100644
--- a/llvm/lib/Analysis/MemorySSAUpdater.cpp
+++ b/llvm/lib/Analysis/MemorySSAUpdater.cpp
@@ -1074,7 +1074,7 @@ void MemorySSAUpdater::moveTo(MemoryUseOrDef *What, BasicBlock *BB,
// Now reinsert it into the IR and do whatever fixups needed.
if (auto *MD = dyn_cast<MemoryDef>(What))
- insertDef(MD);
+ insertDef(MD, true);
else
insertUse(cast<MemoryUse>(What));
diff --git a/llvm/test/Analysis/MemorySSA/unreachable.ll b/llvm/test/Analysis/MemorySSA/unreachable.ll
new file mode 100644
index 00000000000..6a936435373
--- /dev/null
+++ b/llvm/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
+}
OpenPOWER on IntegriCloud