//===- llvm/unittest/Analysis/LoopPassManagerTest.cpp - LPM tests ---------===//
//
// 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/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/SourceMgr.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {

using testing::DoDefault;
using testing::Return;
using testing::Expectation;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::_;

template <typename DerivedT, typename IRUnitT,
          typename AnalysisManagerT = AnalysisManager<IRUnitT>,
          typename... ExtraArgTs>
class MockAnalysisHandleBase {
public:
  class Analysis : public AnalysisInfoMixin<Analysis> {
    friend AnalysisInfoMixin<Analysis>;
    friend MockAnalysisHandleBase;
    static AnalysisKey Key;

    DerivedT *Handle;

    Analysis(DerivedT &Handle) : Handle(&Handle) {
      static_assert(std::is_base_of<MockAnalysisHandleBase, DerivedT>::value,
                    "Must pass the derived type to this template!");
    }

  public:
    class Result {
      friend MockAnalysisHandleBase;

      DerivedT *Handle;

      Result(DerivedT &Handle) : Handle(&Handle) {}

    public:
      // Forward invalidation events to the mock handle.
      bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA,
                      typename AnalysisManagerT::Invalidator &Inv) {
        return Handle->invalidate(IR, PA, Inv);
      }
    };

    Result run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs) {
      return Handle->run(IR, AM, ExtraArgs...);
    }
  };

  Analysis getAnalysis() { return Analysis(static_cast<DerivedT &>(*this)); }
  typename Analysis::Result getResult() {
    return typename Analysis::Result(static_cast<DerivedT &>(*this));
  }

protected:
  // FIXME: MSVC seems unable to handle a lambda argument to Invoke from within
  // the template, so we use a boring static function.
  static bool invalidateCallback(IRUnitT &IR, const PreservedAnalyses &PA,
                                 typename AnalysisManagerT::Invalidator &Inv) {
    auto PAC = PA.template getChecker<Analysis>();
    return !PAC.preserved() &&
           !PAC.template preservedSet<AllAnalysesOn<IRUnitT>>();
  }

  /// Derived classes should call this in their constructor to set up default
  /// mock actions. (We can't do this in our constructor because this has to
  /// run after the DerivedT is constructed.)
  void setDefaults() {
    ON_CALL(static_cast<DerivedT &>(*this),
            run(_, _, testing::Matcher<ExtraArgTs>(_)...))
        .WillByDefault(Return(this->getResult()));
    ON_CALL(static_cast<DerivedT &>(*this), invalidate(_, _, _))
        .WillByDefault(Invoke(&invalidateCallback));
  }
};

template <typename DerivedT, typename IRUnitT, typename AnalysisManagerT,
          typename... ExtraArgTs>
AnalysisKey MockAnalysisHandleBase<DerivedT, IRUnitT, AnalysisManagerT,
                                   ExtraArgTs...>::Analysis::Key;

/// Mock handle for loop analyses.
///
/// This is provided as a template accepting an (optional) integer. Because
/// analyses are identified and queried by type, this allows constructing
/// multiple handles with distinctly typed nested 'Analysis' types that can be
/// registered and queried. If you want to register multiple loop analysis
/// passes, you'll need to instantiate this type with different values for I.
/// For example:
///
///   MockLoopAnalysisHandleTemplate<0> h0;
///   MockLoopAnalysisHandleTemplate<1> h1;
///   typedef decltype(h0)::Analysis Analysis0;
///   typedef decltype(h1)::Analysis Analysis1;
template <size_t I = static_cast<size_t>(-1)>
struct MockLoopAnalysisHandleTemplate
    : MockAnalysisHandleBase<MockLoopAnalysisHandleTemplate<I>, Loop,
                             LoopAnalysisManager,
                             LoopStandardAnalysisResults &> {
  typedef typename MockLoopAnalysisHandleTemplate::Analysis Analysis;

  MOCK_METHOD3_T(run, typename Analysis::Result(Loop &, LoopAnalysisManager &,
                                                LoopStandardAnalysisResults &));

  MOCK_METHOD3_T(invalidate, bool(Loop &, const PreservedAnalyses &,
                                  LoopAnalysisManager::Invalidator &));

  MockLoopAnalysisHandleTemplate() { this->setDefaults(); }
};

typedef MockLoopAnalysisHandleTemplate<> MockLoopAnalysisHandle;

struct MockFunctionAnalysisHandle
    : MockAnalysisHandleBase<MockFunctionAnalysisHandle, Function> {
  MOCK_METHOD2(run, Analysis::Result(Function &, FunctionAnalysisManager &));

  MOCK_METHOD3(invalidate, bool(Function &, const PreservedAnalyses &,
                                FunctionAnalysisManager::Invalidator &));

  MockFunctionAnalysisHandle() { setDefaults(); }
};

template <typename DerivedT, typename IRUnitT,
          typename AnalysisManagerT = AnalysisManager<IRUnitT>,
          typename... ExtraArgTs>
class MockPassHandleBase {
public:
  class Pass : public PassInfoMixin<Pass> {
    friend MockPassHandleBase;

    DerivedT *Handle;

    Pass(DerivedT &Handle) : Handle(&Handle) {
      static_assert(std::is_base_of<MockPassHandleBase, DerivedT>::value,
                    "Must pass the derived type to this template!");
    }

  public:
    PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM,
                          ExtraArgTs... ExtraArgs) {
      return Handle->run(IR, AM, ExtraArgs...);
    }
  };

  Pass getPass() { return Pass(static_cast<DerivedT &>(*this)); }

protected:
  /// Derived classes should call this in their constructor to set up default
  /// mock actions. (We can't do this in our constructor because this has to
  /// run after the DerivedT is constructed.)
  void setDefaults() {
    ON_CALL(static_cast<DerivedT &>(*this),
            run(_, _, testing::Matcher<ExtraArgTs>(_)...))
        .WillByDefault(Return(PreservedAnalyses::all()));
  }
};

struct MockLoopPassHandle
    : MockPassHandleBase<MockLoopPassHandle, Loop, LoopAnalysisManager,
                         LoopStandardAnalysisResults &, LPMUpdater &> {
  MOCK_METHOD4(run,
               PreservedAnalyses(Loop &, LoopAnalysisManager &,
                                 LoopStandardAnalysisResults &, LPMUpdater &));
  MockLoopPassHandle() { setDefaults(); }
};

struct MockLoopNestPassHandle
    : MockPassHandleBase<MockLoopNestPassHandle, LoopNest, LoopAnalysisManager,
                         LoopStandardAnalysisResults &, LPMUpdater &> {
  MOCK_METHOD4(run,
               PreservedAnalyses(LoopNest &, LoopAnalysisManager &,
                                 LoopStandardAnalysisResults &, LPMUpdater &));

  MockLoopNestPassHandle() { setDefaults(); }
};

struct MockFunctionPassHandle
    : MockPassHandleBase<MockFunctionPassHandle, Function> {
  MOCK_METHOD2(run, PreservedAnalyses(Function &, FunctionAnalysisManager &));

  MockFunctionPassHandle() { setDefaults(); }
};

struct MockModulePassHandle : MockPassHandleBase<MockModulePassHandle, Module> {
  MOCK_METHOD2(run, PreservedAnalyses(Module &, ModuleAnalysisManager &));

  MockModulePassHandle() { setDefaults(); }
};

/// Define a custom matcher for objects which support a 'getName' method
/// returning a StringRef.
///
/// LLVM often has IR objects or analysis objects which expose a StringRef name
/// and in tests it is convenient to match these by name for readability. This
/// matcher supports any type exposing a getName() method of this form.
///
/// It should be used as:
///
///   HasName("my_function")
///
/// No namespace or other qualification is required.
MATCHER_P(HasName, Name, "") {
  // The matcher's name and argument are printed in the case of failure, but we
  // also want to print out the name of the argument. This uses an implicitly
  // avaiable std::ostream, so we have to construct a std::string.
  *result_listener << "has name '" << arg.getName().str() << "'";
  return Name == arg.getName();
}

std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
  SMDiagnostic Err;
  return parseAssemblyString(IR, Err, C);
}

class LoopPassManagerTest : public ::testing::Test {
protected:
  LLVMContext Context;
  std::unique_ptr<Module> M;

