//===- MemorySSA.cpp - Unit tests for MemorySSA ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "gtest/gtest.h"

using namespace llvm;

const static char DLString[] = "e-i64:64-f80:128-n8:16:32:64-S128";

/// There's a lot of common setup between these tests. This fixture helps reduce
/// that. Tests should mock up a function, store it in F, and then call
/// setupAnalyses().
class MemorySSATest : public testing::Test {
protected:
  // N.B. Many of these members depend on each other (e.g. the Module depends on
  // the Context, etc.). So, order matters here (and in TestAnalyses).
  LLVMContext C;
  Module M;
  IRBuilder<> B;
  DataLayout DL;
  TargetLibraryInfoImpl TLII;
  TargetLibraryInfo TLI;
  Function *F;

  // Things that we need to build after the function is created.
  struct TestAnalyses {
    DominatorTree DT;
    AssumptionCache AC;
    AAResults AA;
    BasicAAResult BAA;
    // We need to defer MSSA construction until AA is *entirely* set up, which
    // requires calling addAAResult. Hence, we just use a pointer here.
    std::unique_ptr<MemorySSA> MSSA;
    MemorySSAWalker *Walker;

    TestAnalyses(MemorySSATest &Test)
        : DT(*Test.F), AC(*Test.F), AA(Test.TLI),
          BAA(Test.DL, *Test.F, Test.TLI, AC, &DT) {
      AA.addAAResult(BAA);
      MSSA = make_unique<MemorySSA>(*Test.F, &AA, &DT);
      Walker = MSSA->getWalker();
    }
  };

  std::unique_ptr<TestAnalyses> Analyses;

  void setupAnalyses() {
    assert(F);
    Analyses.reset(new TestAnalyses(*this));
  }

public:
  MemorySSATest()
      : M("MemorySSATest", C), B(C), DL(DLString), TLI(TLII), F(nullptr) {}
};

TEST_F(MemorySSATest, CreateALoad) {
  // We create a diamond where there is a store on one side, and then after
  // building MemorySSA, create a load after the merge point, and use it to test
  // updating by creating an access for the load.
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  BasicBlock *Entry(BasicBlock::Create(C, "", F));
  BasicBlock *Left(BasicBlock::Create(C, "", F));
  BasicBlock *Right(BasicBlock::Create(C, "", F));
  BasicBlock *Merge(BasicBlock::Create(C, "", F));
  B.SetInsertPoint(Entry);
  B.CreateCondBr(B.getTrue(), Left, Right);
  B.SetInsertPoint(Left);
  Argument *PointerArg = &*F->arg_begin();
  B.CreateStore(B.getInt8(16), PointerArg);
  BranchInst::Create(Merge, Left);
  BranchInst::Create(Merge, Right);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAUpdater Updater(&MSSA);
  // Add the load
  B.SetInsertPoint(Merge);
  LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);

  // MemoryPHI should already exist.
  MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
  EXPECT_NE(MP, nullptr);

  // Create the load memory acccess
  MemoryUse *LoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
      LoadInst, MP, Merge, MemorySSA::Beginning));
  MemoryAccess *DefiningAccess = LoadAccess->getDefiningAccess();
  EXPECT_TRUE(isa<MemoryPhi>(DefiningAccess));
  MSSA.verifyMemorySSA();
}
TEST_F(MemorySSATest, CreateLoadsAndStoreUpdater) {
  // We create a diamond, then build memoryssa with no memory accesses, and
  // incrementally update it by inserting a store in the, entry, a load in the
  // merge point, then a store in the branch, another load in the merge point,
  // and then a store in the entry.
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  BasicBlock *Entry(BasicBlock::Create(C, "", F));
  BasicBlock *Left(BasicBlock::Create(C, "", F));
  BasicBlock *Right(BasicBlock::Create(C, "", F));
  BasicBlock *Merge(BasicBlock::Create(C, "", F));
  B.SetInsertPoint(Entry);
  B.CreateCondBr(B.getTrue(), Left, Right);
  B.SetInsertPoint(Left, Left->begin());
  Argument *PointerArg = &*F->arg_begin();
  B.SetInsertPoint(Left);
  B.CreateBr(Merge);
  B.SetInsertPoint(Right);
  B.CreateBr(Merge);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAUpdater Updater(&MSSA);
  // Add the store
  B.SetInsertPoint(Entry, Entry->begin());
  StoreInst *EntryStore = B.CreateStore(B.getInt8(16), PointerArg);
  MemoryAccess *EntryStoreAccess = Updater.createMemoryAccessInBB(
      EntryStore, nullptr, Entry, MemorySSA::Beginning);
  Updater.insertDef(cast<MemoryDef>(EntryStoreAccess));

  // Add the load
  B.SetInsertPoint(Merge, Merge->begin());
  LoadInst *FirstLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);

  // MemoryPHI should not already exist.
  MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
  EXPECT_EQ(MP, nullptr);

  // Create the load memory access
  MemoryUse *FirstLoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
      FirstLoad, nullptr, Merge, MemorySSA::Beginning));
  Updater.insertUse(FirstLoadAccess);
  // Should just have a load using the entry access, because it should discover
  // the phi is trivial
  EXPECT_EQ(FirstLoadAccess->getDefiningAccess(), EntryStoreAccess);

  // Create a store on the left
  // Add the store
  B.SetInsertPoint(Left, Left->begin());
  StoreInst *LeftStore = B.CreateStore(B.getInt8(16), PointerArg);
  MemoryAccess *LeftStoreAccess = Updater.createMemoryAccessInBB(
      LeftStore, nullptr, Left, MemorySSA::Beginning);
  Updater.insertDef(cast<MemoryDef>(LeftStoreAccess), false);
  // We don't touch existing loads, so we need to create a new one to get a phi
  // Add the second load
  B.SetInsertPoint(Merge, Merge->begin());
  LoadInst *SecondLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);

  // MemoryPHI should not already exist.
  MP = MSSA.getMemoryAccess(Merge);
  EXPECT_EQ(MP, nullptr);

  // Create the load memory access
  MemoryUse *SecondLoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
      SecondLoad, nullptr, Merge, MemorySSA::Beginning));
  Updater.insertUse(SecondLoadAccess);
  // Now the load should be a phi of the entry store and the left store
  MemoryPhi *MergePhi =
      dyn_cast<MemoryPhi>(SecondLoadAccess->getDefiningAccess());
  EXPECT_NE(MergePhi, nullptr);
  EXPECT_EQ(MergePhi->getIncomingValue(0), EntryStoreAccess);
  EXPECT_EQ(MergePhi->getIncomingValue(1), LeftStoreAccess);
  // Now create a store below the existing one in the entry
  B.SetInsertPoint(Entry, --Entry->end());
  StoreInst *SecondEntryStore = B.CreateStore(B.getInt8(16), PointerArg);
  MemoryAccess *SecondEntryStoreAccess = Updater.createMemoryAccessInBB(
      SecondEntryStore, nullptr, Entry, MemorySSA::End);
  // Insert it twice just to test renaming
  Updater.insertDef(cast<MemoryDef>(SecondEntryStoreAccess), false);
  EXPECT_NE(FirstLoadAccess->getDefiningAccess(), MergePhi);
  Updater.insertDef(cast<MemoryDef>(SecondEntryStoreAccess), true);
  EXPECT_EQ(FirstLoadAccess->getDefiningAccess(), MergePhi);
  // and make sure the phi below it got updated, despite being blocks away
  MergePhi = dyn_cast<MemoryPhi>(SecondLoadAccess->getDefiningAccess());
  EXPECT_NE(MergePhi, nullptr);
  EXPECT_EQ(MergePhi->getIncomingValue(0), SecondEntryStoreAccess);
  EXPECT_EQ(MergePhi->getIncomingValue(1), LeftStoreAccess);
  MSSA.verifyMemorySSA();
}

