summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Analysis/MemorySSAUpdater.h2
-rw-r--r--llvm/lib/Analysis/MemorySSAUpdater.cpp17
-rw-r--r--llvm/test/Transforms/GVNHoist/non-trivial-phi.ll34
3 files changed, 53 insertions, 0 deletions
diff --git a/llvm/include/llvm/Analysis/MemorySSAUpdater.h b/llvm/include/llvm/Analysis/MemorySSAUpdater.h
index 3f4ef0614ca..1fbffb2b16e 100644
--- a/llvm/include/llvm/Analysis/MemorySSAUpdater.h
+++ b/llvm/include/llvm/Analysis/MemorySSAUpdater.h
@@ -33,6 +33,7 @@
#define LLVM_ANALYSIS_MEMORYSSAUPDATER_H
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/IR/BasicBlock.h"
@@ -61,6 +62,7 @@ private:
MemorySSA *MSSA;
SmallVector<MemoryPhi *, 8> InsertedPHIs;
SmallPtrSet<BasicBlock *, 8> VisitedBlocks;
+ SmallSet<AssertingVH<MemoryPhi>, 8> NonOptPhis;
public:
MemorySSAUpdater(MemorySSA *MSSA) : MSSA(MSSA) {}
diff --git a/llvm/lib/Analysis/MemorySSAUpdater.cpp b/llvm/lib/Analysis/MemorySSAUpdater.cpp
index 0d1e6471e98..57b9cc98a43 100644
--- a/llvm/lib/Analysis/MemorySSAUpdater.cpp
+++ b/llvm/lib/Analysis/MemorySSAUpdater.cpp
@@ -180,6 +180,10 @@ MemoryAccess *MemorySSAUpdater::recursePhi(MemoryAccess *Phi) {
template <class RangeType>
MemoryAccess *MemorySSAUpdater::tryRemoveTrivialPhi(MemoryPhi *Phi,
RangeType &Operands) {
+ // Bail out on non-opt Phis.
+ if (NonOptPhis.count(Phi))
+ return Phi;
+
// Detect equal or self arguments
MemoryAccess *Same = nullptr;
for (auto &Op : Operands) {
@@ -320,6 +324,10 @@ void MemorySSAUpdater::fixupDefs(const SmallVectorImpl<MemoryAccess *> &Vars) {
auto *Defs = MSSA->getWritableBlockDefs(NewDef->getBlock());
auto DefIter = NewDef->getDefsIterator();
+ // The temporary Phi is being fixed, unmark it for not to optimize.
+ if (MemoryPhi *Phi = dyn_cast_or_null<MemoryPhi>(NewDef))
+ NonOptPhis.erase(Phi);
+
// If there is a local def after us, we only have to rename that.
if (++DefIter != Defs->end()) {
cast<MemoryDef>(DefIter)->setDefiningAccess(NewDef);
@@ -379,6 +387,11 @@ void MemorySSAUpdater::fixupDefs(const SmallVectorImpl<MemoryAccess *> &Vars) {
template <class WhereType>
void MemorySSAUpdater::moveTo(MemoryUseOrDef *What, BasicBlock *BB,
WhereType Where) {
+ // Mark MemoryPhi users of What not to be optimized.
+ for (auto *U : What->users())
+ if (MemoryPhi *PhiUser = dyn_cast_or_null<MemoryPhi>(U))
+ NonOptPhis.insert(PhiUser);
+
// Replace all our users with our defining access.
What->replaceAllUsesWith(What->getDefiningAccess());
@@ -390,6 +403,10 @@ void MemorySSAUpdater::moveTo(MemoryUseOrDef *What, BasicBlock *BB,
insertDef(MD);
else
insertUse(cast<MemoryUse>(What));
+
+ // Clear dangling pointers. We added all MemoryPhi users, but not all
+ // of them are removed by fixupDefs().
+ NonOptPhis.clear();
}
// Move What before Where in the MemorySSA IR.
diff --git a/llvm/test/Transforms/GVNHoist/non-trivial-phi.ll b/llvm/test/Transforms/GVNHoist/non-trivial-phi.ll
new file mode 100644
index 00000000000..f77ad1bf680
--- /dev/null
+++ b/llvm/test/Transforms/GVNHoist/non-trivial-phi.ll
@@ -0,0 +1,34 @@
+; RUN: opt -gvn-hoist %s -S -o - | FileCheck %s
+
+; CHECK: store
+; CHECK-NOT: store
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+
+define void @f(i8* %p) {
+entry:
+ switch i4 undef, label %if.then30 [
+ i4 4, label %if.end
+ i4 0, label %if.end
+ ]
+
+if.end:
+ br label %if.end19
+
+if.end19:
+ br i1 undef, label %e, label %e.thread
+
+e.thread:
+ store i8 0, i8* %p, align 4
+ br label %if.then30
+
+if.then30:
+ call void @g()
+ unreachable
+
+e:
+ store i8 0, i8* %p, align 4
+ unreachable
+}
+
+declare void @g()
OpenPOWER on IntegriCloud