  LoopAnalysisManager LAM;
  FunctionAnalysisManager FAM;
  ModuleAnalysisManager MAM;

  MockLoopAnalysisHandle MLAHandle;
  MockLoopPassHandle MLPHandle;
  MockLoopNestPassHandle MLNPHandle;
  MockFunctionPassHandle MFPHandle;
  MockModulePassHandle MMPHandle;

  static PreservedAnalyses
  getLoopAnalysisResult(Loop &L, LoopAnalysisManager &AM,
                        LoopStandardAnalysisResults &AR, LPMUpdater &) {
    (void)AM.getResult<MockLoopAnalysisHandle::Analysis>(L, AR);
    return PreservedAnalyses::all();
  };

public:
  LoopPassManagerTest()
      : M(parseIR(Context,
                  "define void @f(i1* %ptr) {\n"
                  "entry:\n"
                  "  br label %loop.0\n"
                  "loop.0:\n"
                  "  %cond.0 = load volatile i1, i1* %ptr\n"
                  "  br i1 %cond.0, label %loop.0.0.ph, label %end\n"
                  "loop.0.0.ph:\n"
                  "  br label %loop.0.0\n"
                  "loop.0.0:\n"
                  "  %cond.0.0 = load volatile i1, i1* %ptr\n"
                  "  br i1 %cond.0.0, label %loop.0.0, label %loop.0.1.ph\n"
                  "loop.0.1.ph:\n"
                  "  br label %loop.0.1\n"
                  "loop.0.1:\n"
                  "  %cond.0.1 = load volatile i1, i1* %ptr\n"
                  "  br i1 %cond.0.1, label %loop.0.1, label %loop.0.latch\n"
                  "loop.0.latch:\n"
                  "  br label %loop.0\n"
                  "end:\n"
                  "  ret void\n"
                  "}\n"
                  "\n"
                  "define void @g(i1* %ptr) {\n"
                  "entry:\n"
                  "  br label %loop.g.0\n"
                  "loop.g.0:\n"
                  "  %cond.0 = load volatile i1, i1* %ptr\n"
                  "  br i1 %cond.0, label %loop.g.0, label %end\n"
                  "end:\n"
                  "  ret void\n"
                  "}\n")),
        LAM(), FAM(), MAM() {
    // Register our mock analysis.
    LAM.registerPass([&] { return MLAHandle.getAnalysis(); });

    // We need DominatorTreeAnalysis for LoopAnalysis.
    FAM.registerPass([&] { return DominatorTreeAnalysis(); });
    FAM.registerPass([&] { return LoopAnalysis(); });
    // We also allow loop passes to assume a set of other analyses and so need
    // those.
    FAM.registerPass([&] { return AAManager(); });
    FAM.registerPass([&] { return AssumptionAnalysis(); });
    FAM.registerPass([&] { return BlockFrequencyAnalysis(); });
    FAM.registerPass([&] { return BranchProbabilityAnalysis(); });
    FAM.registerPass([&] { return PostDominatorTreeAnalysis(); });
    FAM.registerPass([&] { return MemorySSAAnalysis(); });
    FAM.registerPass([&] { return ScalarEvolutionAnalysis(); });
    FAM.registerPass([&] { return TargetLibraryAnalysis(); });
    FAM.registerPass([&] { return TargetIRAnalysis(); });

    // Register required pass instrumentation analysis.
    LAM.registerPass([&] { return PassInstrumentationAnalysis(); });
    FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
    MAM.registerPass([&] { return PassInstrumentationAnalysis(); });

    // Cross-register proxies.
    LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
    FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
    FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
    MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
  }
};

TEST_F(LoopPassManagerTest, Basic) {
  ModulePassManager MPM;
  ::testing::InSequence MakeExpectationsSequenced;

  // First we just visit all the loops in all the functions and get their
  // analysis results. This will run the analysis a total of four times,
  // once for each loop.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.g.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.g.0"), _, _));
  // Wire the loop pass through pass managers into the module pipeline.
  {
    LoopPassManager LPM;
    LPM.addPass(MLPHandle.getPass());
    FunctionPassManager FPM;
    FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  }

  // Next we run two passes over the loops. The first one invalidates the
  // analyses for one loop, the second ones try to get the analysis results.
  // This should force only one analysis to re-run within the loop PM, but will
  // also invalidate everything after the loop pass manager finishes.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .WillOnce(DoDefault())
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .WillOnce(InvokeWithoutArgs([] { return PreservedAnalyses::none(); }))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .WillOnce(DoDefault())
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLPHandle, run(HasName("loop.g.0"), _, _, _))
      .WillOnce(DoDefault())
      .WillOnce(Invoke(getLoopAnalysisResult));
  // Wire two loop pass runs into the module pipeline.
  {
    LoopPassManager LPM;
    LPM.addPass(MLPHandle.getPass());
    LPM.addPass(MLPHandle.getPass());
    FunctionPassManager FPM;
    FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  }

  // And now run the pipeline across the module.
  MPM.run(*M, MAM);
}

TEST_F(LoopPassManagerTest, FunctionPassInvalidationOfLoopAnalyses) {
  ModulePassManager MPM;
  FunctionPassManager FPM;
  // We process each function completely in sequence.
  ::testing::Sequence FSequence, GSequence;

  // First, force the analysis result to be computed for each loop.
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _))
      .InSequence(FSequence)
      .WillOnce(DoDefault());
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _))
      .InSequence(FSequence)
      .WillOnce(DoDefault());
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _))
      .InSequence(FSequence)
      .WillOnce(DoDefault());
  EXPECT_CALL(MLAHandle, run(HasName("loop.g.0"), _, _))
      .InSequence(GSequence)
      .WillOnce(DoDefault());
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));

  // No need to re-run if we require again from a fresh loop pass manager.
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));
  // For 'f', preserve most things but not the specific loop analyses.
  auto PA = getLoopPassPreservedAnalyses();
  PA.preserve<MemorySSAAnalysis>();
  EXPECT_CALL(MFPHandle, run(HasName("f"), _))
      .InSequence(FSequence)
      .WillOnce(Return(PA));
  EXPECT_CALL(MLAHandle, invalidate(HasName("loop.0.0"), _, _))
      .InSequence(FSequence)
      .WillOnce(DoDefault());
  // On one loop, skip the invalidation (as though we did an internal update).
  EXPECT_CALL(MLAHandle, invalidate(HasName("loop.0.1"), _, _))
      .InSequence(FSequence)
      .WillOnce(Return(false));
  EXPECT_CALL(MLAHandle, invalidate(HasName("loop.0"), _, _))
      .InSequence(FSequence)
      .WillOnce(DoDefault());
  // Now two loops still have to be recomputed.
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _))
      .InSequence(FSequence)
      .WillOnce(DoDefault());
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _))
      .InSequence(FSequence)
      .WillOnce(DoDefault());
  // Preserve things in the second function to ensure invalidation remains
  // isolated to one function.
  EXPECT_CALL(MFPHandle, run(HasName("g"), _))
      .InSequence(GSequence)
      .WillOnce(DoDefault());
  FPM.addPass(MFPHandle.getPass());
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));

  EXPECT_CALL(MFPHandle, run(HasName("f"), _))
      .InSequence(FSequence)
      .WillOnce(DoDefault());
  // For 'g', fail to preserve anything, causing the loops themselves to be
  // cleared. We don't get an invalidation event here as the loop is gone, but
  // we should still have to recompute the analysis.
  EXPECT_CALL(MFPHandle, run(HasName("g"), _))
      .InSequence(GSequence)
      .WillOnce(Return(PreservedAnalyses::none()));
  EXPECT_CALL(MLAHandle, run(HasName("loop.g.0"), _, _))
      .InSequence(GSequence)
      .WillOnce(DoDefault());
  FPM.addPass(MFPHandle.getPass());
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));

  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));

  // Verify with a separate function pass run that we didn't mess up 'f's
  // cache. No analysis runs should be necessary here.
  MPM.addPass(createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>())));

  MPM.run(*M, MAM);
}