TEST_F(MemorySSATest, CreateALoadUpdater) {
  // We create a diamond, then build memoryssa with no memory accesses, and
  // incrementally update it by inserting a store in one of the branches, and a
  // load in the merge point
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  BasicBlock *Entry(BasicBlock::Create(C, "", F));
  BasicBlock *Left(BasicBlock::Create(C, "", F));
  BasicBlock *Right(BasicBlock::Create(C, "", F));
  BasicBlock *Merge(BasicBlock::Create(C, "", F));
  B.SetInsertPoint(Entry);
  B.CreateCondBr(B.getTrue(), Left, Right);
  B.SetInsertPoint(Left, Left->begin());
  Argument *PointerArg = &*F->arg_begin();
  B.SetInsertPoint(Left);
  B.CreateBr(Merge);
  B.SetInsertPoint(Right);
  B.CreateBr(Merge);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAUpdater Updater(&MSSA);
  B.SetInsertPoint(Left, Left->begin());
  // Add the store
  StoreInst *SI = B.CreateStore(B.getInt8(16), PointerArg);
  MemoryAccess *StoreAccess =
      Updater.createMemoryAccessInBB(SI, nullptr, Left, MemorySSA::Beginning);
  Updater.insertDef(cast<MemoryDef>(StoreAccess));

  // Add the load
  B.SetInsertPoint(Merge, Merge->begin());
  LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);

  // MemoryPHI should not already exist.
  MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
  EXPECT_EQ(MP, nullptr);

  // Create the load memory acccess
  MemoryUse *LoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
      LoadInst, nullptr, Merge, MemorySSA::Beginning));
  Updater.insertUse(LoadAccess);
  MemoryAccess *DefiningAccess = LoadAccess->getDefiningAccess();
  EXPECT_TRUE(isa<MemoryPhi>(DefiningAccess));
  MSSA.verifyMemorySSA();
}

TEST_F(MemorySSATest, SinkLoad) {
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  BasicBlock *Entry(BasicBlock::Create(C, "", F));
  BasicBlock *Left(BasicBlock::Create(C, "", F));
  BasicBlock *Right(BasicBlock::Create(C, "", F));
  BasicBlock *Merge(BasicBlock::Create(C, "", F));
  B.SetInsertPoint(Entry);
  B.CreateCondBr(B.getTrue(), Left, Right);
  B.SetInsertPoint(Left, Left->begin());
  Argument *PointerArg = &*F->arg_begin();
  B.SetInsertPoint(Left);
  B.CreateBr(Merge);
  B.SetInsertPoint(Right);
  B.CreateBr(Merge);

  // Load in left block
  B.SetInsertPoint(Left, Left->begin());
  LoadInst *LoadInst1 = B.CreateLoad(B.getInt8Ty(), PointerArg);
  // Store in merge block
  B.SetInsertPoint(Merge, Merge->begin());
  B.CreateStore(B.getInt8(16), PointerArg);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAUpdater Updater(&MSSA);

  // Mimic sinking of a load:
  // - clone load
  // - insert in "exit" block
  // - insert in mssa
  // - remove from original block

  LoadInst *LoadInstClone = cast<LoadInst>(LoadInst1->clone());
  Merge->getInstList().insert(Merge->begin(), LoadInstClone);
  MemoryAccess * NewLoadAccess =
      Updater.createMemoryAccessInBB(LoadInstClone, nullptr,
                                     LoadInstClone->getParent(),
                                     MemorySSA::Beginning);
  Updater.insertUse(cast<MemoryUse>(NewLoadAccess));
  MSSA.verifyMemorySSA();
  Updater.removeMemoryAccess(MSSA.getMemoryAccess(LoadInst1));
  MSSA.verifyMemorySSA();
}

TEST_F(MemorySSATest, MoveAStore) {
  // We create a diamond where there is a in the entry, a store on one side, and
  // a load at the end.  After building MemorySSA, we test updating by moving
  // the store from the side block to the entry block. This destroys the old
  // access.
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  BasicBlock *Entry(BasicBlock::Create(C, "", F));
  BasicBlock *Left(BasicBlock::Create(C, "", F));
  BasicBlock *Right(BasicBlock::Create(C, "", F));
  BasicBlock *Merge(BasicBlock::Create(C, "", F));
  B.SetInsertPoint(Entry);
  Argument *PointerArg = &*F->arg_begin();
  StoreInst *EntryStore = B.CreateStore(B.getInt8(16), PointerArg);
  B.CreateCondBr(B.getTrue(), Left, Right);
  B.SetInsertPoint(Left);
  StoreInst *SideStore = B.CreateStore(B.getInt8(16), PointerArg);
  BranchInst::Create(Merge, Left);
  BranchInst::Create(Merge, Right);
  B.SetInsertPoint(Merge);
  B.CreateLoad(B.getInt8Ty(), PointerArg);
  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAUpdater Updater(&MSSA);
  // Move the store
  SideStore->moveBefore(Entry->getTerminator());
  MemoryAccess *EntryStoreAccess = MSSA.getMemoryAccess(EntryStore);
  MemoryAccess *SideStoreAccess = MSSA.getMemoryAccess(SideStore);
  MemoryAccess *NewStoreAccess = Updater.createMemoryAccessAfter(
      SideStore, EntryStoreAccess, EntryStoreAccess);
  EntryStoreAccess->replaceAllUsesWith(NewStoreAccess);
  Updater.removeMemoryAccess(SideStoreAccess);
  MSSA.verifyMemorySSA();
}

TEST_F(MemorySSATest, MoveAStoreUpdater) {
  // We create a diamond where there is a in the entry, a store on one side, and
  // a load at the end.  After building MemorySSA, we test updating by moving
  // the store from the side block to the entry block.  This destroys the old
  // access.
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  BasicBlock *Entry(BasicBlock::Create(C, "", F));
  BasicBlock *Left(BasicBlock::Create(C, "", F));
  BasicBlock *Right(BasicBlock::Create(C, "", F));
  BasicBlock *Merge(BasicBlock::Create(C, "", F));
  B.SetInsertPoint(Entry);
  Argument *PointerArg = &*F->arg_begin();
  StoreInst *EntryStore = B.CreateStore(B.getInt8(16), PointerArg);
  B.CreateCondBr(B.getTrue(), Left, Right);
  B.SetInsertPoint(Left);
  auto *SideStore = B.CreateStore(B.getInt8(16), PointerArg);
  BranchInst::Create(Merge, Left);
  BranchInst::Create(Merge, Right);
  B.SetInsertPoint(Merge);
  auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAUpdater Updater(&MSSA);

  // Move the store
  SideStore->moveBefore(Entry->getTerminator());
  auto *EntryStoreAccess = MSSA.getMemoryAccess(EntryStore);
  auto *SideStoreAccess = MSSA.getMemoryAccess(SideStore);
  auto *NewStoreAccess = Updater.createMemoryAccessAfter(
      SideStore, EntryStoreAccess, EntryStoreAccess);
  // Before, the load will point to a phi of the EntryStore and SideStore.
  auto *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(MergeLoad));
  EXPECT_TRUE(isa<MemoryPhi>(LoadAccess->getDefiningAccess()));
  MemoryPhi *MergePhi = cast<MemoryPhi>(LoadAccess->getDefiningAccess());
  EXPECT_EQ(MergePhi->getIncomingValue(1), EntryStoreAccess);
  EXPECT_EQ(MergePhi->getIncomingValue(0), SideStoreAccess);
  Updater.removeMemoryAccess(SideStoreAccess);
  Updater.insertDef(cast<MemoryDef>(NewStoreAccess));
  // After it's a phi of the new side store access.
  EXPECT_EQ(MergePhi->getIncomingValue(0), NewStoreAccess);
  EXPECT_EQ(MergePhi->getIncomingValue(1), NewStoreAccess);
  MSSA.verifyMemorySSA();
}

TEST_F(MemorySSATest, MoveAStoreUpdaterMove) {
  // We create a diamond where there is a in the entry, a store on one side, and
  // a load at the end.  After building MemorySSA, we test updating by moving
  // the store from the side block to the entry block.  This does not destroy
  // the old access.
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  BasicBlock *Entry(BasicBlock::Create(C, "", F));
  BasicBlock *Left(BasicBlock::Create(C, "", F));
  BasicBlock *Right(BasicBlock::Create(C, "", F));
  BasicBlock *Merge(BasicBlock::Create(C, "", F));
  B.SetInsertPoint(Entry);
  Argument *PointerArg = &*F->arg_begin();
  StoreInst *EntryStore = B.CreateStore(B.getInt8(16), PointerArg);
  B.CreateCondBr(B.getTrue(), Left, Right);
  B.SetInsertPoint(Left);
  auto *SideStore = B.CreateStore(B.getInt8(16), PointerArg);
  BranchInst::Create(Merge, Left);
  BranchInst::Create(Merge, Right);
  B.SetInsertPoint(Merge);
  auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAUpdater Updater(&MSSA);

  // Move the store
  auto *EntryStoreAccess = MSSA.getMemoryAccess(EntryStore);
  auto *SideStoreAccess = MSSA.getMemoryAccess(SideStore);
  // Before, the load will point to a phi of the EntryStore and SideStore.
  auto *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(MergeLoad));
  EXPECT_TRUE(isa<MemoryPhi>(LoadAccess->getDefiningAccess()));
  MemoryPhi *MergePhi = cast<MemoryPhi>(LoadAccess->getDefiningAccess());
  EXPECT_EQ(MergePhi->getIncomingValue(1), EntryStoreAccess);
  EXPECT_EQ(MergePhi->getIncomingValue(0), SideStoreAccess);
  SideStore->moveBefore(*EntryStore->getParent(), ++EntryStore->getIterator());
  Updater.moveAfter(SideStoreAccess, EntryStoreAccess);
  // After, it's a phi of the side store.
  EXPECT_EQ(MergePhi->getIncomingValue(0), SideStoreAccess);
  EXPECT_EQ(MergePhi->getIncomingValue(1), SideStoreAccess);

  MSSA.verifyMemorySSA();
}

