Page MenuHomePhabricator

D63354.diff
No OneTemporary

File Metadata

Created
Tue, Aug 20, 4:38 AM

D63354.diff

Index: llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp
===================================================================
--- llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp
+++ llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp
@@ -866,7 +866,6 @@
for (auto *BB : NewBlocks)
PredMap.erase(BB);
- SmallVector<BasicBlock *, 8> BlocksToProcess;
SmallVector<BasicBlock *, 16> BlocksWithDefsToReplace;
SmallVector<WeakVH, 8> InsertedPhis;
@@ -942,10 +941,6 @@
for (auto *Pred : PrevBlockSet)
for (int I = 0, E = EdgeCountMap[{Pred, BB}]; I < E; ++I)
NewPhi->addIncoming(DefP1, Pred);
-
- // Insert BB in the set of blocks that now have definition. We'll use this
- // to compute IDF and add Phis there next.
- BlocksToProcess.push_back(BB);
}
// Get all blocks that used to dominate BB and no longer do after adding
@@ -960,6 +955,14 @@
GetNoLongerDomBlocks(PrevIDom, NewIDom, BlocksWithDefsToReplace);
}
+ tryRemoveTrivialPhis(InsertedPhis);
+ // Create the set of blocks that now have a definition. We'll use this to
+ // compute IDF and add Phis there next.
+ SmallVector<BasicBlock *, 8> BlocksToProcess;
+ for (auto &VH : InsertedPhis)
+ if (auto *MPhi = cast_or_null<MemoryPhi>(VH))
+ BlocksToProcess.push_back(MPhi->getBlock());
+
// Compute IDF and add Phis in all IDF blocks that do not have one.
SmallVector<BasicBlock *, 32> IDFBlocks;
if (!BlocksToProcess.empty()) {
Index: llvm/trunk/test/Analysis/MemorySSA/simple_loop_unswitch_nontrivial.ll
===================================================================
--- llvm/trunk/test/Analysis/MemorySSA/simple_loop_unswitch_nontrivial.ll
+++ llvm/trunk/test/Analysis/MemorySSA/simple_loop_unswitch_nontrivial.ll
@@ -0,0 +1,113 @@
+; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -verify-memoryssa -S %s | FileCheck %s
+; REQUIRES: asserts
+
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @foo()
+
+; In Test1, there are no definitions. MemorySSA updates insert trivial phis and remove them.
+; Verify all are removed, considering the SLU pass leaves unreachable blocks hanging when the MSSA updates are done.
+; CHECK-LABEL: @Test1
+define void @Test1(i32) {
+header:
+ br label %outer
+
+outer.loopexit.split: ; preds = %continue
+ br label %outer.loopexit
+
+outer.loopexit: ; preds = %outer.loopexit.split.us, %outer.loopexit.split
+ br label %outer
+
+outer: ; preds = %outer.loopexit, %header
+ br i1 false, label %outer.split.us, label %outer.split
+
+outer.split.us: ; preds = %outer
+ br label %inner.us
+
+inner.us: ; preds = %continue.us, %outer.split.us
+ br label %overflow.us
+
+overflow.us: ; preds = %inner.us
+ br label %continue.us
+
+continue.us: ; preds = %overflow.us
+ br i1 true, label %outer.loopexit.split.us, label %inner.us
+
+outer.loopexit.split.us: ; preds = %continue.us
+ br label %outer.loopexit
+
+outer.split: ; preds = %outer
+ br label %inner
+
+inner: ; preds = %continue, %outer.split
+ br label %switchme
+
+switchme: ; preds = %inner
+ switch i32 %0, label %continue [
+ i32 88, label %go_out
+ i32 99, label %case2
+ ]
+
+case2: ; preds = %switchme
+ br label %continue
+
+continue: ; preds = %case2, %switchme
+ br i1 true, label %outer.loopexit.split, label %inner
+
+go_out: ; preds = %switchme
+ unreachable
+}
+
+; In Test2 there is a single def (call to foo). There are already Phis in place that are cloned when unswitching.
+; Ensure MemorySSA remains correct. Due to SLU's pruned cloning, continue.us2 becomes unreachable, with an empty Phi that is later cleaned.
+; CHECK-LABEL: @Test2
+define void @Test2(i32) {
+header:
+ br label %outer
+
+outer.loopexit.split: ; preds = %continue
+ br label %outer.loopexit
+
+outer.loopexit: ; preds = %outer.loopexit.split.us, %outer.loopexit.split
+ br label %outer
+
+outer: ; preds = %outer.loopexit, %header
+ br i1 false, label %outer.split.us, label %outer.split
+
+outer.split.us: ; preds = %outer
+ br label %inner.us
+
+inner.us: ; preds = %continue.us, %outer.split.us
+ br label %overflow.us
+
+overflow.us: ; preds = %inner.us
+ br label %continue.us
+
+continue.us: ; preds = %overflow.us
+ br i1 true, label %outer.loopexit.split.us, label %inner.us
+
+outer.loopexit.split.us: ; preds = %continue.us
+ br label %outer.loopexit
+
+outer.split: ; preds = %outer
+ br label %inner
+
+inner: ; preds = %continue, %outer.split
+ br label %switchme
+
+switchme: ; preds = %inner
+ switch i32 %0, label %continue [
+ i32 88, label %go_out
+ i32 99, label %case2
+ ]
+
+case2: ; preds = %switchme
+ call void @foo()
+ br label %continue
+
+continue: ; preds = %case2, %switchme
+ br i1 true, label %outer.loopexit.split, label %inner
+
+go_out: ; preds = %switchme
+ unreachable
+}

Event Timeline