TEST_F(LoopPassManagerTest, ModulePassInvalidationOfLoopAnalyses) {
  ModulePassManager MPM;
  ::testing::InSequence MakeExpectationsSequenced;

  // First, force the analysis result to be computed for each loop.
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.g.0"), _, _));
  MPM.addPass(createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>())));

  // Walking all the way out and all the way back in doesn't re-run the
  // analysis.
  MPM.addPass(createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>())));

  // But a module pass that doesn't preserve the actual mock loop analysis
  // invalidates all the way down and forces recomputing.
  EXPECT_CALL(MMPHandle, run(_, _)).WillOnce(InvokeWithoutArgs([] {
    auto PA = getLoopPassPreservedAnalyses();
    PA.preserve<FunctionAnalysisManagerModuleProxy>();
    PA.preserve<MemorySSAAnalysis>();
    return PA;
  }));
  // All the loop analyses from both functions get invalidated before we
  // recompute anything.
  EXPECT_CALL(MLAHandle, invalidate(HasName("loop.0.0"), _, _));
  // On one loop, again skip the invalidation (as though we did an internal
  // update).
  EXPECT_CALL(MLAHandle, invalidate(HasName("loop.0.1"), _, _))
      .WillOnce(Return(false));
  EXPECT_CALL(MLAHandle, invalidate(HasName("loop.0"), _, _));
  EXPECT_CALL(MLAHandle, invalidate(HasName("loop.g.0"), _, _));
  // Now all but one of the loops gets re-analyzed.
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.g.0"), _, _));
  MPM.addPass(MMPHandle.getPass());
  MPM.addPass(createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>())));

  // Verify that the cached values persist.
  MPM.addPass(createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>())));

  // Now we fail to preserve the loop analysis and observe that the loop
  // analyses are cleared (so no invalidation event) as the loops themselves
  // are no longer valid.
  EXPECT_CALL(MMPHandle, run(_, _)).WillOnce(InvokeWithoutArgs([] {
    auto PA = PreservedAnalyses::none();
    PA.preserve<FunctionAnalysisManagerModuleProxy>();
    return PA;
  }));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.g.0"), _, _));
  MPM.addPass(MMPHandle.getPass());
  MPM.addPass(createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>())));

  // Verify that the cached values persist.
  MPM.addPass(createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>())));

  // Next, check that even if we preserve everything within the function itelf,
  // if the function's module pass proxy isn't preserved and the potential set
  // of functions changes, the clear reaches the loop analyses as well. This
  // will again trigger re-runs but not invalidation events.
  EXPECT_CALL(MMPHandle, run(_, _)).WillOnce(InvokeWithoutArgs([] {
    auto PA = PreservedAnalyses::none();
    PA.preserveSet<AllAnalysesOn<Function>>();
    PA.preserveSet<AllAnalysesOn<Loop>>();
    return PA;
  }));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.g.0"), _, _));
  MPM.addPass(MMPHandle.getPass());
  MPM.addPass(createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>())));

  MPM.run(*M, MAM);
}

// Test that if any of the bundled analyses provided in the LPM's signature
// become invalid, the analysis proxy itself becomes invalid and we clear all
// loop analysis results.
TEST_F(LoopPassManagerTest, InvalidationOfBundledAnalyses) {
  ModulePassManager MPM;
  FunctionPassManager FPM;
  ::testing::InSequence MakeExpectationsSequenced;

  // First, force the analysis result to be computed for each loop.
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));

  // No need to re-run if we require again from a fresh loop pass manager.
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));

  // Preserving everything but the loop analyses themselves results in
  // invalidation and running.
  EXPECT_CALL(MFPHandle, run(HasName("f"), _))
      .WillOnce(Return(getLoopPassPreservedAnalyses()));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  FPM.addPass(MFPHandle.getPass());
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));

  // The rest don't invalidate analyses, they only trigger re-runs because we
  // clear the cache completely.
  EXPECT_CALL(MFPHandle, run(HasName("f"), _)).WillOnce(InvokeWithoutArgs([] {
    auto PA = PreservedAnalyses::none();
    // Not preserving `AAManager`.
    PA.preserve<DominatorTreeAnalysis>();
    PA.preserve<LoopAnalysis>();
    PA.preserve<LoopAnalysisManagerFunctionProxy>();
    PA.preserve<ScalarEvolutionAnalysis>();
    return PA;
  }));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  FPM.addPass(MFPHandle.getPass());
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));

  EXPECT_CALL(MFPHandle, run(HasName("f"), _)).WillOnce(InvokeWithoutArgs([] {
    auto PA = PreservedAnalyses::none();
    // Not preserving `DominatorTreeAnalysis`.
    PA.preserve<LoopAnalysis>();
    PA.preserve<LoopAnalysisManagerFunctionProxy>();
    PA.preserve<ScalarEvolutionAnalysis>();
    return PA;
  }));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  FPM.addPass(MFPHandle.getPass());
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));

  EXPECT_CALL(MFPHandle, run(HasName("f"), _)).WillOnce(InvokeWithoutArgs([] {
    auto PA = PreservedAnalyses::none();
    PA.preserve<DominatorTreeAnalysis>();
    // Not preserving the `LoopAnalysis`.
    PA.preserve<LoopAnalysisManagerFunctionProxy>();
    PA.preserve<ScalarEvolutionAnalysis>();
    return PA;
  }));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  FPM.addPass(MFPHandle.getPass());
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));

  EXPECT_CALL(MFPHandle, run(HasName("f"), _)).WillOnce(InvokeWithoutArgs([] {
    auto PA = PreservedAnalyses::none();
    PA.preserve<DominatorTreeAnalysis>();
    PA.preserve<LoopAnalysis>();
    // Not preserving the `LoopAnalysisManagerFunctionProxy`.
    PA.preserve<ScalarEvolutionAnalysis>();
    return PA;
  }));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  FPM.addPass(MFPHandle.getPass());
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));

  EXPECT_CALL(MFPHandle, run(HasName("f"), _)).WillOnce(InvokeWithoutArgs([] {
    auto PA = PreservedAnalyses::none();
    PA.preserve<DominatorTreeAnalysis>();
    PA.preserve<LoopAnalysis>();
    PA.preserve<LoopAnalysisManagerFunctionProxy>();
    // Not preserving `ScalarEvolutionAnalysis`.
    return PA;
  }));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  FPM.addPass(MFPHandle.getPass());
  FPM.addPass(createFunctionToLoopPassAdaptor(
      RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));

  // After all the churn on 'f', we'll compute the loop analysis results for
  // 'g' once with a requires pass and then run our mock pass over g a bunch
  // but just get cached results each time.
  EXPECT_CALL(MLAHandle, run(HasName("loop.g.0"), _, _));
  EXPECT_CALL(MFPHandle, run(HasName("g"), _)).Times(6);

  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  MPM.run(*M, MAM);
}