TEST_F(MemorySSATest, MoveAStoreAllAround) {
  // We create a diamond where there is a in the entry, a store on one side, and
  // a load at the end.  After building MemorySSA, we test updating by moving
  // the store from the side block to the entry block, then to the other side
  // block, then to before the load.  This does not destroy the old access.
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  BasicBlock *Entry(BasicBlock::Create(C, "", F));
  BasicBlock *Left(BasicBlock::Create(C, "", F));
  BasicBlock *Right(BasicBlock::Create(C, "", F));
  BasicBlock *Merge(BasicBlock::Create(C, "", F));
  B.SetInsertPoint(Entry);
  Argument *PointerArg = &*F->arg_begin();
  StoreInst *EntryStore = B.CreateStore(B.getInt8(16), PointerArg);
  B.CreateCondBr(B.getTrue(), Left, Right);
  B.SetInsertPoint(Left);
  auto *SideStore = B.CreateStore(B.getInt8(16), PointerArg);
  BranchInst::Create(Merge, Left);
  BranchInst::Create(Merge, Right);
  B.SetInsertPoint(Merge);
  auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAUpdater Updater(&MSSA);

  // Move the store
  auto *EntryStoreAccess = MSSA.getMemoryAccess(EntryStore);
  auto *SideStoreAccess = MSSA.getMemoryAccess(SideStore);
  // Before, the load will point to a phi of the EntryStore and SideStore.
  auto *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(MergeLoad));
  EXPECT_TRUE(isa<MemoryPhi>(LoadAccess->getDefiningAccess()));
  MemoryPhi *MergePhi = cast<MemoryPhi>(LoadAccess->getDefiningAccess());
  EXPECT_EQ(MergePhi->getIncomingValue(1), EntryStoreAccess);
  EXPECT_EQ(MergePhi->getIncomingValue(0), SideStoreAccess);
  // Move the store before the entry store
  SideStore->moveBefore(*EntryStore->getParent(), EntryStore->getIterator());
  Updater.moveBefore(SideStoreAccess, EntryStoreAccess);
  // After, it's a phi of the entry store.
  EXPECT_EQ(MergePhi->getIncomingValue(0), EntryStoreAccess);
  EXPECT_EQ(MergePhi->getIncomingValue(1), EntryStoreAccess);
  MSSA.verifyMemorySSA();
  // Now move the store to the right branch
  SideStore->moveBefore(*Right, Right->begin());
  Updater.moveToPlace(SideStoreAccess, Right, MemorySSA::Beginning);
  MSSA.verifyMemorySSA();
  EXPECT_EQ(MergePhi->getIncomingValue(0), EntryStoreAccess);
  EXPECT_EQ(MergePhi->getIncomingValue(1), SideStoreAccess);
  // Now move it before the load
  SideStore->moveBefore(MergeLoad);
  Updater.moveBefore(SideStoreAccess, LoadAccess);
  EXPECT_EQ(MergePhi->getIncomingValue(0), EntryStoreAccess);
  EXPECT_EQ(MergePhi->getIncomingValue(1), EntryStoreAccess);
  MSSA.verifyMemorySSA();
}

TEST_F(MemorySSATest, RemoveAPhi) {
  // We create a diamond where there is a store on one side, and then a load
  // after the merge point.  This enables us to test a bunch of different
  // removal cases.
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  BasicBlock *Entry(BasicBlock::Create(C, "", F));
  BasicBlock *Left(BasicBlock::Create(C, "", F));
  BasicBlock *Right(BasicBlock::Create(C, "", F));
  BasicBlock *Merge(BasicBlock::Create(C, "", F));
  B.SetInsertPoint(Entry);
  B.CreateCondBr(B.getTrue(), Left, Right);
  B.SetInsertPoint(Left);
  Argument *PointerArg = &*F->arg_begin();
  StoreInst *StoreInst = B.CreateStore(B.getInt8(16), PointerArg);
  BranchInst::Create(Merge, Left);
  BranchInst::Create(Merge, Right);
  B.SetInsertPoint(Merge);
  LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAUpdater Updater(&MSSA);

  // Before, the load will be a use of a phi<store, liveonentry>.
  MemoryUse *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(LoadInst));
  MemoryDef *StoreAccess = cast<MemoryDef>(MSSA.getMemoryAccess(StoreInst));
  MemoryAccess *DefiningAccess = LoadAccess->getDefiningAccess();
  EXPECT_TRUE(isa<MemoryPhi>(DefiningAccess));
  // Kill the store
  Updater.removeMemoryAccess(StoreAccess);
  MemoryPhi *MP = cast<MemoryPhi>(DefiningAccess);
  // Verify the phi ended up as liveonentry, liveonentry
  for (auto &Op : MP->incoming_values())
    EXPECT_TRUE(MSSA.isLiveOnEntryDef(cast<MemoryAccess>(Op.get())));
  // Replace the phi uses with the live on entry def
  MP->replaceAllUsesWith(MSSA.getLiveOnEntryDef());
  // Verify the load is now defined by liveOnEntryDef
  EXPECT_TRUE(MSSA.isLiveOnEntryDef(LoadAccess->getDefiningAccess()));
  // Remove the PHI
  Updater.removeMemoryAccess(MP);
  MSSA.verifyMemorySSA();
}

TEST_F(MemorySSATest, RemoveMemoryAccess) {
  // We create a diamond where there is a store on one side, and then a load
  // after the merge point.  This enables us to test a bunch of different
  // removal cases.
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  BasicBlock *Entry(BasicBlock::Create(C, "", F));
  BasicBlock *Left(BasicBlock::Create(C, "", F));
  BasicBlock *Right(BasicBlock::Create(C, "", F));
  BasicBlock *Merge(BasicBlock::Create(C, "", F));
  B.SetInsertPoint(Entry);
  B.CreateCondBr(B.getTrue(), Left, Right);
  B.SetInsertPoint(Left);
  Argument *PointerArg = &*F->arg_begin();
  StoreInst *StoreInst = B.CreateStore(B.getInt8(16), PointerArg);
  BranchInst::Create(Merge, Left);
  BranchInst::Create(Merge, Right);
  B.SetInsertPoint(Merge);
  LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;
  MemorySSAUpdater Updater(&MSSA);

  // Before, the load will be a use of a phi<store, liveonentry>. It should be
  // the same after.
  MemoryUse *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(LoadInst));
  MemoryDef *StoreAccess = cast<MemoryDef>(MSSA.getMemoryAccess(StoreInst));
  MemoryAccess *DefiningAccess = LoadAccess->getDefiningAccess();
  EXPECT_TRUE(isa<MemoryPhi>(DefiningAccess));
  // The load is currently clobbered by one of the phi arguments, so the walker
  // should determine the clobbering access as the phi.
  EXPECT_EQ(DefiningAccess, Walker->getClobberingMemoryAccess(LoadInst));
  Updater.removeMemoryAccess(StoreAccess);
  MSSA.verifyMemorySSA();
  // After the removeaccess, let's see if we got the right accesses
  // The load should still point to the phi ...
  EXPECT_EQ(DefiningAccess, LoadAccess->getDefiningAccess());
  // but we should now get live on entry for the clobbering definition of the
  // load, since it will walk past the phi node since every argument is the
  // same.
  // XXX: This currently requires either removing the phi or resetting optimized
  // on the load

  EXPECT_FALSE(
      MSSA.isLiveOnEntryDef(Walker->getClobberingMemoryAccess(LoadInst)));
  // If we reset optimized, we get live on entry.
  LoadAccess->resetOptimized();
  EXPECT_TRUE(
      MSSA.isLiveOnEntryDef(Walker->getClobberingMemoryAccess(LoadInst)));
  // The phi should now be a two entry phi with two live on entry defs.
  for (const auto &Op : DefiningAccess->operands()) {
    MemoryAccess *Operand = cast<MemoryAccess>(&*Op);
    EXPECT_TRUE(MSSA.isLiveOnEntryDef(Operand));
  }

  // Now we try to remove the single valued phi
  Updater.removeMemoryAccess(DefiningAccess);
  MSSA.verifyMemorySSA();
  // Now the load should be a load of live on entry.
  EXPECT_TRUE(MSSA.isLiveOnEntryDef(LoadAccess->getDefiningAccess()));
}

