[llvm] r348263 - Update MemorySSA in SimpleLoopUnswitch.

Alina Sbirlea via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 4 06:23:38 PST 2018


Author: asbirlea
Date: Tue Dec  4 06:23:37 2018
New Revision: 348263

URL: http://llvm.org/viewvc/llvm-project?rev=348263&view=rev
Log:
Update MemorySSA in SimpleLoopUnswitch.

Summary:
Teach SimpleLoopUnswitch to preserve MemorySSA.

Subscribers: sanjoy, jlebar, Prazek, george.burgess.iv, llvm-commits

Differential Revision: https://reviews.llvm.org/D47022

Modified:
    llvm/trunk/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2006-06-13-SingleEntryPHI.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2006-06-27-DeadSwitchCase.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-05-09-Unreachable.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-05-09-tl.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-12-ExitDomInfo.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-13-DomInfo.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-18-DomInfo.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-08-01-LCSSA.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2008-06-02-DomInfo.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2010-11-18-LCSSA.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2011-06-02-CritSwitch.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2011-09-26-EHCrash.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2012-04-02-IndirectBr.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2012-05-20-Phi.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/2015-09-18-Addrspace.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/basictest.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/cleanuppad.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/copy-metadata.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/crash.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/exponential-behavior.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/guards.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/infinite-loop.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/msan.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/pr37888.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/preserve-analyses.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-iteration.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
    llvm/trunk/test/Transforms/SimpleLoopUnswitch/update-scev.ll

Modified: llvm/trunk/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp Tue Dec  4 06:23:37 2018
@@ -25,6 +25,8 @@
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/LoopIterator.h"
 #include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/MemorySSA.h"
+#include "llvm/Analysis/MemorySSAUpdater.h"
 #include "llvm/Analysis/Utils/Local.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Constant.h"