TEST_F(LoopPassManagerTest, IndirectInvalidation) {
  // We need two distinct analysis types and handles.
  enum { A, B };
  MockLoopAnalysisHandleTemplate<A> MLAHandleA;
  MockLoopAnalysisHandleTemplate<B> MLAHandleB;
  LAM.registerPass([&] { return MLAHandleA.getAnalysis(); });
  LAM.registerPass([&] { return MLAHandleB.getAnalysis(); });
  typedef decltype(MLAHandleA)::Analysis AnalysisA;
  typedef decltype(MLAHandleB)::Analysis AnalysisB;

  // Set up AnalysisA to depend on our AnalysisB. For testing purposes we just
  // need to get the AnalysisB results in AnalysisA's run method and check if
  // AnalysisB gets invalidated in AnalysisA's invalidate method.
  ON_CALL(MLAHandleA, run(_, _, _))
      .WillByDefault(Invoke([&](Loop &L, LoopAnalysisManager &AM,
                                LoopStandardAnalysisResults &AR) {
        (void)AM.getResult<AnalysisB>(L, AR);
        return MLAHandleA.getResult();
      }));
  ON_CALL(MLAHandleA, invalidate(_, _, _))
      .WillByDefault(Invoke([](Loop &L, const PreservedAnalyses &PA,
                               LoopAnalysisManager::Invalidator &Inv) {
        auto PAC = PA.getChecker<AnalysisA>();
        return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Loop>>()) ||
               Inv.invalidate<AnalysisB>(L, PA);
      }));

  ::testing::InSequence MakeExpectationsSequenced;

  // Compute the analyses across all of 'f' first.
  EXPECT_CALL(MLAHandleA, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandleB, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandleA, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandleB, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandleA, run(HasName("loop.0"), _, _));
  EXPECT_CALL(MLAHandleB, run(HasName("loop.0"), _, _));

  // Now we invalidate AnalysisB (but not AnalysisA) for one of the loops and
  // preserve everything for the rest. This in turn triggers that one loop to
  // recompute both AnalysisB *and* AnalysisA if indirect invalidation is
  // working.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .WillOnce(InvokeWithoutArgs([] {
        auto PA = getLoopPassPreservedAnalyses();
        // Specifically preserve AnalysisA so that it would survive if it
        // didn't depend on AnalysisB.
        PA.preserve<AnalysisA>();
        return PA;
      }));
  // It happens that AnalysisB is invalidated first. That shouldn't matter
  // though, and we should still call AnalysisA's invalidation.
  EXPECT_CALL(MLAHandleB, invalidate(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandleA, invalidate(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .WillOnce(Invoke([](Loop &L, LoopAnalysisManager &AM,
                          LoopStandardAnalysisResults &AR, LPMUpdater &) {
        (void)AM.getResult<AnalysisA>(L, AR);
        return PreservedAnalyses::all();
      }));
  EXPECT_CALL(MLAHandleA, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandleB, run(HasName("loop.0.0"), _, _));
  // The rest of the loops should run and get cached results.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke([](Loop &L, LoopAnalysisManager &AM,
                                LoopStandardAnalysisResults &AR, LPMUpdater &) {
        (void)AM.getResult<AnalysisA>(L, AR);
        return PreservedAnalyses::all();
      }));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke([](Loop &L, LoopAnalysisManager &AM,
                                LoopStandardAnalysisResults &AR, LPMUpdater &) {
        (void)AM.getResult<AnalysisA>(L, AR);
        return PreservedAnalyses::all();
      }));

  // The run over 'g' should be boring, with us just computing the analyses once
  // up front and then running loop passes and getting cached results.
  EXPECT_CALL(MLAHandleA, run(HasName("loop.g.0"), _, _));
  EXPECT_CALL(MLAHandleB, run(HasName("loop.g.0"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.g.0"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke([](Loop &L, LoopAnalysisManager &AM,
                                LoopStandardAnalysisResults &AR, LPMUpdater &) {
        (void)AM.getResult<AnalysisA>(L, AR);
        return PreservedAnalyses::all();
      }));

  // Build the pipeline and run it.
  ModulePassManager MPM;
  FunctionPassManager FPM;
  FPM.addPass(
      createFunctionToLoopPassAdaptor(RequireAnalysisLoopPass<AnalysisA>()));
  LoopPassManager LPM;
  LPM.addPass(MLPHandle.getPass());
  LPM.addPass(MLPHandle.getPass());
  FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  MPM.run(*M, MAM);
}

TEST_F(LoopPassManagerTest, IndirectOuterPassInvalidation) {
  typedef decltype(MLAHandle)::Analysis LoopAnalysis;

  MockFunctionAnalysisHandle MFAHandle;
  FAM.registerPass([&] { return MFAHandle.getAnalysis(); });
  typedef decltype(MFAHandle)::Analysis FunctionAnalysis;

  // Set up the loop analysis to depend on both the function and module
  // analysis.
  ON_CALL(MLAHandle, run(_, _, _))
      .WillByDefault(Invoke([&](Loop &L, LoopAnalysisManager &AM,
                                LoopStandardAnalysisResults &AR) {
        auto &FAMP = AM.getResult<FunctionAnalysisManagerLoopProxy>(L, AR);
        Function &F = *L.getHeader()->getParent();
        // This call will assert when trying to get the actual analysis if the
        // FunctionAnalysis can be invalidated. Only check its existence.
        // Alternatively, use FAM above, for the purposes of this unittest.
        if (FAMP.cachedResultExists<FunctionAnalysis>(F))
          FAMP.registerOuterAnalysisInvalidation<FunctionAnalysis,
                                                 LoopAnalysis>();
        return MLAHandle.getResult();
      }));

  ::testing::InSequence MakeExpectationsSequenced;

  // Compute the analyses across all of 'f' first.
  EXPECT_CALL(MFPHandle, run(HasName("f"), _))
      .WillOnce(Invoke([](Function &F, FunctionAnalysisManager &AM) {
        // Force the computing of the function analysis so it is available in
        // this function.
        (void)AM.getResult<FunctionAnalysis>(F);
        return PreservedAnalyses::all();
      }));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));

  // Now invalidate the function analysis but preserve the loop analyses.
  // This should trigger immediate invalidation of the loop analyses, despite
  // the fact that they were preserved.
  EXPECT_CALL(MFPHandle, run(HasName("f"), _)).WillOnce(InvokeWithoutArgs([] {
    auto PA = getLoopPassPreservedAnalyses();
    PA.preserve<MemorySSAAnalysis>();
    PA.preserveSet<AllAnalysesOn<Loop>>();
    return PA;
  }));
  EXPECT_CALL(MLAHandle, invalidate(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, invalidate(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, invalidate(HasName("loop.0"), _, _));

  // And re-running a requires pass recomputes them.
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));

  // When we run over 'g' we don't populate the cache with the function
  // analysis.
  EXPECT_CALL(MFPHandle, run(HasName("g"), _))
      .WillOnce(Return(PreservedAnalyses::all()));
  EXPECT_CALL(MLAHandle, run(HasName("loop.g.0"), _, _));

  // Which means that no extra invalidation occurs and cached values are used.
  EXPECT_CALL(MFPHandle, run(HasName("g"), _)).WillOnce(InvokeWithoutArgs([] {
    auto PA = getLoopPassPreservedAnalyses();
    PA.preserve<MemorySSAAnalysis>();
    PA.preserveSet<AllAnalysesOn<Loop>>();
    return PA;
  }));

  // Build the pipeline and run it.
  ModulePassManager MPM;
  FunctionPassManager FPM;
  FPM.addPass(MFPHandle.getPass());
  FPM.addPass(
      createFunctionToLoopPassAdaptor(RequireAnalysisLoopPass<LoopAnalysis>()));
  FPM.addPass(MFPHandle.getPass());
  FPM.addPass(
      createFunctionToLoopPassAdaptor(RequireAnalysisLoopPass<LoopAnalysis>()));
  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  MPM.run(*M, MAM);
}