// We had a bug with caching where the walker would report MemoryDef#3's clobber
// (below) was MemoryDef#1.
//
// define void @F(i8*) {
//   %A = alloca i8, i8 1
// ; 1 = MemoryDef(liveOnEntry)
//   store i8 0, i8* %A
// ; 2 = MemoryDef(1)
//   store i8 1, i8* %A
// ; 3 = MemoryDef(2)
//   store i8 2, i8* %A
// }
TEST_F(MemorySSATest, TestTripleStore) {
  F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "", F));
  Type *Int8 = Type::getInt8Ty(C);
  Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
  StoreInst *S1 = B.CreateStore(ConstantInt::get(Int8, 0), Alloca);
  StoreInst *S2 = B.CreateStore(ConstantInt::get(Int8, 1), Alloca);
  StoreInst *S3 = B.CreateStore(ConstantInt::get(Int8, 2), Alloca);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;

  unsigned I = 0;
  for (StoreInst *V : {S1, S2, S3}) {
    // Everything should be clobbered by its defining access
    MemoryAccess *DefiningAccess = MSSA.getMemoryAccess(V)->getDefiningAccess();
    MemoryAccess *WalkerClobber = Walker->getClobberingMemoryAccess(V);
    EXPECT_EQ(DefiningAccess, WalkerClobber)
        << "Store " << I << " doesn't have the correct clobbering access";
    // EXPECT_EQ expands such that if we increment I above, it won't get
    // incremented except when we try to print the error message.
    ++I;
  }
}

// ...And fixing the above bug made it obvious that, when walking, MemorySSA's
// walker was caching the initial node it walked. This was fine (albeit
// mostly redundant) unless the initial node being walked is a clobber for the
// query. In that case, we'd cache that the node clobbered itself.
TEST_F(MemorySSATest, TestStoreAndLoad) {
  F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "", F));
  Type *Int8 = Type::getInt8Ty(C);
  Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
  Instruction *SI = B.CreateStore(ConstantInt::get(Int8, 0), Alloca);
  Instruction *LI = B.CreateLoad(Int8, Alloca);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;

  MemoryAccess *LoadClobber = Walker->getClobberingMemoryAccess(LI);
  EXPECT_EQ(LoadClobber, MSSA.getMemoryAccess(SI));
  EXPECT_TRUE(MSSA.isLiveOnEntryDef(Walker->getClobberingMemoryAccess(SI)));
}

// Another bug (related to the above two fixes): It was noted that, given the
// following code:
// ; 1 = MemoryDef(liveOnEntry)
// store i8 0, i8* %1
//
// ...A query to getClobberingMemoryAccess(MemoryAccess*, MemoryLocation) would
// hand back the store (correctly). A later call to
// getClobberingMemoryAccess(const Instruction*) would also hand back the store
// (incorrectly; it should return liveOnEntry).
//
// This test checks that repeated calls to either function returns what they're
// meant to.
TEST_F(MemorySSATest, TestStoreDoubleQuery) {
  F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "", F));
  Type *Int8 = Type::getInt8Ty(C);
  Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
  StoreInst *SI = B.CreateStore(ConstantInt::get(Int8, 0), Alloca);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;

  MemoryAccess *StoreAccess = MSSA.getMemoryAccess(SI);
  MemoryLocation StoreLoc = MemoryLocation::get(SI);
  MemoryAccess *Clobber =
      Walker->getClobberingMemoryAccess(StoreAccess, StoreLoc);
  MemoryAccess *LiveOnEntry = Walker->getClobberingMemoryAccess(SI);

  EXPECT_EQ(Clobber, StoreAccess);
  EXPECT_TRUE(MSSA.isLiveOnEntryDef(LiveOnEntry));

  // Try again (with entries in the cache already) for good measure...
  Clobber = Walker->getClobberingMemoryAccess(StoreAccess, StoreLoc);
  LiveOnEntry = Walker->getClobberingMemoryAccess(SI);
  EXPECT_EQ(Clobber, StoreAccess);
  EXPECT_TRUE(MSSA.isLiveOnEntryDef(LiveOnEntry));
}

// Bug: During phi optimization, the walker wouldn't cache to the proper result
// in the farthest-walked BB.
//
// Specifically, it would assume that whatever we walked to was a clobber.
// "Whatever we walked to" isn't a clobber if we hit a cache entry.
//
// ...So, we need a test case that looks like:
//    A
//   / \
//  B   |
//   \ /
//    C
//
// Where, when we try to optimize a thing in 'C', a blocker is found in 'B'.
// The walk must determine that the blocker exists by using cache entries *while
// walking* 'B'.
TEST_F(MemorySSATest, PartialWalkerCacheWithPhis) {
  F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "A", F));
  Type *Int8 = Type::getInt8Ty(C);
  Constant *One = ConstantInt::get(Int8, 1);
  Constant *Zero = ConstantInt::get(Int8, 0);
  Value *AllocA = B.CreateAlloca(Int8, One, "a");
  Value *AllocB = B.CreateAlloca(Int8, One, "b");
  BasicBlock *IfThen = BasicBlock::Create(C, "B", F);
  BasicBlock *IfEnd = BasicBlock::Create(C, "C", F);

  B.CreateCondBr(UndefValue::get(Type::getInt1Ty(C)), IfThen, IfEnd);

  B.SetInsertPoint(IfThen);
  Instruction *FirstStore = B.CreateStore(Zero, AllocA);
  B.CreateStore(Zero, AllocB);
  Instruction *ALoad0 = B.CreateLoad(Int8, AllocA, "");
  Instruction *BStore = B.CreateStore(Zero, AllocB);
  // Due to use optimization/etc. we make a store to A, which is removed after
  // we build MSSA. This helps keep the test case simple-ish.
  Instruction *KillStore = B.CreateStore(Zero, AllocA);
  Instruction *ALoad = B.CreateLoad(Int8, AllocA, "");
  B.CreateBr(IfEnd);

  B.SetInsertPoint(IfEnd);
  Instruction *BelowPhi = B.CreateStore(Zero, AllocA);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;
  MemorySSAUpdater Updater(&MSSA);

  // Kill `KillStore`; it exists solely so that the load after it won't be
  // optimized to FirstStore.
  Updater.removeMemoryAccess(MSSA.getMemoryAccess(KillStore));
  KillStore->eraseFromParent();
  auto *ALoadMA = cast<MemoryUse>(MSSA.getMemoryAccess(ALoad));
  EXPECT_EQ(ALoadMA->getDefiningAccess(), MSSA.getMemoryAccess(BStore));

  // Populate the cache for the store to AllocB directly after FirstStore. It
  // should point to something in block B (so something in D can't be optimized
  // to it).
  MemoryAccess *Load0Clobber = Walker->getClobberingMemoryAccess(ALoad0);
  EXPECT_EQ(MSSA.getMemoryAccess(FirstStore), Load0Clobber);

  // If the bug exists, this will introduce a bad cache entry for %a on BStore.
  // It will point to the store to %b after FirstStore. This only happens during
  // phi optimization.
  MemoryAccess *BottomClobber = Walker->getClobberingMemoryAccess(BelowPhi);
  MemoryAccess *Phi = MSSA.getMemoryAccess(IfEnd);
  EXPECT_EQ(BottomClobber, Phi);

  // This query will first check the cache for {%a, BStore}. It should point to
  // FirstStore, not to the store after FirstStore.
  MemoryAccess *UseClobber = Walker->getClobberingMemoryAccess(ALoad);
  EXPECT_EQ(UseClobber, MSSA.getMemoryAccess(FirstStore));
}

// Test that our walker properly handles loads with the invariant group
// attribute. It's a bit hacky, since we add the invariant attribute *after*
// building MSSA. Otherwise, the use optimizer will optimize it for us, which
// isn't what we want.
// FIXME: It may be easier/cleaner to just add an 'optimize uses?' flag to MSSA.
TEST_F(MemorySSATest, WalkerInvariantLoadOpt) {
  F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "", F));
  Type *Int8 = Type::getInt8Ty(C);
  Constant *One = ConstantInt::get(Int8, 1);
  Value *AllocA = B.CreateAlloca(Int8, One, "");

  Instruction *Store = B.CreateStore(One, AllocA);
  Instruction *Load = B.CreateLoad(Int8, AllocA);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;

  auto *LoadMA = cast<MemoryUse>(MSSA.getMemoryAccess(Load));
  auto *StoreMA = cast<MemoryDef>(MSSA.getMemoryAccess(Store));
  EXPECT_EQ(LoadMA->getDefiningAccess(), StoreMA);

  // ...At the time of writing, no cache should exist for LoadMA. Be a bit
  // flexible to future changes.
  Walker->invalidateInfo(LoadMA);
  Load->setMetadata(LLVMContext::MD_invariant_load, MDNode::get(C, {}));

  MemoryAccess *LoadClobber = Walker->getClobberingMemoryAccess(LoadMA);
  EXPECT_EQ(LoadClobber, MSSA.getLiveOnEntryDef());
}