@@ -349,7 +351,8 @@ static void hoistLoopToNewParent(Loop &L
 /// If `SE` is not null, it will be updated based on the potential loop SCEVs
 /// invalidated by this.
 static bool unswitchTrivialBranch(Loop &L, BranchInst &BI, DominatorTree &DT,
-                                  LoopInfo &LI, ScalarEvolution *SE) {
+                                  LoopInfo &LI, ScalarEvolution *SE,
+                                  MemorySSAUpdater *MSSAU) {
   assert(BI.isConditional() && "Can only unswitch a conditional branch!");
   LLVM_DEBUG(dbgs() << "  Trying to unswitch branch: " << BI << "\n");
 
@@ -423,11 +426,14 @@ static bool unswitchTrivialBranch(Loop &
       SE->forgetTopmostLoop(&L);
   }
 
+  if (MSSAU && VerifyMemorySSA)
+    MSSAU->getMemorySSA()->verifyMemorySSA();
+
   // Split the preheader, so that we know that there is a safe place to insert
   // the conditional branch. We will change the preheader to have a conditional
   // branch on LoopCond.
   BasicBlock *OldPH = L.getLoopPreheader();
-  BasicBlock *NewPH = SplitEdge(OldPH, L.getHeader(), &DT, &LI);
+  BasicBlock *NewPH = SplitEdge(OldPH, L.getHeader(), &DT, &LI, MSSAU);
 
   // Now that we have a place to insert the conditional branch, create a place
   // to branch to: this is the exit block out of the loop that we are
@@ -439,9 +445,13 @@ static bool unswitchTrivialBranch(Loop &
            "A branch's parent isn't a predecessor!");
     UnswitchedBB = LoopExitBB;
   } else {
-    UnswitchedBB = SplitBlock(LoopExitBB, &LoopExitBB->front(), &DT, &LI);
+    UnswitchedBB =
+        SplitBlock(LoopExitBB, &LoopExitBB->front(), &DT, &LI, MSSAU);
   }
 
+  if (MSSAU && VerifyMemorySSA)
+    MSSAU->getMemorySSA()->verifyMemorySSA();
+
   // Actually move the invariant uses into the unswitched position. If possible,
   // we do this by moving the instructions, but when doing partial unswitching
   // we do it by building a new merge of the values in the unswitched position.
@@ -452,12 +462,17 @@ static bool unswitchTrivialBranch(Loop &
     // its successors.
     OldPH->getInstList().splice(OldPH->end(), BI.getParent()->getInstList(),
                                 BI);
+    if (MSSAU) {
+      // Temporarily clone the terminator, to make MSSA update cheaper by
+      // separating "insert edge" updates from "remove edge" ones.
+      ParentBB->getInstList().push_back(BI.clone());
+    } else {
+      // Create a new unconditional branch that will continue the loop as a new
+      // terminator.
+      BranchInst::Create(ContinueBB, ParentBB);
+    }
     BI.setSuccessor(LoopExitSuccIdx, UnswitchedBB);
     BI.setSuccessor(1 - LoopExitSuccIdx, NewPH);
-
-    // Create a new unconditional branch that will continue the loop as a new
-    // terminator.
-    BranchInst::Create(ContinueBB, ParentBB);
   } else {
     // Only unswitching a subset of inputs to the condition, so we will need to
     // build a new branch that merges the invariant inputs.
@@ -473,6 +488,32 @@ static bool unswitchTrivialBranch(Loop &
                                           *UnswitchedBB, *NewPH);
   }
 
+  // Update the dominator tree with the added edge.
+  DT.insertEdge(OldPH, UnswitchedBB);
+
+  // After the dominator tree was updated with the added edge, update MemorySSA
+  // if available.
+  if (MSSAU) {
+    SmallVector<CFGUpdate, 1> Updates;
+    Updates.push_back({cfg::UpdateKind::Insert, OldPH, UnswitchedBB});
+    MSSAU->applyInsertUpdates(Updates, DT);
+  }
+
+  // Finish updating dominator tree and memory ssa for full unswitch.
+  if (FullUnswitch) {
+    if (MSSAU) {
+      // Remove the cloned branch instruction.
+      ParentBB->getTerminator()->eraseFromParent();
+      // Create unconditional branch now.
+      BranchInst::Create(ContinueBB, ParentBB);
+      MSSAU->removeEdge(ParentBB, LoopExitBB);
+    }
+    DT.deleteEdge(ParentBB, LoopExitBB);
+  }
+
+  if (MSSAU && VerifyMemorySSA)
+    MSSAU->getMemorySSA()->verifyMemorySSA();
+
   // Rewrite the relevant PHI nodes.
   if (UnswitchedBB == LoopExitBB)
     rewritePHINodesForUnswitchedExitBlock(*UnswitchedBB, *ParentBB, *OldPH);
@@ -480,13 +521,6 @@ static bool unswitchTrivialBranch(Loop &
     rewritePHINodesForExitAndUnswitchedBlocks(*LoopExitBB, *UnswitchedBB,
                                               *ParentBB, *OldPH, FullUnswitch);
 
-  // Now we need to update the dominator tree.
-  SmallVector<DominatorTree::UpdateType, 2> DTUpdates;
-  DTUpdates.push_back({DT.Insert, OldPH, UnswitchedBB});
-  if (FullUnswitch)
-    DTUpdates.push_back({DT.Delete, ParentBB, LoopExitBB});
-  DT.applyUpdates(DTUpdates);
-
   // The constant we can replace all of our invariants with inside the loop
   // body. If any of the invariants have a value other than this the loop won't
   // be entered.
@@ -537,7 +571,8 @@ static bool unswitchTrivialBranch(Loop &
 /// If `SE` is not null, it will be updated based on the potential loop SCEVs
 /// invalidated by this.
 static bool unswitchTrivialSwitch(Loop &L, SwitchInst &SI, DominatorTree &DT,
-                                  LoopInfo &LI, ScalarEvolution *SE) {
+                                  LoopInfo &LI, ScalarEvolution *SE,
+                                  MemorySSAUpdater *MSSAU) {
   LLVM_DEBUG(dbgs() << "  Trying to unswitch switch: " << SI << "\n");
   Value *LoopCond = SI.getCondition();
 
@@ -564,6 +599,9 @@ static bool unswitchTrivialSwitch(Loop &
 
   LLVM_DEBUG(dbgs() << "    unswitching trivial switch...\n");
 
+  if (MSSAU && VerifyMemorySSA)
+    MSSAU->getMemorySSA()->verifyMemorySSA();
+
   // We may need to invalidate SCEVs for the outermost loop reached by any of
   // the exits.
   Loop *OuterL = &L;
@@ -626,7 +664,7 @@ static bool unswitchTrivialSwitch(Loop &
   // Split the preheader, so that we know that there is a safe place to insert
   // the switch.
   BasicBlock *OldPH = L.getLoopPreheader();
-  BasicBlock *NewPH = SplitEdge(OldPH, L.getHeader(), &DT, &LI);
+  BasicBlock *NewPH = SplitEdge(OldPH, L.getHeader(), &DT, &LI, MSSAU);
   OldPH->getTerminator()->eraseFromParent();
 
   // Now add the unswitched switch.
@@ -649,9 +687,10 @@ static bool unswitchTrivialSwitch(Loop &
       rewritePHINodesForUnswitchedExitBlock(*DefaultExitBB, *ParentBB, *OldPH);
     } else {
       auto *SplitBB =
-          SplitBlock(DefaultExitBB, &DefaultExitBB->front(), &DT, &LI);
-      rewritePHINodesForExitAndUnswitchedBlocks(
-          *DefaultExitBB, *SplitBB, *ParentBB, *OldPH, /*FullUnswitch*/ true);
+          SplitBlock(DefaultExitBB, &DefaultExitBB->front(), &DT, &LI, MSSAU);
+      rewritePHINodesForExitAndUnswitchedBlocks(*DefaultExitBB, *SplitBB,
+                                                *ParentBB, *OldPH,
+                                                /*FullUnswitch*/ true);
       DefaultExitBB = SplitExitBBMap[DefaultExitBB] = SplitBB;
     }
   }
@@ -675,9 +714,10 @@ static bool unswitchTrivialSwitch(Loop &
     BasicBlock *&SplitExitBB = SplitExitBBMap[ExitBB];
     if (!SplitExitBB) {
       // If this is the first time we see this, do the split and remember it.
-      SplitExitBB = SplitBlock(ExitBB, &ExitBB->front(), &DT, &LI);
-      rewritePHINodesForExitAndUnswitchedBlocks(
-          *ExitBB, *SplitExitBB, *ParentBB, *OldPH, /*FullUnswitch*/ true);
+      SplitExitBB = SplitBlock(ExitBB, &ExitBB->front(), &DT, &LI, MSSAU);
+      rewritePHINodesForExitAndUnswitchedBlocks(*ExitBB, *SplitExitBB,
+                                                *ParentBB, *OldPH,
+                                                /*FullUnswitch*/ true);
     }
     // Update the case pair to point to the split block.
     CasePair.second = SplitExitBB;
@@ -754,6 +794,13 @@ static bool unswitchTrivialSwitch(Loop &
     DTUpdates.push_back({DT.Insert, OldPH, UnswitchedBB});
   }
   DT.applyUpdates(DTUpdates);
+
+  if (MSSAU) {
+    MSSAU->applyUpdates(DTUpdates, DT);
+    if (VerifyMemorySSA)
+      MSSAU->getMemorySSA()->verifyMemorySSA();
+  }
+
   assert(DT.verify(DominatorTree::VerificationLevel::Fast));
 
   // We may have changed the nesting relationship for this loop so hoist it to
@@ -779,7 +826,8 @@ static bool unswitchTrivialSwitch(Loop &
 /// If `SE` is not null, it will be updated based on the potential loop SCEVs
 /// invalidated by this.
 static bool unswitchAllTrivialConditions(Loop &L, DominatorTree &DT,
-                                         LoopInfo &LI, ScalarEvolution *SE) {
+                                         LoopInfo &LI, ScalarEvolution *SE,
+                                         MemorySSAUpdater *MSSAU) {
   bool Changed = false;
 
   // If loop header has only one reachable successor we should keep looking for
@@ -813,7 +861,7 @@ static bool unswitchAllTrivialConditions
       if (isa<Constant>(SI->getCondition()))
         return Changed;
 
-      if (!unswitchTrivialSwitch(L, *SI, DT, LI, SE))
+      if (!unswitchTrivialSwitch(L, *SI, DT, LI, SE, MSSAU))
         // Couldn't unswitch this one so we're done.
         return Changed;
 
@@ -845,7 +893,7 @@ static bool unswitchAllTrivialConditions
 
     // Found a trivial condition candidate: non-foldable conditional branch. If
     // we fail to unswitch this, we can't do anything else that is trivial.
-    if (!unswitchTrivialBranch(L, *BI, DT, LI, SE))
+    if (!unswitchTrivialBranch(L, *BI, DT, LI, SE, MSSAU))
       return Changed;
 
     // Mark that we managed to unswitch something.
@@ -898,7 +946,7 @@ static BasicBlock *buildClonedLoopBlocks
     const SmallDenseMap<BasicBlock *, BasicBlock *, 16> &DominatingSucc,
     ValueToValueMapTy &VMap,
     SmallVectorImpl<DominatorTree::UpdateType> &DTUpdates, AssumptionCache &AC,
-    DominatorTree &DT, LoopInfo &LI) {
+    DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU) {
   SmallVector<BasicBlock *, 4> NewBlocks;
   NewBlocks.reserve(L.getNumBlocks() + ExitBlocks.size());
 
@@ -943,7 +991,7 @@ static BasicBlock *buildClonedLoopBlocks
     // place to merge the CFG, so split the exit first. This is always safe to
     // do because there cannot be any non-loop predecessors of a loop exit in
     // loop simplified form.
-    auto *MergeBB = SplitBlock(ExitBB, &ExitBB->front(), &DT, &LI);
+    auto *MergeBB = SplitBlock(ExitBB, &ExitBB->front(), &DT, &LI, MSSAU);
 
     // Rearrange the names to make it easier to write test cases by having the
     // exit block carry the suffix rather than the merge block carrying the
@@ -1374,7 +1422,7 @@ static void buildClonedLoops(Loop &OrigL
 static void
 deleteDeadClonedBlocks(Loop &L, ArrayRef<BasicBlock *> ExitBlocks,
                        ArrayRef<std::unique_ptr<ValueToValueMapTy>> VMaps,
-                       DominatorTree &DT) {
+                       DominatorTree &DT, MemorySSAUpdater *MSSAU) {
   // Find all the dead clones, and remove them from their successors.
   SmallVector<BasicBlock *, 16> DeadBlocks;
   for (BasicBlock *BB : llvm::concat<BasicBlock *const>(L.blocks(), ExitBlocks))
@@ -1386,6 +1434,13 @@ deleteDeadClonedBlocks(Loop &L, ArrayRef
           DeadBlocks.push_back(ClonedBB);
         }
 
+  // Remove all MemorySSA in the dead blocks
+  if (MSSAU) {
+    SmallPtrSet<BasicBlock *, 16> DeadBlockSet(DeadBlocks.begin(),
+                                               DeadBlocks.end());
+    MSSAU->removeBlocks(DeadBlockSet);
+  }
+
   // Drop any remaining references to break cycles.
   for (BasicBlock *BB : DeadBlocks)
     BB->dropAllReferences();
@@ -1394,10 +1449,10 @@ deleteDeadClonedBlocks(Loop &L, ArrayRef
     BB->eraseFromParent();
 }
 
-static void
-deleteDeadBlocksFromLoop(Loop &L,
-                         SmallVectorImpl<BasicBlock *> &ExitBlocks,
-                         DominatorTree &DT, LoopInfo &LI) {
+static void deleteDeadBlocksFromLoop(Loop &L,
+                                     SmallVectorImpl<BasicBlock *> &ExitBlocks,
+                                     DominatorTree &DT, LoopInfo &LI,
+                                     MemorySSAUpdater *MSSAU) {
   // Find all the dead blocks tied to this loop, and remove them from their
   // successors.
   SmallPtrSet<BasicBlock *, 16> DeadBlockSet;
@@ -1418,6 +1473,10 @@ deleteDeadBlocksFromLoop(Loop &L,
     }
   }
 
+  // Remove all MemorySSA in the dead blocks
+  if (MSSAU)
+    MSSAU->removeBlocks(DeadBlockSet);
+
   // Filter out the dead blocks from the exit blocks list so that it can be
   // used in the caller.
   llvm::erase_if(ExitBlocks,
@@ -1817,7 +1876,7 @@ static void unswitchNontrivialInvariants
     Loop &L, Instruction &TI, ArrayRef<Value *> Invariants,
     SmallVectorImpl<BasicBlock *> &ExitBlocks, DominatorTree &DT, LoopInfo &LI,
     AssumptionCache &AC, function_ref<void(bool, ArrayRef<Loop *>)> UnswitchCB,
-    ScalarEvolution *SE) {
+    ScalarEvolution *SE, MemorySSAUpdater *MSSAU) {
   auto *ParentBB = TI.getParent();
   BranchInst *BI = dyn_cast<BranchInst>(&TI);
   SwitchInst *SI = BI ? nullptr : cast<SwitchInst>(&TI);
@@ -1834,6 +1893,9 @@ static void unswitchNontrivialInvariants
     assert(isa<Instruction>(BI->getCondition()) &&
            "Partial unswitching requires an instruction as the condition!");
 
+  if (MSSAU && VerifyMemorySSA)
+    MSSAU->getMemorySSA()->verifyMemorySSA();
+
   // Constant and BBs tracking the cloned and continuing successor. When we are
   // unswitching the entire condition, this can just be trivially chosen to
   // unswitch towards `true`. However, when we are unswitching a set of
@@ -1874,6 +1936,10 @@ static void unswitchNontrivialInvariants
 
   // Compute the parent loop now before we start hacking on things.
   Loop *ParentL = L.getParentLoop();
+  // Get blocks in RPO order for MSSA update, before changing the CFG.
+  LoopBlocksRPO LBRPO(&L);
+  if (MSSAU)
+    LBRPO.perform(&LI);
 
   // Compute the outer-most loop containing one of our exit blocks. This is the
   // furthest up our loopnest which can be mutated, which we will use below to
@@ -1923,7 +1989,7 @@ static void unswitchNontrivialInvariants
   // between the unswitched versions, and we will have a new preheader for the
   // original loop.
   BasicBlock *SplitBB = L.getLoopPreheader();
-  BasicBlock *LoopPH = SplitEdge(SplitBB, L.getHeader(), &DT, &LI);
+  BasicBlock *LoopPH = SplitEdge(SplitBB, L.getHeader(), &DT, &LI, MSSAU);
 
   // Keep track of the dominator tree updates needed.
   SmallVector<DominatorTree::UpdateType, 4> DTUpdates;
@@ -1936,7 +2002,7 @@ static void unswitchNontrivialInvariants
     VMaps.emplace_back(new ValueToValueMapTy());
     ClonedPHs[SuccBB] = buildClonedLoopBlocks(
         L, LoopPH, SplitBB, ExitBlocks, ParentBB, SuccBB, RetainedSuccBB,
-        DominatingSucc, *VMaps.back(), DTUpdates, AC, DT, LI);
+        DominatingSucc, *VMaps.back(), DTUpdates, AC, DT, LI, MSSAU);
   }
 
   // The stitching of the branched code back together depends on whether we're
@@ -1944,7 +2010,63 @@ static void unswitchNontrivialInvariants
   // nuke the initial terminator placed in the split block.
   SplitBB->getTerminator()->eraseFromParent();
   if (FullUnswitch) {
-    // First we need to unhook the successor relationship as we'll be replacing
+    // Splice the terminator from the original loop and rewrite its
+    // successors.
+    SplitBB->getInstList().splice(SplitBB->end(), ParentBB->getInstList(), TI);
+
+    // Keep a clone of the terminator for MSSA updates.
+    Instruction *NewTI = TI.clone();
+    ParentBB->getInstList().push_back(NewTI);
+
+    // First wire up the moved terminator to the preheaders.
+    if (BI) {
+      BasicBlock *ClonedPH = ClonedPHs.begin()->second;
+      BI->setSuccessor(ClonedSucc, ClonedPH);
+      BI->setSuccessor(1 - ClonedSucc, LoopPH);
+      DTUpdates.push_back({DominatorTree::Insert, SplitBB, ClonedPH});
+    } else {
+      assert(SI && "Must either be a branch or switch!");
+
+      // Walk the cases and directly update their successors.
+      assert(SI->getDefaultDest() == RetainedSuccBB &&
+             "Not retaining default successor!");
+      SI->setDefaultDest(LoopPH);
+      for (auto &Case : SI->cases())
+        if (Case.getCaseSuccessor() == RetainedSuccBB)
+          Case.setSuccessor(LoopPH);
+        else
+          Case.setSuccessor(ClonedPHs.find(Case.getCaseSuccessor())->second);
+
+      // We need to use the set to populate domtree updates as even when there
+      // are multiple cases pointing at the same successor we only want to
+      // remove and insert one edge in the domtree.
+      for (BasicBlock *SuccBB : UnswitchedSuccBBs)
+        DTUpdates.push_back(
+            {DominatorTree::Insert, SplitBB, ClonedPHs.find(SuccBB)->second});
+    }
+
+    if (MSSAU) {
+      DT.applyUpdates(DTUpdates);
+      DTUpdates.clear();
+
+      // Remove all but one edge to the retained block and all unswitched
+      // blocks. This is to avoid having duplicate entries in the cloned Phis,
+      // when we know we only keep a single edge for each case.
+      MSSAU->removeDuplicatePhiEdgesBetween(ParentBB, RetainedSuccBB);
+      for (BasicBlock *SuccBB : UnswitchedSuccBBs)
+        MSSAU->removeDuplicatePhiEdgesBetween(ParentBB, SuccBB);
+
+      for (auto &VMap : VMaps)
+        MSSAU->updateForClonedLoop(LBRPO, ExitBlocks, *VMap,
+                                   /*IgnoreIncomingWithNoClones=*/true);
+      MSSAU->updateExitBlocksForClonedLoop(ExitBlocks, VMaps, DT);
+
+      // Remove all edges to unswitched blocks.
+      for (BasicBlock *SuccBB : UnswitchedSuccBBs)
+        MSSAU->removeEdge(ParentBB, SuccBB);
+    }
+
+    // Now unhook the successor relationship as we'll be replacing
     // the terminator with a direct branch. This is much simpler for branches
     // than switches so we handle those first.
     if (BI) {
@@ -1962,9 +2084,10 @@ static void unswitchNontrivialInvariants
       // is a duplicate edge to the retained successor as the retained successor
       // is always the default successor and as we'll replace this with a direct
       // branch we no longer need the duplicate entries in the PHI nodes.
-      assert(SI->getDefaultDest() == RetainedSuccBB &&
+      SwitchInst *NewSI = cast<SwitchInst>(NewTI);
+      assert(NewSI->getDefaultDest() == RetainedSuccBB &&
              "Not retaining default successor!");
-      for (auto &Case : SI->cases())
+      for (auto &Case : NewSI->cases())
         Case.getCaseSuccessor()->removePredecessor(
             ParentBB,
             /*DontDeleteUselessPHIs*/ true);
@@ -1976,34 +2099,8 @@ static void unswitchNontrivialInvariants
         DTUpdates.push_back({DominatorTree::Delete, ParentBB, SuccBB});
     }
 
-    // Now that we've unhooked the successor relationship, splice the terminator
-    // from the original loop to the split.
-    SplitBB->getInstList().splice(SplitBB->end(), ParentBB->getInstList(), TI);
-
-    // Now wire up the terminator to the preheaders.
-    if (BI) {
-      BasicBlock *ClonedPH = ClonedPHs.begin()->second;
-      BI->setSuccessor(ClonedSucc, ClonedPH);
-      BI->setSuccessor(1 - ClonedSucc, LoopPH);
-      DTUpdates.push_back({DominatorTree::Insert, SplitBB, ClonedPH});
-    } else {
-      assert(SI && "Must either be a branch or switch!");
-
-      // Walk the cases and directly update their successors.
-      SI->setDefaultDest(LoopPH);
-      for (auto &Case : SI->cases())
-        if (Case.getCaseSuccessor() == RetainedSuccBB)
-          Case.setSuccessor(LoopPH);
-        else
-          Case.setSuccessor(ClonedPHs.find(Case.getCaseSuccessor())->second);
-
-      // We need to use the set to populate domtree updates as even when there
-      // are multiple cases pointing at the same successor we only want to
-      // remove and insert one edge in the domtree.
-      for (BasicBlock *SuccBB : UnswitchedSuccBBs)
-        DTUpdates.push_back(
-            {DominatorTree::Insert, SplitBB, ClonedPHs.find(SuccBB)->second});
-    }
+    // After MSSAU update, remove the cloned terminator instruction NewTI.
+    ParentBB->getTerminator()->eraseFromParent();
 
     // Create a new unconditional branch to the continuing block (as opposed to
     // the one cloned).
@@ -2022,12 +2119,19 @@ static void unswitchNontrivialInvariants
 
   // Apply the updates accumulated above to get an up-to-date dominator tree.
   DT.applyUpdates(DTUpdates);
+  if (!FullUnswitch && MSSAU) {
+    // Update MSSA for partial unswitch, after DT update.
+    SmallVector<CFGUpdate, 1> Updates;
+    Updates.push_back(
+        {cfg::UpdateKind::Insert, SplitBB, ClonedPHs.begin()->second});
+    MSSAU->applyInsertUpdates(Updates, DT);
+  }
 
   // Now that we have an accurate dominator tree, first delete the dead cloned
   // blocks so that we can accurately build any cloned loops. It is important to
   // not delete the blocks from the original loop yet because we still want to
   // reference the original loop to understand the cloned loop's structure.
-  deleteDeadClonedBlocks(L, ExitBlocks, VMaps, DT);
+  deleteDeadClonedBlocks(L, ExitBlocks, VMaps, DT, MSSAU);
 
   // Build the cloned loop structure itself. This may be substantially
   // different from the original structure due to the simplified CFG. This also
@@ -2039,10 +2143,17 @@ static void unswitchNontrivialInvariants
   // Now that our cloned loops have been built, we can update the original loop.
   // First we delete the dead blocks from it and then we rebuild the loop
   // structure taking these deletions into account.
-  deleteDeadBlocksFromLoop(L, ExitBlocks, DT, LI);
+  deleteDeadBlocksFromLoop(L, ExitBlocks, DT, LI, MSSAU);
+
+  if (MSSAU && VerifyMemorySSA)
+    MSSAU->getMemorySSA()->verifyMemorySSA();
+
   SmallVector<Loop *, 4> HoistedLoops;
   bool IsStillLoop = rebuildLoopAfterUnswitch(L, ExitBlocks, LI, HoistedLoops);
 
+  if (MSSAU && VerifyMemorySSA)
+    MSSAU->getMemorySSA()->verifyMemorySSA();
+
   // This transformation has a high risk of corrupting the dominator tree, and
   // the below steps to rebuild loop structures will result in hard to debug
   // errors in that case so verify that the dominator tree is sane first.
@@ -2167,6 +2278,9 @@ static void unswitchNontrivialInvariants
       SibLoops.push_back(UpdatedL);
   UnswitchCB(IsStillLoop, SibLoops);
 
+  if (MSSAU && VerifyMemorySSA)
+    MSSAU->getMemorySSA()->verifyMemorySSA();
+
   ++NumBranches;
 }
 
@@ -2227,11 +2341,16 @@ computeDomSubtreeCost(DomTreeNode &N,
 static BranchInst *
 turnGuardIntoBranch(IntrinsicInst *GI, Loop &L,
                     SmallVectorImpl<BasicBlock *> &ExitBlocks,
-                    DominatorTree &DT, LoopInfo &LI) {
+                    DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU) {
   SmallVector<DominatorTree::UpdateType, 4> DTUpdates;
   LLVM_DEBUG(dbgs() << "Turning " << *GI << " into a branch.\n");
   BasicBlock *CheckBB = GI->getParent();
 
+  if (MSSAU && VerifyMemorySSA) {
+     MSSAU->getMemorySSA()->verifyMemorySSA();
+     MSSAU->getMemorySSA()->dump();
+  }
+
   // Remove all CheckBB's successors from DomTree. A block can be seen among
   // successors more than once, but for DomTree it should be added only once.
   SmallPtrSet<BasicBlock *, 4> Successors;
@@ -2249,10 +2368,14 @@ turnGuardIntoBranch(IntrinsicInst *GI, L
   BasicBlock *GuardedBlock = CheckBI->getSuccessor(0);
   GuardedBlock->setName("guarded");
   CheckBI->getSuccessor(1)->setName("deopt");
+  BasicBlock *DeoptBlock = CheckBI->getSuccessor(1);
 
   // We now have a new exit block.
   ExitBlocks.push_back(CheckBI->getSuccessor(1));
 
+  if (MSSAU)
+    MSSAU->moveAllAfterSpliceBlocks(CheckBB, GuardedBlock, GI);
+
   GI->moveBefore(DeoptBlockTerm);
   GI->setArgOperand(0, ConstantInt::getFalse(GI->getContext()));
 
@@ -2270,6 +2393,13 @@ turnGuardIntoBranch(IntrinsicInst *GI, L
   // Inform LI of a new loop block.
   L.addBasicBlockToLoop(GuardedBlock, LI);
 
+  if (MSSAU) {
+    MemoryDef *MD = cast<MemoryDef>(MSSAU->getMemorySSA()->getMemoryAccess(GI));
+    MSSAU->moveToPlace(MD, DeoptBlock, MemorySSA::End);
+    if (VerifyMemorySSA)
+      MSSAU->getMemorySSA()->verifyMemorySSA();
+  }
+
   ++NumGuards;
   return CheckBI;
 }
@@ -2363,7 +2493,7 @@ static bool
 unswitchBestCondition(Loop &L, DominatorTree &DT, LoopInfo &LI,
                       AssumptionCache &AC, TargetTransformInfo &TTI,
                       function_ref<void(bool, ArrayRef<Loop *>)> UnswitchCB,
-                      ScalarEvolution *SE) {
+                      ScalarEvolution *SE, MemorySSAUpdater *MSSAU) {
   // Collect all invariant conditions within this loop (as opposed to an inner
   // loop which would be handled when visiting that inner loop).
   SmallVector<std::pair<Instruction *, TinyPtrVector<Value *>>, 4>
@@ -2605,13 +2735,13 @@ unswitchBestCondition(Loop &L, Dominator
   // If the best candidate is a guard, turn it into a branch.
   if (isGuard(BestUnswitchTI))
     BestUnswitchTI = turnGuardIntoBranch(cast<IntrinsicInst>(BestUnswitchTI), L,
-                                         ExitBlocks, DT, LI);
+                                         ExitBlocks, DT, LI, MSSAU);
 
   LLVM_DEBUG(dbgs() << "  Unswitching non-trivial (cost = "
                     << BestUnswitchCost << ") terminator: " << *BestUnswitchTI
                     << "\n");
   unswitchNontrivialInvariants(L, *BestUnswitchTI, BestUnswitchInvariants,
-                               ExitBlocks, DT, LI, AC, UnswitchCB, SE);
+                               ExitBlocks, DT, LI, AC, UnswitchCB, SE, MSSAU);
   return true;
 }
 
@@ -2624,6 +2754,7 @@ unswitchBestCondition(Loop &L, Dominator
 ///
 /// The `DT`, `LI`, `AC`, `TTI` parameters are required analyses that are also
 /// updated based on the unswitch.
+/// The `MSSA` analysis is also updated if valid (i.e. its use is enabled).
 ///
 /// If either `NonTrivial` is true or the flag `EnableNonTrivialUnswitch` is
 /// true, we will attempt to do non-trivial unswitching as well as trivial
@@ -2639,7 +2770,7 @@ static bool unswitchLoop(Loop &L, Domina
                          AssumptionCache &AC, TargetTransformInfo &TTI,
                          bool NonTrivial,
                          function_ref<void(bool, ArrayRef<Loop *>)> UnswitchCB,
-                         ScalarEvolution *SE) {
+                         ScalarEvolution *SE, MemorySSAUpdater *MSSAU) {
   assert(L.isRecursivelyLCSSAForm(DT, LI) &&
          "Loops must be in LCSSA form before unswitching.");
   bool Changed = false;
@@ -2649,7 +2780,7 @@ static bool unswitchLoop(Loop &L, Domina
     return false;
 
   // Try trivial unswitch first before loop over other basic blocks in the loop.
-  if (unswitchAllTrivialConditions(L, DT, LI, SE)) {
+  if (unswitchAllTrivialConditions(L, DT, LI, SE, MSSAU)) {
     // If we unswitched successfully we will want to clean up the loop before
     // processing it further so just mark it as unswitched and return.
     UnswitchCB(/*CurrentLoopValid*/ true, {});
@@ -2670,7 +2801,7 @@ static bool unswitchLoop(Loop &L, Domina
 
   // Try to unswitch the best invariant condition. We prefer this full unswitch to
   // a partial unswitch when possible below the threshold.
-  if (unswitchBestCondition(L, DT, LI, AC, TTI, UnswitchCB, SE))
+  if (unswitchBestCondition(L, DT, LI, AC, TTI, UnswitchCB, SE, MSSAU))
     return true;
 
   // No other opportunities to unswitch.
@@ -2704,10 +2835,19 @@ PreservedAnalyses SimpleLoopUnswitchPass
       U.markLoopAsDeleted(L, LoopName);
   };
 
+  Optional<MemorySSAUpdater> MSSAU;
+  if (AR.MSSA) {
+    MSSAU = MemorySSAUpdater(AR.MSSA);
+    if (VerifyMemorySSA)
+      AR.MSSA->verifyMemorySSA();
+  }
   if (!unswitchLoop(L, AR.DT, AR.LI, AR.AC, AR.TTI, NonTrivial, UnswitchCB,
-                    &AR.SE))
+                    &AR.SE, MSSAU.hasValue() ? MSSAU.getPointer() : nullptr))
     return PreservedAnalyses::all();
 
+  if (AR.MSSA && VerifyMemorySSA)
+    AR.MSSA->verifyMemorySSA();
+
   // Historically this pass has had issues with the dominator tree so verify it
   // in asserts builds.
   assert(AR.DT.verify(DominatorTree::VerificationLevel::Fast));
@@ -2733,6 +2873,10 @@ public:
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<AssumptionCacheTracker>();
     AU.addRequired<TargetTransformInfoWrapperPass>();
+    if (EnableMSSALoopDependency) {
+      AU.addRequired<MemorySSAWrapperPass>();
+      AU.addPreserved<MemorySSAWrapperPass>();
+    }
     getLoopAnalysisUsage(AU);
   }
 };
@@ -2752,6 +2896,12 @@ bool SimpleLoopUnswitchLegacyPass::runOn
   auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
   auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
   auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+  MemorySSA *MSSA = nullptr;
+  Optional<MemorySSAUpdater> MSSAU;
+  if (EnableMSSALoopDependency) {
+    MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
+    MSSAU = MemorySSAUpdater(MSSA);
+  }
 
   auto *SEWP = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
   auto *SE = SEWP ? &SEWP->getSE() : nullptr;
@@ -2771,7 +2921,14 @@ bool SimpleLoopUnswitchLegacyPass::runOn
       LPM.markLoopAsDeleted(*L);
   };
 
-  bool Changed = unswitchLoop(*L, DT, LI, AC, TTI, NonTrivial, UnswitchCB, SE);
+  if (MSSA && VerifyMemorySSA)
+    MSSA->verifyMemorySSA();
+
+  bool Changed = unswitchLoop(*L, DT, LI, AC, TTI, NonTrivial, UnswitchCB, SE,
+                              MSSAU.hasValue() ? MSSAU.getPointer() : nullptr);
+
+  if (MSSA && VerifyMemorySSA)
+    MSSA->verifyMemorySSA();
 
   // If anything was unswitched, also clear any cached information about this
   // loop.
@@ -2791,6 +2948,7 @@ INITIALIZE_PASS_DEPENDENCY(AssumptionCac
 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(LoopPass)
+INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
 INITIALIZE_PASS_END(SimpleLoopUnswitchLegacyPass, "simple-loop-unswitch",
                     "Simple unswitch loops", false, false)

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2006-06-13-SingleEntryPHI.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2006-06-13-SingleEntryPHI.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2006-06-13-SingleEntryPHI.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2006-06-13-SingleEntryPHI.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -disable-output
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
 
 	%struct.BLEND_MAP = type { i16, i16, i16, i32, %struct.BLEND_MAP_ENTRY* }
 	%struct.BLEND_MAP_ENTRY = type { float, i8, { [5 x float], [4 x i8] } }

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2006-06-27-DeadSwitchCase.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2006-06-27-DeadSwitchCase.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2006-06-27-DeadSwitchCase.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2006-06-27-DeadSwitchCase.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -disable-output
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
 
 define void @init_caller_save() {
 entry:

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-05-09-Unreachable.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-05-09-Unreachable.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-05-09-Unreachable.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-05-09-Unreachable.ll Tue Dec  4 06:23:37 2018
@@ -1,5 +1,6 @@
 ; PR1333
 ; RUN: opt < %s -simple-loop-unswitch -disable-output
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
 
 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
 target triple = "i686-pc-linux-gnu"

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-05-09-tl.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-05-09-tl.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-05-09-tl.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-05-09-tl.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -disable-output
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
 ; PR1333
 
 define void @pp_cxx_expression() {

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-12-ExitDomInfo.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-12-ExitDomInfo.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-12-ExitDomInfo.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-12-ExitDomInfo.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -instcombine -disable-output
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -instcombine -disable-output
 
 @str3 = external constant [3 x i8]		; <[3 x i8]*> [#uses=1]
 

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-13-DomInfo.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-13-DomInfo.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-13-DomInfo.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-13-DomInfo.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -disable-output
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
 
 define i32 @main(i32 %argc, i8** %argv) {
 entry:

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-18-DomInfo.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-18-DomInfo.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-18-DomInfo.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-07-18-DomInfo.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -disable-output
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
 ; PR1559
 
 target triple = "i686-pc-linux-gnu"

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-08-01-LCSSA.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-08-01-LCSSA.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-08-01-LCSSA.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2007-08-01-LCSSA.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -instcombine -disable-output
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -instcombine -disable-output
 	%struct.ClassDef = type { %struct.QByteArray, %struct.QByteArray, %"struct.QList<ArgumentDef>", %"struct.QList<ArgumentDef>", i8, i8, %"struct.QList<ArgumentDef>", %"struct.QList<ArgumentDef>", %"struct.QList<ArgumentDef>", %"struct.QList<ArgumentDef>", %"struct.QList<ArgumentDef>", %"struct.QList<ArgumentDef>", %"struct.QMap<QByteArray,QByteArray>", %"struct.QList<ArgumentDef>", %"struct.QMap<QByteArray,QByteArray>", i32, i32 }
 	%struct.FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct.FILE*, i32, i32, i32, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i32, i32, [40 x i8] }
 	%struct.Generator = type { %struct.FILE*, %struct.ClassDef*, %"struct.QList<ArgumentDef>", %struct.QByteArray, %"struct.QList<ArgumentDef>" }

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2008-06-02-DomInfo.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2008-06-02-DomInfo.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2008-06-02-DomInfo.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2008-06-02-DomInfo.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -instcombine -gvn -disable-output
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -instcombine -gvn -disable-output
 ; PR2372
 target triple = "i386-pc-linux-gnu"
 

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2010-11-18-LCSSA.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2010-11-18-LCSSA.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2010-11-18-LCSSA.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2010-11-18-LCSSA.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa
 ; PR8622
 @g_38 = external global i32, align 4
 

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2011-06-02-CritSwitch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2011-06-02-CritSwitch.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2011-06-02-CritSwitch.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2011-06-02-CritSwitch.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt -simple-loop-unswitch -disable-output < %s
+; RUN: opt -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output < %s
 ; PR10031
 
 define i32 @test(i32 %command) {

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2011-09-26-EHCrash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2011-09-26-EHCrash.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2011-09-26-EHCrash.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2011-09-26-EHCrash.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -sroa -simple-loop-unswitch -disable-output
+; RUN: opt < %s -sroa -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
 ; PR11016
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 target triple = "x86_64-apple-macosx10.7.2"

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2012-04-02-IndirectBr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2012-04-02-IndirectBr.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2012-04-02-IndirectBr.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2012-04-02-IndirectBr.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -S -simple-loop-unswitch -verify-loop-info -verify-dom-info | FileCheck %s
+; RUN: opt < %s -S -simple-loop-unswitch -verify-loop-info -verify-dom-info -enable-mssa-loop-dependency=true -verify-memoryssa | FileCheck %s
 ; PR12343: -simple-loop-unswitch crash on indirect branch
 
 ; CHECK:       %0 = icmp eq i64 undef, 0

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2012-05-20-Phi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2012-05-20-Phi.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2012-05-20-Phi.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2012-05-20-Phi.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -disable-output
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
 ; PR12887
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/2015-09-18-Addrspace.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/2015-09-18-Addrspace.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/2015-09-18-Addrspace.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/2015-09-18-Addrspace.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -S | FileCheck %s
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -S | FileCheck %s
 
 ; In cases where two address spaces do not have the same size pointer, the
 ; input for the addrspacecast should not be used as a substitute for itself

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/LIV-loop-condtion.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -S 2>&1 | FileCheck %s
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -S 2>&1 | FileCheck %s
 
 ; This is to test trivial loop unswitch only happens when trivial condition
 ; itself is an LIV loop condition (not partial LIV which could occur in and/or).

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/basictest.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/basictest.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/basictest.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/basictest.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
+; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
 
 define i32 @test(i32* %A, i1 %C) {
 entry:

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/cleanuppad.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/cleanuppad.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/cleanuppad.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/cleanuppad.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt -S -simple-loop-unswitch < %s | FileCheck %s
+; RUN: opt -S -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s
 target triple = "x86_64-pc-win32"
 
 define void @f(i32 %doit, i1 %x, i1 %y) personality i32 (...)* @__CxxFrameHandler3 {

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/copy-metadata.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/copy-metadata.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/copy-metadata.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/copy-metadata.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -S | FileCheck %s
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -S | FileCheck %s
 
 ; This test checks if unswitched condition preserve make.implicit metadata.
 define i32 @test(i1 %cond) {

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/crash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/crash.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/crash.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/crash.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -simple-loop-unswitch -disable-output
+; RUN: opt < %s -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output
 
 define void @test1(i32* %S2) {
 entry:

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/exponential-behavior.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/exponential-behavior.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/exponential-behavior.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/exponential-behavior.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt -simple-loop-unswitch -S < %s | FileCheck %s
+; RUN: opt -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -S < %s | FileCheck %s
 
 define void @f(i32 %n, i32* %ptr) {
 ; CHECK-LABEL: @f(

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/guards.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/guards.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/guards.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/guards.ll Tue Dec  4 06:23:37 2018
@@ -1,5 +1,6 @@
 ; RUN: opt -passes='loop(unswitch),verify<loops>' -enable-nontrivial-unswitch -simple-loop-unswitch-guards -S < %s | FileCheck %s
 ; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -simple-loop-unswitch-guards -S < %s | FileCheck %s
+; RUN: opt -passes='loop(unswitch),verify<loops>' -enable-nontrivial-unswitch -simple-loop-unswitch-guards -enable-mssa-loop-dependency=true -verify-memoryssa -S < %s | FileCheck %s
 
 declare void @llvm.experimental.guard(i1, ...)
 

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/infinite-loop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/infinite-loop.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/infinite-loop.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/infinite-loop.ll Tue Dec  4 06:23:37 2018
@@ -1,6 +1,7 @@
 ; REQUIRES: asserts
 ; RUN: opt -simple-loop-unswitch -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s
 ; RUN: opt -simple-loop-unswitch -S < %s | FileCheck %s
+; RUN: opt -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -S < %s | FileCheck %s
 ; PR5373
 
 ; Loop unswitching shouldn't trivially unswitch the true case of condition %a

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/msan.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/msan.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/msan.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/msan.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
+; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
 
 declare void @unknown()
 declare void @unknown2()

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll Tue Dec  4 06:23:37 2018
@@ -2,6 +2,7 @@
 ;
 ; RUN: opt -passes='loop(unswitch),verify<loops>' -enable-nontrivial-unswitch -unswitch-threshold=5 -S < %s | FileCheck %s
 ; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -unswitch-threshold=5 -S < %s | FileCheck %s
+; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -unswitch-threshold=5 -enable-mssa-loop-dependency=true -verify-memoryssa -S < %s | FileCheck %s
 
 declare void @a()
 declare void @b()

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll Tue Dec  4 06:23:37 2018
@@ -1,5 +1,6 @@
 ; RUN: opt -passes='loop(unswitch),verify<loops>' -enable-nontrivial-unswitch -S < %s | FileCheck %s
 ; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -S < %s | FileCheck %s
+; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -S < %s | FileCheck %s
 
 declare i32 @a()
 declare i32 @b()

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/pr37888.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/pr37888.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/pr37888.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/pr37888.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt -simple-loop-unswitch -loop-deletion -S < %s | FileCheck %s
+; RUN: opt -simple-loop-unswitch -enable-mssa-loop-dependency=true -verify-memoryssa -loop-deletion -S < %s | FileCheck %s
 ;
 ; Check that when we do unswitching where we re-enqueue the loop to be processed
 ; again, but manage to delete the loop before ever getting to iterate on it, it

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/preserve-analyses.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/preserve-analyses.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/preserve-analyses.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/preserve-analyses.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt -simple-loop-unswitch -verify-loop-info -verify-dom-info -disable-output < %s
+; RUN: opt -simple-loop-unswitch -verify-loop-info -verify-dom-info -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output < %s
 
 ; Loop unswitch should be able to unswitch these loops and
 ; preserve LCSSA and LoopSimplify forms.

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-iteration.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-iteration.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-iteration.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-iteration.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt -passes='loop(loop-instsimplify,simplify-cfg,unswitch),verify<loops>' -S < %s | FileCheck %s
+; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='loop(loop-instsimplify,simplify-cfg,unswitch),verify<loops>' -S < %s | FileCheck %s
 
 declare void @some_func() noreturn
 

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
+; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
 
 declare void @some_func() noreturn
 declare void @sink(i32)

Modified: llvm/trunk/test/Transforms/SimpleLoopUnswitch/update-scev.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimpleLoopUnswitch/update-scev.ll?rev=348263&r1=348262&r2=348263&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimpleLoopUnswitch/update-scev.ll (original)
+++ llvm/trunk/test/Transforms/SimpleLoopUnswitch/update-scev.ll Tue Dec  4 06:23:37 2018
@@ -1,4 +1,5 @@
 ; RUN: opt -passes='print<scalar-evolution>,loop(unswitch,loop-instsimplify),print<scalar-evolution>' -enable-nontrivial-unswitch -S < %s 2>%t.scev | FileCheck %s
+; RUN: opt -enable-mssa-loop-dependency=true -verify-memoryssa -passes='print<scalar-evolution>,loop(unswitch,loop-instsimplify),print<scalar-evolution>' -enable-nontrivial-unswitch -S < %s 2>%t.scev | FileCheck %s
 ; RUN: FileCheck %s --check-prefix=SCEV < %t.scev
 
 target triple = "x86_64-unknown-linux-gnu"




More information about the llvm-commits mailing list