TEST_F(LoopPassManagerTest, LoopChildInsertion) {
  // Super boring module with three loops in a single loop nest.
  M = parseIR(Context, "define void @f(i1* %ptr) {\n"
                       "entry:\n"
                       "  br label %loop.0\n"
                       "loop.0:\n"
                       "  %cond.0 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0, label %loop.0.0.ph, label %end\n"
                       "loop.0.0.ph:\n"
                       "  br label %loop.0.0\n"
                       "loop.0.0:\n"
                       "  %cond.0.0 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0.0, label %loop.0.0, label %loop.0.1.ph\n"
                       "loop.0.1.ph:\n"
                       "  br label %loop.0.1\n"
                       "loop.0.1:\n"
                       "  %cond.0.1 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0.1, label %loop.0.1, label %loop.0.2.ph\n"
                       "loop.0.2.ph:\n"
                       "  br label %loop.0.2\n"
                       "loop.0.2:\n"
                       "  %cond.0.2 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0.2, label %loop.0.2, label %loop.0.latch\n"
                       "loop.0.latch:\n"
                       "  br label %loop.0\n"
                       "end:\n"
                       "  ret void\n"
                       "}\n");

  // Build up variables referring into the IR so we can rewrite it below
  // easily.
  Function &F = *M->begin();
  ASSERT_THAT(F, HasName("f"));
  Argument &Ptr = *F.arg_begin();
  auto BBI = F.begin();
  BasicBlock &EntryBB = *BBI++;
  ASSERT_THAT(EntryBB, HasName("entry"));
  BasicBlock &Loop0BB = *BBI++;
  ASSERT_THAT(Loop0BB, HasName("loop.0"));
  BasicBlock &Loop00PHBB = *BBI++;
  ASSERT_THAT(Loop00PHBB, HasName("loop.0.0.ph"));
  BasicBlock &Loop00BB = *BBI++;
  ASSERT_THAT(Loop00BB, HasName("loop.0.0"));
  BasicBlock &Loop01PHBB = *BBI++;
  ASSERT_THAT(Loop01PHBB, HasName("loop.0.1.ph"));
  BasicBlock &Loop01BB = *BBI++;
  ASSERT_THAT(Loop01BB, HasName("loop.0.1"));
  BasicBlock &Loop02PHBB = *BBI++;
  ASSERT_THAT(Loop02PHBB, HasName("loop.0.2.ph"));
  BasicBlock &Loop02BB = *BBI++;
  ASSERT_THAT(Loop02BB, HasName("loop.0.2"));
  BasicBlock &Loop0LatchBB = *BBI++;
  ASSERT_THAT(Loop0LatchBB, HasName("loop.0.latch"));
  BasicBlock &EndBB = *BBI++;
  ASSERT_THAT(EndBB, HasName("end"));
  ASSERT_THAT(BBI, F.end());
  auto CreateCondBr = [&](BasicBlock *TrueBB, BasicBlock *FalseBB,
                          const char *Name, BasicBlock *BB) {
    auto *Cond = new LoadInst(Type::getInt1Ty(Context), &Ptr, Name,
                              /*isVolatile*/ true, BB);
    BranchInst::Create(TrueBB, FalseBB, Cond, BB);
  };

  // Build the pass managers and register our pipeline. We build a single loop
  // pass pipeline consisting of three mock pass runs over each loop. After
  // this we run both domtree and loop verification passes to make sure that
  // the IR remained valid during our mutations.
  ModulePassManager MPM;
  FunctionPassManager FPM;
  LoopPassManager LPM;
  LPM.addPass(MLPHandle.getPass());
  LPM.addPass(MLPHandle.getPass());
  LPM.addPass(MLPHandle.getPass());
  FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
  FPM.addPass(DominatorTreeVerifierPass());
  FPM.addPass(LoopVerifierPass());
  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));

  // All the visit orders are deterministic, so we use simple fully order
  // expectations.
  ::testing::InSequence MakeExpectationsSequenced;

  // We run loop passes three times over each of the loops.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));

  // When running over the middle loop, the second run inserts two new child
  // loops, inserting them and itself into the worklist.
  BasicBlock *NewLoop010BB, *NewLoop01LatchBB;
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .WillOnce(Invoke([&](Loop &L, LoopAnalysisManager &AM,
                           LoopStandardAnalysisResults &AR,
                           LPMUpdater &Updater) {
        auto *NewLoop = AR.LI.AllocateLoop();
        L.addChildLoop(NewLoop);
        auto *NewLoop010PHBB =
            BasicBlock::Create(Context, "loop.0.1.0.ph", &F, &Loop02PHBB);
        NewLoop010BB =
            BasicBlock::Create(Context, "loop.0.1.0", &F, &Loop02PHBB);
        NewLoop01LatchBB =
            BasicBlock::Create(Context, "loop.0.1.latch", &F, &Loop02PHBB);
        Loop01BB.getTerminator()->replaceUsesOfWith(&Loop01BB, NewLoop010PHBB);
        BranchInst::Create(NewLoop010BB, NewLoop010PHBB);
        CreateCondBr(NewLoop01LatchBB, NewLoop010BB, "cond.0.1.0",
                     NewLoop010BB);
        BranchInst::Create(&Loop01BB, NewLoop01LatchBB);
        AR.DT.addNewBlock(NewLoop010PHBB, &Loop01BB);
        AR.DT.addNewBlock(NewLoop010BB, NewLoop010PHBB);
        AR.DT.addNewBlock(NewLoop01LatchBB, NewLoop010BB);
        EXPECT_TRUE(AR.DT.verify());
        L.addBasicBlockToLoop(NewLoop010PHBB, AR.LI);
        NewLoop->addBasicBlockToLoop(NewLoop010BB, AR.LI);
        L.addBasicBlockToLoop(NewLoop01LatchBB, AR.LI);
        NewLoop->verifyLoop();
        L.verifyLoop();
        Updater.addChildLoops({NewLoop});
        return PreservedAnalyses::all();
      }));

  // We should immediately drop down to fully visit the new inner loop.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1.0"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1.0"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  // After visiting the inner loop, we should re-visit the second loop
  // reflecting its new loop nest structure.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));

  // In the second run over the middle loop after we've visited the new child,
  // we add another child to check that we can repeatedly add children, and add
  // children to a loop that already has children.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .WillOnce(Invoke([&](Loop &L, LoopAnalysisManager &AM,
                           LoopStandardAnalysisResults &AR,
                           LPMUpdater &Updater) {
        auto *NewLoop = AR.LI.AllocateLoop();
        L.addChildLoop(NewLoop);
        auto *NewLoop011PHBB = BasicBlock::Create(Context, "loop.0.1.1.ph", &F, NewLoop01LatchBB);
        auto *NewLoop011BB = BasicBlock::Create(Context, "loop.0.1.1", &F, NewLoop01LatchBB);
        NewLoop010BB->getTerminator()->replaceUsesOfWith(NewLoop01LatchBB,
                                                         NewLoop011PHBB);
        BranchInst::Create(NewLoop011BB, NewLoop011PHBB);
        CreateCondBr(NewLoop01LatchBB, NewLoop011BB, "cond.0.1.1",
                     NewLoop011BB);
        AR.DT.addNewBlock(NewLoop011PHBB, NewLoop010BB);
        auto *NewDTNode = AR.DT.addNewBlock(NewLoop011BB, NewLoop011PHBB);
        AR.DT.changeImmediateDominator(AR.DT[NewLoop01LatchBB], NewDTNode);
        EXPECT_TRUE(AR.DT.verify());
        L.addBasicBlockToLoop(NewLoop011PHBB, AR.LI);
        NewLoop->addBasicBlockToLoop(NewLoop011BB, AR.LI);
        NewLoop->verifyLoop();
        L.verifyLoop();
        Updater.addChildLoops({NewLoop});
        return PreservedAnalyses::all();
      }));

  // Again, we should immediately drop down to visit the new, unvisited child
  // loop. We don't need to revisit the other child though.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1.1"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1.1"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1.1"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  // And now we should pop back up to the second loop and do a full pipeline of
  // three passes on its current form.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .Times(3)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.2"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  // Now that all the expected actions are registered, run the pipeline over
  // our module. All of our expectations are verified when the test finishes.
  MPM.run(*M, MAM);
}