// Test loads get reoptimized properly by the walker.
TEST_F(MemorySSATest, WalkerReopt) {
  F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "", F));
  Type *Int8 = Type::getInt8Ty(C);
  Value *AllocaA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
  Instruction *SIA = B.CreateStore(ConstantInt::get(Int8, 0), AllocaA);
  Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
  Instruction *SIB = B.CreateStore(ConstantInt::get(Int8, 0), AllocaB);
  Instruction *LIA = B.CreateLoad(Int8, AllocaA);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;
  MemorySSAUpdater Updater(&MSSA);

  MemoryAccess *LoadClobber = Walker->getClobberingMemoryAccess(LIA);
  MemoryUse *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(LIA));
  EXPECT_EQ(LoadClobber, MSSA.getMemoryAccess(SIA));
  EXPECT_TRUE(MSSA.isLiveOnEntryDef(Walker->getClobberingMemoryAccess(SIA)));
  Updater.removeMemoryAccess(LoadAccess);

  // Create the load memory access pointing to an unoptimized place.
  MemoryUse *NewLoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
      LIA, MSSA.getMemoryAccess(SIB), LIA->getParent(), MemorySSA::End));
  // This should it cause it to be optimized
  EXPECT_EQ(Walker->getClobberingMemoryAccess(NewLoadAccess), LoadClobber);
  EXPECT_EQ(NewLoadAccess->getDefiningAccess(), LoadClobber);
}

// Test out MemorySSAUpdater::moveBefore
TEST_F(MemorySSATest, MoveAboveMemoryDef) {
  F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "", F));

  Type *Int8 = Type::getInt8Ty(C);
  Value *A = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
  Value *B_ = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
  Value *C = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "C");

  StoreInst *StoreA0 = B.CreateStore(ConstantInt::get(Int8, 0), A);
  StoreInst *StoreB = B.CreateStore(ConstantInt::get(Int8, 0), B_);
  LoadInst *LoadB = B.CreateLoad(Int8, B_);
  StoreInst *StoreA1 = B.CreateStore(ConstantInt::get(Int8, 4), A);
  StoreInst *StoreC = B.CreateStore(ConstantInt::get(Int8, 4), C);
  StoreInst *StoreA2 = B.CreateStore(ConstantInt::get(Int8, 4), A);
  LoadInst *LoadC = B.CreateLoad(Int8, C);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker &Walker = *Analyses->Walker;

  MemorySSAUpdater Updater(&MSSA);
  StoreC->moveBefore(StoreB);
  Updater.moveBefore(cast<MemoryDef>(MSSA.getMemoryAccess(StoreC)),
                     cast<MemoryDef>(MSSA.getMemoryAccess(StoreB)));

  MSSA.verifyMemorySSA();

  EXPECT_EQ(MSSA.getMemoryAccess(StoreB)->getDefiningAccess(),
            MSSA.getMemoryAccess(StoreC));
  EXPECT_EQ(MSSA.getMemoryAccess(StoreC)->getDefiningAccess(),
            MSSA.getMemoryAccess(StoreA0));
  EXPECT_EQ(MSSA.getMemoryAccess(StoreA2)->getDefiningAccess(),
            MSSA.getMemoryAccess(StoreA1));
  EXPECT_EQ(Walker.getClobberingMemoryAccess(LoadB),
            MSSA.getMemoryAccess(StoreB));
  EXPECT_EQ(Walker.getClobberingMemoryAccess(LoadC),
            MSSA.getMemoryAccess(StoreC));

  // exercise block numbering
  EXPECT_TRUE(MSSA.locallyDominates(MSSA.getMemoryAccess(StoreC),
                                    MSSA.getMemoryAccess(StoreB)));
  EXPECT_TRUE(MSSA.locallyDominates(MSSA.getMemoryAccess(StoreA1),
                                    MSSA.getMemoryAccess(StoreA2)));
}

TEST_F(MemorySSATest, Irreducible) {
  // Create the equivalent of
  // x = something
  // if (...)
  //    goto second_loop_entry
  // while (...) {
  // second_loop_entry:
  // }
  // use(x)

  SmallVector<PHINode *, 8> Inserted;
  IRBuilder<> B(C);
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);

  // Make blocks
  BasicBlock *IfBB = BasicBlock::Create(C, "if", F);
  BasicBlock *LoopStartBB = BasicBlock::Create(C, "loopstart", F);
  BasicBlock *LoopMainBB = BasicBlock::Create(C, "loopmain", F);
  BasicBlock *AfterLoopBB = BasicBlock::Create(C, "afterloop", F);
  B.SetInsertPoint(IfBB);
  B.CreateCondBr(B.getTrue(), LoopMainBB, LoopStartBB);
  B.SetInsertPoint(LoopStartBB);
  B.CreateBr(LoopMainBB);
  B.SetInsertPoint(LoopMainBB);
  B.CreateCondBr(B.getTrue(), LoopStartBB, AfterLoopBB);
  B.SetInsertPoint(AfterLoopBB);
  Argument *FirstArg = &*F->arg_begin();
  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAUpdater Updater(&MSSA);
  // Create the load memory acccess
  LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), FirstArg);
  MemoryUse *LoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
      LoadInst, nullptr, AfterLoopBB, MemorySSA::Beginning));
  Updater.insertUse(LoadAccess);
  MSSA.verifyMemorySSA();
}

TEST_F(MemorySSATest, MoveToBeforeLiveOnEntryInvalidatesCache) {
  // Create:
  //   %1 = alloca i8
  //   ; 1 = MemoryDef(liveOnEntry)
  //   store i8 0, i8* %1
  //   ; 2 = MemoryDef(1)
  //   store i8 0, i8* %1
  //
  // ...And be sure that MSSA's caching doesn't give us `1` for the clobber of
  // `2` after `1` is removed.
  IRBuilder<> B(C);
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);

  BasicBlock *Entry = BasicBlock::Create(C, "if", F);
  B.SetInsertPoint(Entry);

  Value *A = B.CreateAlloca(B.getInt8Ty());
  StoreInst *StoreA = B.CreateStore(B.getInt8(0), A);
  StoreInst *StoreB = B.CreateStore(B.getInt8(0), A);

  setupAnalyses();

  MemorySSA &MSSA = *Analyses->MSSA;

  auto *DefA = cast<MemoryDef>(MSSA.getMemoryAccess(StoreA));
  auto *DefB = cast<MemoryDef>(MSSA.getMemoryAccess(StoreB));

  MemoryAccess *BClobber = MSSA.getWalker()->getClobberingMemoryAccess(DefB);
  ASSERT_EQ(DefA, BClobber);

  MemorySSAUpdater(&MSSA).removeMemoryAccess(DefA);
  StoreA->eraseFromParent();

  EXPECT_EQ(DefB->getDefiningAccess(), MSSA.getLiveOnEntryDef());

  EXPECT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(DefB),
            MSSA.getLiveOnEntryDef())
      << "(DefA = " << DefA << ")";
}

TEST_F(MemorySSATest, RemovingDefInvalidatesCache) {
  // Create:
  //   %x = alloca i8
  //   %y = alloca i8
  //   ; 1 = MemoryDef(liveOnEntry)
  //   store i8 0, i8* %x
  //   ; 2 = MemoryDef(1)
  //   store i8 0, i8* %y
  //   ; 3 = MemoryDef(2)
  //   store i8 0, i8* %x
  //
  // And be sure that MSSA's caching handles the removal of def `1`
  // appropriately.
  IRBuilder<> B(C);
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);

  BasicBlock *Entry = BasicBlock::Create(C, "if", F);
  B.SetInsertPoint(Entry);

  Value *X = B.CreateAlloca(B.getInt8Ty());
  Value *Y = B.CreateAlloca(B.getInt8Ty());
  StoreInst *StoreX1 = B.CreateStore(B.getInt8(0), X);
  StoreInst *StoreY = B.CreateStore(B.getInt8(0), Y);
  StoreInst *StoreX2 = B.CreateStore(B.getInt8(0), X);

  setupAnalyses();

  MemorySSA &MSSA = *Analyses->MSSA;

  auto *DefX1 = cast<MemoryDef>(MSSA.getMemoryAccess(StoreX1));
  auto *DefY = cast<MemoryDef>(MSSA.getMemoryAccess(StoreY));
  auto *DefX2 = cast<MemoryDef>(MSSA.getMemoryAccess(StoreX2));

  EXPECT_EQ(DefX2->getDefiningAccess(), DefY);
  MemoryAccess *X2Clobber = MSSA.getWalker()->getClobberingMemoryAccess(DefX2);
  ASSERT_EQ(DefX1, X2Clobber);

  MemorySSAUpdater(&MSSA).removeMemoryAccess(DefX1);
  StoreX1->eraseFromParent();

  EXPECT_EQ(DefX2->getDefiningAccess(), DefY);
  EXPECT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(DefX2),
            MSSA.getLiveOnEntryDef())
      << "(DefX1 = " << DefX1 << ")";
}

// Test Must alias for optimized uses
TEST_F(MemorySSATest, TestLoadMustAlias) {
  F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "", F));
  Type *Int8 = Type::getInt8Ty(C);
  Value *AllocaA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
  Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");

  B.CreateStore(ConstantInt::get(Int8, 1), AllocaB);
  // Check load from LOE
  LoadInst *LA1 = B.CreateLoad(Int8, AllocaA, "");
  // Check load alias cached for second load
  LoadInst *LA2 = B.CreateLoad(Int8, AllocaA, "");

  B.CreateStore(ConstantInt::get(Int8, 1), AllocaA);
  // Check load from store/def
  LoadInst *LA3 = B.CreateLoad(Int8, AllocaA, "");
  // Check load alias cached for second load
  LoadInst *LA4 = B.CreateLoad(Int8, AllocaA, "");

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;

  unsigned I = 0;
  for (LoadInst *V : {LA1, LA2}) {
    MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
    EXPECT_EQ(MemUse->getOptimizedAccessType(), None)
        << "Load " << I << " doesn't have the correct alias information";
    // EXPECT_EQ expands such that if we increment I above, it won't get
    // incremented except when we try to print the error message.
    ++I;
  }
  for (LoadInst *V : {LA3, LA4}) {
    MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
    EXPECT_EQ(MemUse->getOptimizedAccessType(), MustAlias)
        << "Load " << I << " doesn't have the correct alias information";
    // EXPECT_EQ expands such that if we increment I above, it won't get
    // incremented except when we try to print the error message.
    ++I;
  }
}

// Test Must alias for optimized defs.
TEST_F(MemorySSATest, TestStoreMustAlias) {
  F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "", F));
  Type *Int8 = Type::getInt8Ty(C);
  Value *AllocaA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
  Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
  StoreInst *SA1 = B.CreateStore(ConstantInt::get(Int8, 1), AllocaA);
  StoreInst *SB1 = B.CreateStore(ConstantInt::get(Int8, 1), AllocaB);
  StoreInst *SA2 = B.CreateStore(ConstantInt::get(Int8, 2), AllocaA);
  StoreInst *SB2 = B.CreateStore(ConstantInt::get(Int8, 2), AllocaB);
  StoreInst *SA3 = B.CreateStore(ConstantInt::get(Int8, 3), AllocaA);
  StoreInst *SB3 = B.CreateStore(ConstantInt::get(Int8, 3), AllocaB);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;

  unsigned I = 0;
  for (StoreInst *V : {SA1, SB1, SA2, SB2, SA3, SB3}) {
    MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V));
    EXPECT_EQ(MemDef->isOptimized(), false)
        << "Store " << I << " is optimized from the start?";
    EXPECT_EQ(MemDef->getOptimizedAccessType(), MayAlias)
        << "Store " << I
        << " has correct alias information before being optimized?";
    if (V == SA1)
      Walker->getClobberingMemoryAccess(V);
    else {
      MemoryAccess *Def = MemDef->getDefiningAccess();
      MemoryAccess *Clob = Walker->getClobberingMemoryAccess(V);
      EXPECT_NE(Def, Clob) << "Store " << I
                           << " has Defining Access equal to Clobbering Access";
    }
    EXPECT_EQ(MemDef->isOptimized(), true)
        << "Store " << I << " was not optimized";
    if (I == 0 || I == 1)
      EXPECT_EQ(MemDef->getOptimizedAccessType(), None)
          << "Store " << I << " doesn't have the correct alias information";
    else
      EXPECT_EQ(MemDef->getOptimizedAccessType(), MustAlias)
          << "Store " << I << " doesn't have the correct alias information";
    // EXPECT_EQ expands such that if we increment I above, it won't get
    // incremented except when we try to print the error message.
    ++I;
  }
}

// Test May alias for optimized uses.
TEST_F(MemorySSATest, TestLoadMayAlias) {
  F = Function::Create(FunctionType::get(B.getVoidTy(),
                                         {B.getInt8PtrTy(), B.getInt8PtrTy()},
                                         false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "", F));
  Type *Int8 = Type::getInt8Ty(C);
  auto *ArgIt = F->arg_begin();
  Argument *PointerA = &*ArgIt;
  Argument *PointerB = &*(++ArgIt);
  B.CreateStore(ConstantInt::get(Int8, 1), PointerB);
  LoadInst *LA1 = B.CreateLoad(Int8, PointerA, "");
  B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
  LoadInst *LB1 = B.CreateLoad(Int8, PointerB, "");
  B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
  LoadInst *LA2 = B.CreateLoad(Int8, PointerA, "");
  B.CreateStore(ConstantInt::get(Int8, 0), PointerB);
  LoadInst *LB2 = B.CreateLoad(Int8, PointerB, "");

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;

  unsigned I = 0;
  for (LoadInst *V : {LA1, LB1}) {
    MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
    EXPECT_EQ(MemUse->getOptimizedAccessType(), MayAlias)
        << "Load " << I << " doesn't have the correct alias information";
    // EXPECT_EQ expands such that if we increment I above, it won't get
    // incremented except when we try to print the error message.
    ++I;
  }
  for (LoadInst *V : {LA2, LB2}) {
    MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
    EXPECT_EQ(MemUse->getOptimizedAccessType(), MustAlias)
        << "Load " << I << " doesn't have the correct alias information";
    // EXPECT_EQ expands such that if we increment I above, it won't get
    // incremented except when we try to print the error message.
    ++I;
  }
}

// Test May alias for optimized defs.
TEST_F(MemorySSATest, TestStoreMayAlias) {
  F = Function::Create(FunctionType::get(B.getVoidTy(),
                                         {B.getInt8PtrTy(), B.getInt8PtrTy()},
                                         false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "", F));
  Type *Int8 = Type::getInt8Ty(C);
  auto *ArgIt = F->arg_begin();
  Argument *PointerA = &*ArgIt;
  Argument *PointerB = &*(++ArgIt);
  Value *AllocaC = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "C");
  // Store into arg1, must alias because it's LOE => must
  StoreInst *SA1 = B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
  // Store into arg2, may alias store to arg1 => may
  StoreInst *SB1 = B.CreateStore(ConstantInt::get(Int8, 1), PointerB);
  // Store into aloca, no alias with args, so must alias LOE => must
  StoreInst *SC1 = B.CreateStore(ConstantInt::get(Int8, 2), AllocaC);
  // Store into arg1, may alias store to arg2 => may
  StoreInst *SA2 = B.CreateStore(ConstantInt::get(Int8, 3), PointerA);
  // Store into arg2, may alias store to arg1 => may
  StoreInst *SB2 = B.CreateStore(ConstantInt::get(Int8, 4), PointerB);
  // Store into aloca, no alias with args, so must alias SC1 => must
  StoreInst *SC2 = B.CreateStore(ConstantInt::get(Int8, 5), AllocaC);
  // Store into arg2, must alias store to arg2 => must
  StoreInst *SB3 = B.CreateStore(ConstantInt::get(Int8, 6), PointerB);
  std::initializer_list<StoreInst *> Sts = {SA1, SB1, SC1, SA2, SB2, SC2, SB3};

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;

  unsigned I = 0;
  for (StoreInst *V : Sts) {
    MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V));
    EXPECT_EQ(MemDef->isOptimized(), false)
        << "Store " << I << " is optimized from the start?";
    EXPECT_EQ(MemDef->getOptimizedAccessType(), MayAlias)
        << "Store " << I
        << " has correct alias information before being optimized?";
    ++I;
  }

  for (StoreInst *V : Sts)
    Walker->getClobberingMemoryAccess(V);

  I = 0;
  for (StoreInst *V : Sts) {
    MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V));
    EXPECT_EQ(MemDef->isOptimized(), true)
        << "Store " << I << " was not optimized";
    if (I == 1 || I == 3 || I == 4)
      EXPECT_EQ(MemDef->getOptimizedAccessType(), MayAlias)
          << "Store " << I << " doesn't have the correct alias information";
    else if (I == 0 || I == 2)
      EXPECT_EQ(MemDef->getOptimizedAccessType(), None)
          << "Store " << I << " doesn't have the correct alias information";
    else
      EXPECT_EQ(MemDef->getOptimizedAccessType(), MustAlias)
          << "Store " << I << " doesn't have the correct alias information";
    // EXPECT_EQ expands such that if we increment I above, it won't get
    // incremented except when we try to print the error message.
    ++I;
  }
}