TEST_F(LoopPassManagerTest, LoopPeerInsertion) {
  // Super boring module with two loop nests and loop nest with two child
  // loops.
  M = parseIR(Context, "define void @f(i1* %ptr) {\n"
                       "entry:\n"
                       "  br label %loop.0\n"
                       "loop.0:\n"
                       "  %cond.0 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0, label %loop.0.0.ph, label %loop.2.ph\n"
                       "loop.0.0.ph:\n"
                       "  br label %loop.0.0\n"
                       "loop.0.0:\n"
                       "  %cond.0.0 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0.0, label %loop.0.0, label %loop.0.2.ph\n"
                       "loop.0.2.ph:\n"
                       "  br label %loop.0.2\n"
                       "loop.0.2:\n"
                       "  %cond.0.2 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0.2, label %loop.0.2, label %loop.0.latch\n"
                       "loop.0.latch:\n"
                       "  br label %loop.0\n"
                       "loop.2.ph:\n"
                       "  br label %loop.2\n"
                       "loop.2:\n"
                       "  %cond.2 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.2, label %loop.2, label %end\n"
                       "end:\n"
                       "  ret void\n"
                       "}\n");

  // Build up variables referring into the IR so we can rewrite it below
  // easily.
  Function &F = *M->begin();
  ASSERT_THAT(F, HasName("f"));
  Argument &Ptr = *F.arg_begin();
  auto BBI = F.begin();
  BasicBlock &EntryBB = *BBI++;
  ASSERT_THAT(EntryBB, HasName("entry"));
  BasicBlock &Loop0BB = *BBI++;
  ASSERT_THAT(Loop0BB, HasName("loop.0"));
  BasicBlock &Loop00PHBB = *BBI++;
  ASSERT_THAT(Loop00PHBB, HasName("loop.0.0.ph"));
  BasicBlock &Loop00BB = *BBI++;
  ASSERT_THAT(Loop00BB, HasName("loop.0.0"));
  BasicBlock &Loop02PHBB = *BBI++;
  ASSERT_THAT(Loop02PHBB, HasName("loop.0.2.ph"));
  BasicBlock &Loop02BB = *BBI++;
  ASSERT_THAT(Loop02BB, HasName("loop.0.2"));
  BasicBlock &Loop0LatchBB = *BBI++;
  ASSERT_THAT(Loop0LatchBB, HasName("loop.0.latch"));
  BasicBlock &Loop2PHBB = *BBI++;
  ASSERT_THAT(Loop2PHBB, HasName("loop.2.ph"));
  BasicBlock &Loop2BB = *BBI++;
  ASSERT_THAT(Loop2BB, HasName("loop.2"));
  BasicBlock &EndBB = *BBI++;
  ASSERT_THAT(EndBB, HasName("end"));
  ASSERT_THAT(BBI, F.end());
  auto CreateCondBr = [&](BasicBlock *TrueBB, BasicBlock *FalseBB,
                          const char *Name, BasicBlock *BB) {
    auto *Cond = new LoadInst(Type::getInt1Ty(Context), &Ptr, Name,
                              /*isVolatile*/ true, BB);
    BranchInst::Create(TrueBB, FalseBB, Cond, BB);
  };

  // Build the pass managers and register our pipeline. We build a single loop
  // pass pipeline consisting of three mock pass runs over each loop. After
  // this we run both domtree and loop verification passes to make sure that
  // the IR remained valid during our mutations.
  ModulePassManager MPM;
  FunctionPassManager FPM;
  LoopPassManager LPM;
  LPM.addPass(MLPHandle.getPass());
  LPM.addPass(MLPHandle.getPass());
  LPM.addPass(MLPHandle.getPass());
  FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
  FPM.addPass(DominatorTreeVerifierPass());
  FPM.addPass(LoopVerifierPass());
  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));

  // All the visit orders are deterministic, so we use simple fully order
  // expectations.
  ::testing::InSequence MakeExpectationsSequenced;

  // We run loop passes three times over each of the loops.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));

  // On the second run, we insert a sibling loop.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .WillOnce(Invoke([&](Loop &L, LoopAnalysisManager &AM,
                           LoopStandardAnalysisResults &AR,
                           LPMUpdater &Updater) {
        auto *NewLoop = AR.LI.AllocateLoop();
        L.getParentLoop()->addChildLoop(NewLoop);
        auto *NewLoop01PHBB = BasicBlock::Create(Context, "loop.0.1.ph", &F, &Loop02PHBB);
        auto *NewLoop01BB = BasicBlock::Create(Context, "loop.0.1", &F, &Loop02PHBB);
        BranchInst::Create(NewLoop01BB, NewLoop01PHBB);
        CreateCondBr(&Loop02PHBB, NewLoop01BB, "cond.0.1", NewLoop01BB);
        Loop00BB.getTerminator()->replaceUsesOfWith(&Loop02PHBB, NewLoop01PHBB);
        AR.DT.addNewBlock(NewLoop01PHBB, &Loop00BB);
        auto *NewDTNode = AR.DT.addNewBlock(NewLoop01BB, NewLoop01PHBB);
        AR.DT.changeImmediateDominator(AR.DT[&Loop02PHBB], NewDTNode);
        EXPECT_TRUE(AR.DT.verify());
        L.getParentLoop()->addBasicBlockToLoop(NewLoop01PHBB, AR.LI);
        NewLoop->addBasicBlockToLoop(NewLoop01BB, AR.LI);
        L.getParentLoop()->verifyLoop();
        Updater.addSiblingLoops({NewLoop});
        return PreservedAnalyses::all();
      }));
  // We finish processing this loop as sibling loops don't perturb the
  // postorder walk.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));

  // We visit the inserted sibling next.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.2"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  // Next, on the third pass run on the last inner loop we add more new
  // siblings, more than one, and one with nested child loops. By doing this at
  // the end we make sure that edge case works well.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2"), _, _, _))
      .WillOnce(Invoke([&](Loop &L, LoopAnalysisManager &AM,
                           LoopStandardAnalysisResults &AR,
                           LPMUpdater &Updater) {
        Loop *NewLoops[] = {AR.LI.AllocateLoop(), AR.LI.AllocateLoop(),
                            AR.LI.AllocateLoop()};
        L.getParentLoop()->addChildLoop(NewLoops[0]);
        L.getParentLoop()->addChildLoop(NewLoops[1]);
        NewLoops[1]->addChildLoop(NewLoops[2]);
        auto *NewLoop03PHBB =
            BasicBlock::Create(Context, "loop.0.3.ph", &F, &Loop0LatchBB);
        auto *NewLoop03BB =
            BasicBlock::Create(Context, "loop.0.3", &F, &Loop0LatchBB);
        auto *NewLoop04PHBB =
            BasicBlock::Create(Context, "loop.0.4.ph", &F, &Loop0LatchBB);
        auto *NewLoop04BB =
            BasicBlock::Create(Context, "loop.0.4", &F, &Loop0LatchBB);
        auto *NewLoop040PHBB =
            BasicBlock::Create(Context, "loop.0.4.0.ph", &F, &Loop0LatchBB);
        auto *NewLoop040BB =
            BasicBlock::Create(Context, "loop.0.4.0", &F, &Loop0LatchBB);
        auto *NewLoop04LatchBB =
            BasicBlock::Create(Context, "loop.0.4.latch", &F, &Loop0LatchBB);
        Loop02BB.getTerminator()->replaceUsesOfWith(&Loop0LatchBB, NewLoop03PHBB);
        BranchInst::Create(NewLoop03BB, NewLoop03PHBB);
        CreateCondBr(NewLoop04PHBB, NewLoop03BB, "cond.0.3", NewLoop03BB);
        BranchInst::Create(NewLoop04BB, NewLoop04PHBB);
        CreateCondBr(&Loop0LatchBB, NewLoop040PHBB, "cond.0.4", NewLoop04BB);
        BranchInst::Create(NewLoop040BB, NewLoop040PHBB);
        CreateCondBr(NewLoop04LatchBB, NewLoop040BB, "cond.0.4.0", NewLoop040BB);
        BranchInst::Create(NewLoop04BB, NewLoop04LatchBB);
        AR.DT.addNewBlock(NewLoop03PHBB, &Loop02BB);
        AR.DT.addNewBlock(NewLoop03BB, NewLoop03PHBB);
        AR.DT.addNewBlock(NewLoop04PHBB, NewLoop03BB);
        auto *NewDTNode = AR.DT.addNewBlock(NewLoop04BB, NewLoop04PHBB);
        AR.DT.changeImmediateDominator(AR.DT[&Loop0LatchBB], NewDTNode);
        AR.DT.addNewBlock(NewLoop040PHBB, NewLoop04BB);
        AR.DT.addNewBlock(NewLoop040BB, NewLoop040PHBB);
        AR.DT.addNewBlock(NewLoop04LatchBB, NewLoop040BB);
        EXPECT_TRUE(AR.DT.verify());
        L.getParentLoop()->addBasicBlockToLoop(NewLoop03PHBB, AR.LI);
        NewLoops[0]->addBasicBlockToLoop(NewLoop03BB, AR.LI);
        L.getParentLoop()->addBasicBlockToLoop(NewLoop04PHBB, AR.LI);
        NewLoops[1]->addBasicBlockToLoop(NewLoop04BB, AR.LI);
        NewLoops[1]->addBasicBlockToLoop(NewLoop040PHBB, AR.LI);
        NewLoops[2]->addBasicBlockToLoop(NewLoop040BB, AR.LI);
        NewLoops[1]->addBasicBlockToLoop(NewLoop04LatchBB, AR.LI);
        L.getParentLoop()->verifyLoop();
        Updater.addSiblingLoops({NewLoops[0], NewLoops[1]});
        return PreservedAnalyses::all();
      }));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.3"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.3"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.3"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  // Note that we need to visit the inner loop of this added sibling before the
  // sibling itself!
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.4.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.4.0"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.4.0"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.4"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.4"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.4"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  // And only now do we visit the outermost loop of the nest.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  // On the second pass, we add sibling loops which become new top-level loops.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .WillOnce(Invoke([&](Loop &L, LoopAnalysisManager &AM,
                           LoopStandardAnalysisResults &AR,
                           LPMUpdater &Updater) {
        auto *NewLoop = AR.LI.AllocateLoop();
        AR.LI.addTopLevelLoop(NewLoop);
        auto *NewLoop1PHBB = BasicBlock::Create(Context, "loop.1.ph", &F, &Loop2BB);
        auto *NewLoop1BB = BasicBlock::Create(Context, "loop.1", &F, &Loop2BB);
        BranchInst::Create(NewLoop1BB, NewLoop1PHBB);
        CreateCondBr(&Loop2PHBB, NewLoop1BB, "cond.1", NewLoop1BB);
        Loop0BB.getTerminator()->replaceUsesOfWith(&Loop2PHBB, NewLoop1PHBB);
        AR.DT.addNewBlock(NewLoop1PHBB, &Loop0BB);
        auto *NewDTNode = AR.DT.addNewBlock(NewLoop1BB, NewLoop1PHBB);
        AR.DT.changeImmediateDominator(AR.DT[&Loop2PHBB], NewDTNode);
        EXPECT_TRUE(AR.DT.verify());
        NewLoop->addBasicBlockToLoop(NewLoop1BB, AR.LI);
        NewLoop->verifyLoop();
        Updater.addSiblingLoops({NewLoop});
        return PreservedAnalyses::all();
      }));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.1"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.1"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.1"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.2"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.2"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.2"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  // Now that all the expected actions are registered, run the pipeline over
  // our module. All of our expectations are verified when the test finishes.
  MPM.run(*M, MAM);
}