TEST_F(MemorySSATest, LifetimeMarkersAreClobbers) {
  // Example code:
  // define void @a(i8* %foo) {
  //   %bar = getelementptr i8, i8* %foo, i64 1
  //   store i8 0, i8* %foo
  //   store i8 0, i8* %bar
  //   call void @llvm.lifetime.end.p0i8(i64 8, i32* %p)
  //   call void @llvm.lifetime.start.p0i8(i64 8, i32* %p)
  //   store i8 0, i8* %foo
  //   store i8 0, i8* %bar
  //   ret void
  // }
  //
  // Patterns like this are possible after inlining; the stores to %foo and %bar
  // should both be clobbered by the lifetime.start call if they're dominated by
  // it.

  IRBuilder<> B(C);
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);

  // Make blocks
  BasicBlock *Entry = BasicBlock::Create(C, "entry", F);

  B.SetInsertPoint(Entry);
  Value *Foo = &*F->arg_begin();

  Value *Bar = B.CreateGEP(B.getInt8Ty(), Foo, B.getInt64(1), "bar");

  B.CreateStore(B.getInt8(0), Foo);
  B.CreateStore(B.getInt8(0), Bar);

  auto GetLifetimeIntrinsic = [&](Intrinsic::ID ID) {
    return Intrinsic::getDeclaration(&M, ID, {Foo->getType()});
  };

  B.CreateCall(GetLifetimeIntrinsic(Intrinsic::lifetime_end),
               {B.getInt64(2), Foo});
  Instruction *LifetimeStart = B.CreateCall(
      GetLifetimeIntrinsic(Intrinsic::lifetime_start), {B.getInt64(2), Foo});

  Instruction *FooStore = B.CreateStore(B.getInt8(0), Foo);
  Instruction *BarStore = B.CreateStore(B.getInt8(0), Bar);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;

  MemoryAccess *LifetimeStartAccess = MSSA.getMemoryAccess(LifetimeStart);
  ASSERT_NE(LifetimeStartAccess, nullptr);

  MemoryAccess *FooAccess = MSSA.getMemoryAccess(FooStore);
  ASSERT_NE(FooAccess, nullptr);

  MemoryAccess *BarAccess = MSSA.getMemoryAccess(BarStore);
  ASSERT_NE(BarAccess, nullptr);

  MemoryAccess *FooClobber =
      MSSA.getWalker()->getClobberingMemoryAccess(FooAccess);
  EXPECT_EQ(FooClobber, LifetimeStartAccess);

  MemoryAccess *BarClobber =
      MSSA.getWalker()->getClobberingMemoryAccess(BarAccess);
  EXPECT_EQ(BarClobber, LifetimeStartAccess);
}

TEST_F(MemorySSATest, DefOptimizationsAreInvalidatedOnMoving) {
  IRBuilder<> B(C);
  F = Function::Create(FunctionType::get(B.getVoidTy(), {B.getInt1Ty()}, false),
                       GlobalValue::ExternalLinkage, "F", &M);

  // Make a CFG like
  //     entry
  //      / \
  //     a   b
  //      \ /
  //       c
  //
  // Put a def in A and a def in B, move the def from A -> B, observe as the
  // optimization is invalidated.
  BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
  BasicBlock *BlockA = BasicBlock::Create(C, "a", F);
  BasicBlock *BlockB = BasicBlock::Create(C, "b", F);
  BasicBlock *BlockC = BasicBlock::Create(C, "c", F);

  B.SetInsertPoint(Entry);
  Type *Int8 = Type::getInt8Ty(C);
  Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "alloc");
  StoreInst *StoreEntry = B.CreateStore(B.getInt8(0), Alloca);
  B.CreateCondBr(B.getTrue(), BlockA, BlockB);

  B.SetInsertPoint(BlockA);
  StoreInst *StoreA = B.CreateStore(B.getInt8(1), Alloca);
  B.CreateBr(BlockC);

  B.SetInsertPoint(BlockB);
  StoreInst *StoreB = B.CreateStore(B.getInt8(2), Alloca);
  B.CreateBr(BlockC);

  B.SetInsertPoint(BlockC);
  B.CreateUnreachable();

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;

  auto *AccessEntry = cast<MemoryDef>(MSSA.getMemoryAccess(StoreEntry));
  auto *StoreAEntry = cast<MemoryDef>(MSSA.getMemoryAccess(StoreA));
  auto *StoreBEntry = cast<MemoryDef>(MSSA.getMemoryAccess(StoreB));

  ASSERT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(StoreAEntry),
            AccessEntry);
  ASSERT_TRUE(StoreAEntry->isOptimized());

  ASSERT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(StoreBEntry),
            AccessEntry);
  ASSERT_TRUE(StoreBEntry->isOptimized());

  // Note that if we did InsertionPlace::Beginning, we don't go out of our way
  // to invalidate the cache for StoreBEntry. If the user wants to actually do
  // moves like these, it's up to them to ensure that nearby cache entries are
  // correctly invalidated (which, in general, requires walking all instructions
  // that the moved instruction dominates. So we probably shouldn't be doing
  // moves like this in general. Still, works as a test-case. ;) )
  MemorySSAUpdater(&MSSA).moveToPlace(StoreAEntry, BlockB,
                                      MemorySSA::InsertionPlace::End);
  ASSERT_FALSE(StoreAEntry->isOptimized());
  ASSERT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(StoreAEntry),
            StoreBEntry);
}

TEST_F(MemorySSATest, TestOptimizedDefsAreProperUses) {
  F = Function::Create(FunctionType::get(B.getVoidTy(),
                                         {B.getInt8PtrTy(), B.getInt8PtrTy()},
                                         false),
                       GlobalValue::ExternalLinkage, "F", &M);
  B.SetInsertPoint(BasicBlock::Create(C, "", F));
  Type *Int8 = Type::getInt8Ty(C);
  Value *AllocA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
  Value *AllocB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");

  StoreInst *StoreA = B.CreateStore(ConstantInt::get(Int8, 0), AllocA);
  StoreInst *StoreB = B.CreateStore(ConstantInt::get(Int8, 1), AllocB);
  StoreInst *StoreA2 = B.CreateStore(ConstantInt::get(Int8, 2), AllocA);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;

  // If these don't hold, there's no chance of the test result being useful.
  ASSERT_EQ(Walker->getClobberingMemoryAccess(StoreA),
            MSSA.getLiveOnEntryDef());
  ASSERT_EQ(Walker->getClobberingMemoryAccess(StoreB),
            MSSA.getLiveOnEntryDef());
  auto *StoreAAccess = cast<MemoryDef>(MSSA.getMemoryAccess(StoreA));
  auto *StoreA2Access = cast<MemoryDef>(MSSA.getMemoryAccess(StoreA2));
  ASSERT_EQ(Walker->getClobberingMemoryAccess(StoreA2), StoreAAccess);
  ASSERT_EQ(StoreA2Access->getOptimized(), StoreAAccess);

  auto *StoreBAccess = cast<MemoryDef>(MSSA.getMemoryAccess(StoreB));
  ASSERT_LT(StoreAAccess->getID(), StoreBAccess->getID());
  ASSERT_LT(StoreBAccess->getID(), StoreA2Access->getID());

  auto SortVecByID = [](std::vector<const MemoryDef *> &Defs) {
    llvm::sort(Defs, [](const MemoryDef *LHS, const MemoryDef *RHS) {
      return LHS->getID() < RHS->getID();
    });
  };

  auto SortedUserList = [&](const MemoryDef *MD) {
    std::vector<const MemoryDef *> Result;
    transform(MD->users(), std::back_inserter(Result),
              [](const User *U) { return cast<MemoryDef>(U); });
    SortVecByID(Result);
    return Result;
  };

  // Use std::vectors, since they have nice pretty-printing if the test fails.
  // Parens are necessary because EXPECT_EQ is a macro, and we have commas in
  // our init lists...
  EXPECT_EQ(SortedUserList(StoreAAccess),
            (std::vector<const MemoryDef *>{StoreBAccess, StoreA2Access}));

  EXPECT_EQ(SortedUserList(StoreBAccess),
            std::vector<const MemoryDef *>{StoreA2Access});

  // StoreAAccess should be present twice, since it uses liveOnEntry for both
  // its defining and optimized accesses. This is a bit awkward, and is not
  // relied upon anywhere at the moment. If this is painful, we can fix it.
  EXPECT_EQ(SortedUserList(cast<MemoryDef>(MSSA.getLiveOnEntryDef())),
            (std::vector<const MemoryDef *>{StoreAAccess, StoreAAccess,
                                            StoreBAccess}));
}