TEST_F(LoopPassManagerTest, LoopDeletion) {
  // Build a module with a single loop nest that contains one outer loop with
  // three subloops, and one of those with its own subloop. We will
  // incrementally delete all of these to test different deletion scenarios.
  M = parseIR(Context, "define void @f(i1* %ptr) {\n"
                       "entry:\n"
                       "  br label %loop.0\n"
                       "loop.0:\n"
                       "  %cond.0 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0, label %loop.0.0.ph, label %end\n"
                       "loop.0.0.ph:\n"
                       "  br label %loop.0.0\n"
                       "loop.0.0:\n"
                       "  %cond.0.0 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0.0, label %loop.0.0, label %loop.0.1.ph\n"
                       "loop.0.1.ph:\n"
                       "  br label %loop.0.1\n"
                       "loop.0.1:\n"
                       "  %cond.0.1 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0.1, label %loop.0.1, label %loop.0.2.ph\n"
                       "loop.0.2.ph:\n"
                       "  br label %loop.0.2\n"
                       "loop.0.2:\n"
                       "  %cond.0.2 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0.2, label %loop.0.2.0.ph, label %loop.0.latch\n"
                       "loop.0.2.0.ph:\n"
                       "  br label %loop.0.2.0\n"
                       "loop.0.2.0:\n"
                       "  %cond.0.2.0 = load volatile i1, i1* %ptr\n"
                       "  br i1 %cond.0.2.0, label %loop.0.2.0, label %loop.0.2.latch\n"
                       "loop.0.2.latch:\n"
                       "  br label %loop.0.2\n"
                       "loop.0.latch:\n"
                       "  br label %loop.0\n"
                       "end:\n"
                       "  ret void\n"
                       "}\n");

  // Build up variables referring into the IR so we can rewrite it below
  // easily.
  Function &F = *M->begin();
  ASSERT_THAT(F, HasName("f"));
  Argument &Ptr = *F.arg_begin();
  auto BBI = F.begin();
  BasicBlock &EntryBB = *BBI++;
  ASSERT_THAT(EntryBB, HasName("entry"));
  BasicBlock &Loop0BB = *BBI++;
  ASSERT_THAT(Loop0BB, HasName("loop.0"));
  BasicBlock &Loop00PHBB = *BBI++;
  ASSERT_THAT(Loop00PHBB, HasName("loop.0.0.ph"));
  BasicBlock &Loop00BB = *BBI++;
  ASSERT_THAT(Loop00BB, HasName("loop.0.0"));
  BasicBlock &Loop01PHBB = *BBI++;
  ASSERT_THAT(Loop01PHBB, HasName("loop.0.1.ph"));
  BasicBlock &Loop01BB = *BBI++;
  ASSERT_THAT(Loop01BB, HasName("loop.0.1"));
  BasicBlock &Loop02PHBB = *BBI++;
  ASSERT_THAT(Loop02PHBB, HasName("loop.0.2.ph"));
  BasicBlock &Loop02BB = *BBI++;
  ASSERT_THAT(Loop02BB, HasName("loop.0.2"));
  BasicBlock &Loop020PHBB = *BBI++;
  ASSERT_THAT(Loop020PHBB, HasName("loop.0.2.0.ph"));
  BasicBlock &Loop020BB = *BBI++;
  ASSERT_THAT(Loop020BB, HasName("loop.0.2.0"));
  BasicBlock &Loop02LatchBB = *BBI++;
  ASSERT_THAT(Loop02LatchBB, HasName("loop.0.2.latch"));
  BasicBlock &Loop0LatchBB = *BBI++;
  ASSERT_THAT(Loop0LatchBB, HasName("loop.0.latch"));
  BasicBlock &EndBB = *BBI++;
  ASSERT_THAT(EndBB, HasName("end"));
  ASSERT_THAT(BBI, F.end());

  // Helper to do the actual deletion of a loop. We directly encode this here
  // to isolate ourselves from the rest of LLVM and for simplicity. Here we can
  // egregiously cheat based on knowledge of the test case. For example, we
  // have no PHI nodes and there is always a single i-dom.
  auto EraseLoop = [](Loop &L, BasicBlock &IDomBB,
                      LoopStandardAnalysisResults &AR, LPMUpdater &Updater) {
    assert(L.isInnermost() && "Can only delete leaf loops with this routine!");
    SmallVector<BasicBlock *, 4> LoopBBs(L.block_begin(), L.block_end());
    Updater.markLoopAsDeleted(L, L.getName());
    IDomBB.getTerminator()->replaceUsesOfWith(L.getHeader(),
                                              L.getUniqueExitBlock());
    for (BasicBlock *LoopBB : LoopBBs) {
      SmallVector<DomTreeNode *, 4> ChildNodes(AR.DT[LoopBB]->begin(),
                                               AR.DT[LoopBB]->end());
      for (DomTreeNode *ChildNode : ChildNodes)
        AR.DT.changeImmediateDominator(ChildNode, AR.DT[&IDomBB]);
      AR.DT.eraseNode(LoopBB);
      AR.LI.removeBlock(LoopBB);
      LoopBB->dropAllReferences();
    }
    for (BasicBlock *LoopBB : LoopBBs)
      LoopBB->eraseFromParent();

    AR.LI.erase(&L);
  };

  // Build up the pass managers.
  ModulePassManager MPM;
  FunctionPassManager FPM;
  // We run several loop pass pipelines across the loop nest, but they all take
  // the same form of three mock pass runs in a loop pipeline followed by
  // domtree and loop verification. We use a lambda to stamp this out each
  // time.
  auto AddLoopPipelineAndVerificationPasses = [&] {
    LoopPassManager LPM;
    LPM.addPass(MLPHandle.getPass());
    LPM.addPass(MLPHandle.getPass());
    LPM.addPass(MLPHandle.getPass());
    FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
    FPM.addPass(DominatorTreeVerifierPass());
    FPM.addPass(LoopVerifierPass());
  };

  // All the visit orders are deterministic so we use simple fully order
  // expectations.
  ::testing::InSequence MakeExpectationsSequenced;

  // We run the loop pipeline with three passes over each of the loops. When
  // running over the middle loop, the second pass in the pipeline deletes it.
  // This should prevent the third pass from visiting it but otherwise leave
  // the process unimpacted.
  AddLoopPipelineAndVerificationPasses();
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .WillOnce(
          Invoke([&](Loop &L, LoopAnalysisManager &AM,
                     LoopStandardAnalysisResults &AR, LPMUpdater &Updater) {
            Loop *ParentL = L.getParentLoop();
            AR.SE.forgetLoop(&L);
            EraseLoop(L, Loop01PHBB, AR, Updater);
            ParentL->verifyLoop();
            return PreservedAnalyses::all();
          }));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.2.0"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2.0"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.2"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  // Run the loop pipeline again. This time we delete the last loop, which
  // contains a nested loop within it and insert a new loop into the nest. This
  // makes sure we can handle nested loop deletion.
  AddLoopPipelineAndVerificationPasses();
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .Times(3)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2.0"), _, _, _))
      .Times(3)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  BasicBlock *NewLoop03PHBB;
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.2"), _, _, _))
      .WillOnce(
          Invoke([&](Loop &L, LoopAnalysisManager &AM,
                     LoopStandardAnalysisResults &AR, LPMUpdater &Updater) {
            AR.SE.forgetLoop(*L.begin());
            EraseLoop(**L.begin(), Loop020PHBB, AR, Updater);

            auto *ParentL = L.getParentLoop();
            AR.SE.forgetLoop(&L);
            EraseLoop(L, Loop02PHBB, AR, Updater);

            // Now insert a new sibling loop.
            auto *NewSibling = AR.LI.AllocateLoop();
            ParentL->addChildLoop(NewSibling);
            NewLoop03PHBB =
                BasicBlock::Create(Context, "loop.0.3.ph", &F, &Loop0LatchBB);
            auto *NewLoop03BB =
                BasicBlock::Create(Context, "loop.0.3", &F, &Loop0LatchBB);
            BranchInst::Create(NewLoop03BB, NewLoop03PHBB);
            auto *Cond =
                new LoadInst(Type::getInt1Ty(Context), &Ptr, "cond.0.3",
                             /*isVolatile*/ true, NewLoop03BB);
            BranchInst::Create(&Loop0LatchBB, NewLoop03BB, Cond, NewLoop03BB);
            Loop02PHBB.getTerminator()->replaceUsesOfWith(&Loop0LatchBB,
                                                          NewLoop03PHBB);
            AR.DT.addNewBlock(NewLoop03PHBB, &Loop02PHBB);
            AR.DT.addNewBlock(NewLoop03BB, NewLoop03PHBB);
            AR.DT.changeImmediateDominator(AR.DT[&Loop0LatchBB],
                                           AR.DT[NewLoop03BB]);
            EXPECT_TRUE(AR.DT.verify());
            ParentL->addBasicBlockToLoop(NewLoop03PHBB, AR.LI);
            NewSibling->addBasicBlockToLoop(NewLoop03BB, AR.LI);
            NewSibling->verifyLoop();
            ParentL->verifyLoop();
            Updater.addSiblingLoops({NewSibling});
            return PreservedAnalyses::all();
          }));

  // To respect our inner-to-outer traversal order, we must visit the
  // newly-inserted sibling of the loop we just deleted before we visit the
  // outer loop. When we do so, this must compute a fresh analysis result, even
  // though our new loop has the same pointer value as the loop we deleted.
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.3"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLAHandle, run(HasName("loop.0.3"), _, _));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.3"), _, _, _))
      .Times(2)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .Times(3)
      .WillRepeatedly(Invoke(getLoopAnalysisResult));

  // In the final loop pipeline run we delete every loop, including the last
  // loop of the nest. We do this again in the second pass in the pipeline, and
  // as a consequence we never make it to three runs on any loop. We also cover
  // deleting multiple loops in a single pipeline, deleting the first loop and
  // deleting the (last) top level loop.
  AddLoopPipelineAndVerificationPasses();
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .WillOnce(
          Invoke([&](Loop &L, LoopAnalysisManager &AM,
                     LoopStandardAnalysisResults &AR, LPMUpdater &Updater) {
            AR.SE.forgetLoop(&L);
            EraseLoop(L, Loop00PHBB, AR, Updater);
            return PreservedAnalyses::all();
          }));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.3"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.3"), _, _, _))
      .WillOnce(
          Invoke([&](Loop &L, LoopAnalysisManager &AM,
                     LoopStandardAnalysisResults &AR, LPMUpdater &Updater) {
            AR.SE.forgetLoop(&L);
            EraseLoop(L, *NewLoop03PHBB, AR, Updater);
            return PreservedAnalyses::all();
          }));

  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .WillOnce(Invoke(getLoopAnalysisResult));
  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _))
      .WillOnce(
          Invoke([&](Loop &L, LoopAnalysisManager &AM,
                     LoopStandardAnalysisResults &AR, LPMUpdater &Updater) {
            AR.SE.forgetLoop(&L);
            EraseLoop(L, EntryBB, AR, Updater);
            return PreservedAnalyses::all();
          }));

  // Add the function pass pipeline now that it is fully built up and run it
  // over the module's one function.
  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  MPM.run(*M, MAM);
}

TEST_F(LoopPassManagerTest, HandleLoopNestPass) {
  ::testing::Sequence FSequence, GSequence;

  EXPECT_CALL(MLPHandle, run(HasName("loop.0.0"), _, _, _))
      .Times(2)
      .InSequence(FSequence);
  EXPECT_CALL(MLPHandle, run(HasName("loop.0.1"), _, _, _))
      .Times(2)
      .InSequence(FSequence);
  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _)).InSequence(FSequence);
  EXPECT_CALL(MLNPHandle, run(HasName("loop.0"), _, _, _))
      .InSequence(FSequence);
  EXPECT_CALL(MLPHandle, run(HasName("loop.0"), _, _, _)).InSequence(FSequence);
  EXPECT_CALL(MLNPHandle, run(HasName("loop.0"), _, _, _))
      .InSequence(FSequence);
  EXPECT_CALL(MLPHandle, run(HasName("loop.g.0"), _, _, _))
      .InSequence(GSequence);
  EXPECT_CALL(MLNPHandle, run(HasName("loop.g.0"), _, _, _))
      .InSequence(GSequence);
  EXPECT_CALL(MLPHandle, run(HasName("loop.g.0"), _, _, _))
      .InSequence(GSequence);
  EXPECT_CALL(MLNPHandle, run(HasName("loop.g.0"), _, _, _))
      .InSequence(GSequence);

  EXPECT_CALL(MLNPHandle, run(HasName("loop.0"), _, _, _))
      .InSequence(FSequence);
  EXPECT_CALL(MLNPHandle, run(HasName("loop.g.0"), _, _, _))
      .InSequence(GSequence);

  EXPECT_CALL(MLNPHandle, run(HasName("loop.0"), _, _, _))
      .InSequence(FSequence);
  EXPECT_CALL(MLNPHandle, run(HasName("loop.g.0"), _, _, _))
      .InSequence(GSequence);

  ModulePassManager MPM;
  FunctionPassManager FPM;

  {
    LoopPassManager LPM;
    LPM.addPass(MLPHandle.getPass());
    LPM.addPass(MLNPHandle.getPass());
    LPM.addPass(MLPHandle.getPass());
    LPM.addPass(MLNPHandle.getPass());

    auto Adaptor = createFunctionToLoopPassAdaptor(std::move(LPM));
    ASSERT_FALSE(Adaptor.isLoopNestMode());
    FPM.addPass(std::move(Adaptor));
  }

  {
    auto Adaptor = createFunctionToLoopPassAdaptor(MLNPHandle.getPass());
    ASSERT_TRUE(Adaptor.isLoopNestMode());
    FPM.addPass(std::move(Adaptor));
  }

  {
    LoopPassManager LPM;
    LPM.addPass(MLNPHandle.getPass());
    auto Adaptor = createFunctionToLoopPassAdaptor(MLNPHandle.getPass());
    ASSERT_TRUE(Adaptor.isLoopNestMode());
    FPM.addPass(std::move(Adaptor));
  }

  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  MPM.run(*M, MAM);
}

} // namespace