//   entry
//     |
//   header
//    / \
// body  |
//    \ /
//    exit
// header:
//  ; 1 = MemoryDef(liveOnEntry)
// body:
//  ; 2 = MemoryDef(1)
// exit:
//  ; 3 = MemoryPhi({body, 2}, {header, 1})
//  ; 4 = MemoryDef(3); optimized to 3, cannot optimize thorugh phi.
//  Insert edge: entry -> exit, check mssa Update is correct.
TEST_F(MemorySSATest, TestAddedEdgeToBlockWithPhiNotOpt) {
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  Argument *PointerArg = &*F->arg_begin();
  BasicBlock *Entry(BasicBlock::Create(C, "entry", F));
  BasicBlock *Header(BasicBlock::Create(C, "header", F));
  BasicBlock *Body(BasicBlock::Create(C, "body", F));
  BasicBlock *Exit(BasicBlock::Create(C, "exit", F));
  B.SetInsertPoint(Entry);
  BranchInst::Create(Header, Entry);
  B.SetInsertPoint(Header);
  B.CreateStore(B.getInt8(16), PointerArg);
  B.CreateCondBr(B.getTrue(), Exit, Body);
  B.SetInsertPoint(Body);
  B.CreateStore(B.getInt8(16), PointerArg);
  BranchInst::Create(Exit, Body);
  B.SetInsertPoint(Exit);
  StoreInst *S1 = B.CreateStore(B.getInt8(16), PointerArg);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;
  std::unique_ptr<MemorySSAUpdater> MSSAU =
      make_unique<MemorySSAUpdater>(&MSSA);

  MemoryPhi *Phi = MSSA.getMemoryAccess(Exit);
  EXPECT_EQ(Phi, Walker->getClobberingMemoryAccess(S1));

  // Alter CFG, add edge: entry -> exit
  Entry->getTerminator()->eraseFromParent();
  B.SetInsertPoint(Entry);
  B.CreateCondBr(B.getTrue(), Header, Exit);
  SmallVector<CFGUpdate, 1> Updates;
  Updates.push_back({cfg::UpdateKind::Insert, Entry, Exit});
  Analyses->DT.applyUpdates(Updates);
  MSSAU->applyInsertUpdates(Updates, Analyses->DT);
  EXPECT_EQ(Phi, Walker->getClobberingMemoryAccess(S1));
}

//   entry
//     |
//   header
//    / \
// body  |
//    \ /
//    exit
// header:
//  ; 1 = MemoryDef(liveOnEntry)
// body:
//  ; 2 = MemoryDef(1)
// exit:
//  ; 3 = MemoryPhi({body, 2}, {header, 1})
//  ; 4 = MemoryDef(3); optimize this to 1 now, added edge should invalidate
//  the optimized access.
//  Insert edge: entry -> exit, check mssa Update is correct.
TEST_F(MemorySSATest, TestAddedEdgeToBlockWithPhiOpt) {
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  Argument *PointerArg = &*F->arg_begin();
  Type *Int8 = Type::getInt8Ty(C);
  BasicBlock *Entry(BasicBlock::Create(C, "entry", F));
  BasicBlock *Header(BasicBlock::Create(C, "header", F));
  BasicBlock *Body(BasicBlock::Create(C, "body", F));
  BasicBlock *Exit(BasicBlock::Create(C, "exit", F));

  B.SetInsertPoint(Entry);
  Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
  BranchInst::Create(Header, Entry);

  B.SetInsertPoint(Header);
  StoreInst *S1 = B.CreateStore(B.getInt8(16), PointerArg);
  B.CreateCondBr(B.getTrue(), Exit, Body);

  B.SetInsertPoint(Body);
  B.CreateStore(ConstantInt::get(Int8, 0), Alloca);
  BranchInst::Create(Exit, Body);

  B.SetInsertPoint(Exit);
  StoreInst *S2 = B.CreateStore(B.getInt8(16), PointerArg);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  MemorySSAWalker *Walker = Analyses->Walker;
  std::unique_ptr<MemorySSAUpdater> MSSAU =
      make_unique<MemorySSAUpdater>(&MSSA);

  MemoryDef *DefS1 = cast<MemoryDef>(MSSA.getMemoryAccess(S1));
  EXPECT_EQ(DefS1, Walker->getClobberingMemoryAccess(S2));

  // Alter CFG, add edge: entry -> exit
  Entry->getTerminator()->eraseFromParent();
  B.SetInsertPoint(Entry);
  B.CreateCondBr(B.getTrue(), Header, Exit);
  SmallVector<CFGUpdate, 1> Updates;
  Updates.push_back({cfg::UpdateKind::Insert, Entry, Exit});
  Analyses->DT.applyUpdates(Updates);
  MSSAU->applyInsertUpdates(Updates, Analyses->DT);

  MemoryPhi *Phi = MSSA.getMemoryAccess(Exit);
  EXPECT_EQ(Phi, Walker->getClobberingMemoryAccess(S2));
}

//   entry
//    /  |
//   a   |
//  / \  |
//  b c  f
//  \ /  |
//   d   |
//    \ /
//     e
// f:
//  ; 1 = MemoryDef(liveOnEntry)
// e:
//  ; 2 = MemoryPhi({d, liveOnEntry}, {f, 1})
//
// Insert edge: f -> c, check update is correct.
// After update:
// f:
//  ; 1 = MemoryDef(liveOnEntry)
// c:
//  ; 3 = MemoryPhi({a, liveOnEntry}, {f, 1})
// d:
//  ; 4 = MemoryPhi({b, liveOnEntry}, {c, 3})
// e:
//  ; 2 = MemoryPhi({d, 4}, {f, 1})
TEST_F(MemorySSATest, TestAddedEdgeToBlockWithNoPhiAddNewPhis) {
  F = Function::Create(
      FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
      GlobalValue::ExternalLinkage, "F", &M);
  Argument *PointerArg = &*F->arg_begin();
  BasicBlock *Entry(BasicBlock::Create(C, "entry", F));
  BasicBlock *ABlock(BasicBlock::Create(C, "a", F));
  BasicBlock *BBlock(BasicBlock::Create(C, "b", F));
  BasicBlock *CBlock(BasicBlock::Create(C, "c", F));
  BasicBlock *DBlock(BasicBlock::Create(C, "d", F));
  BasicBlock *EBlock(BasicBlock::Create(C, "e", F));
  BasicBlock *FBlock(BasicBlock::Create(C, "f", F));

  B.SetInsertPoint(Entry);
  B.CreateCondBr(B.getTrue(), ABlock, FBlock);
  B.SetInsertPoint(ABlock);
  B.CreateCondBr(B.getTrue(), BBlock, CBlock);
  B.SetInsertPoint(BBlock);
  BranchInst::Create(DBlock, BBlock);
  B.SetInsertPoint(CBlock);
  BranchInst::Create(DBlock, CBlock);
  B.SetInsertPoint(DBlock);
  BranchInst::Create(EBlock, DBlock);
  B.SetInsertPoint(FBlock);
  B.CreateStore(B.getInt8(16), PointerArg);
  BranchInst::Create(EBlock, FBlock);

  setupAnalyses();
  MemorySSA &MSSA = *Analyses->MSSA;
  std::unique_ptr<MemorySSAUpdater> MSSAU =
      make_unique<MemorySSAUpdater>(&MSSA);

  // Alter CFG, add edge: f -> c
  FBlock->getTerminator()->eraseFromParent();
  B.SetInsertPoint(FBlock);
  B.CreateCondBr(B.getTrue(), CBlock, EBlock);
  SmallVector<CFGUpdate, 1> Updates;
  Updates.push_back({cfg::UpdateKind::Insert, FBlock, CBlock});
  Analyses->DT.applyUpdates(Updates);
  MSSAU->applyInsertUpdates(Updates, Analyses->DT);

  MemoryPhi *MPC = MSSA.getMemoryAccess(CBlock);
  EXPECT_NE(MPC, nullptr);
  MemoryPhi *MPD = MSSA.getMemoryAccess(DBlock);
  EXPECT_NE(MPD, nullptr);
  MemoryPhi *MPE = MSSA.getMemoryAccess(EBlock);
  EXPECT_EQ(MPD, MPE->getIncomingValueForBlock(DBlock));
}
