//===-- UnrollLoopRuntime.cpp - Runtime Loop unrolling utilities ----------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file implements some loop unrolling utilities for loops with run-time
// trip counts.  See LoopUnroll.cpp for unrolling loops with compile-time
// trip counts.
//
// The functions in this file are used to generate extra code when the
// run-time trip count modulo the unroll factor is not 0.  When this is the
// case, we need to generate code to execute these 'left over' iterations.
//
// The current strategy generates an if-then-else sequence prior to the
// unrolled loop to execute the 'left over' iterations before or after the
// unrolled loop.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopIterator.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ProfDataUtils.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
#include "llvm/Transforms/Utils/UnrollLoop.h"
#include <cmath>

using namespace llvm;

#define DEBUG_TYPE "loop-unroll"

STATISTIC(NumRuntimeUnrolled,
          "Number of loops unrolled with run-time trip counts");
static cl::opt<bool> UnrollRuntimeMultiExit(
    "unroll-runtime-multi-exit", cl::init(false), cl::Hidden,
    cl::desc("Allow runtime unrolling for loops with multiple exits, when "
             "epilog is generated"));
static cl::opt<bool> UnrollRuntimeOtherExitPredictable(
    "unroll-runtime-other-exit-predictable", cl::init(false), cl::Hidden,
    cl::desc("Assume the non latch exit block to be predictable"));

// Probability that the loop trip count is so small that after the prolog
// we do not enter the unrolled loop at all.
// It is unlikely that the loop trip count is smaller than the unroll factor;
// other than that, the choice of constant is not tuned yet.
static const uint32_t UnrolledLoopHeaderWeights[] = {1, 127};
// Probability that the loop trip count is so small that we skip the unrolled
// loop completely and immediately enter the epilogue loop.
// It is unlikely that the loop trip count is smaller than the unroll factor;
// other than that, the choice of constant is not tuned yet.
static const uint32_t EpilogHeaderWeights[] = {1, 127};

/// Connect the unrolling prolog code to the original loop.
/// The unrolling prolog code contains code to execute the
/// 'extra' iterations if the run-time trip count modulo the
/// unroll count is non-zero.
///
/// This function performs the following:
/// - Create PHI nodes at prolog end block to combine values
///   that exit the prolog code and jump around the prolog.
/// - Add a PHI operand to a PHI node at the loop exit block
///   for values that exit the prolog and go around the loop.
/// - Branch around the original loop if the trip count is less
///   than the unroll factor.
///
static void ConnectProlog(Loop *L, Value *BECount, unsigned Count,
                          BasicBlock *PrologExit,
                          BasicBlock *OriginalLoopLatchExit,
                          BasicBlock *PreHeader, BasicBlock *NewPreHeader,
                          ValueToValueMapTy &VMap, DominatorTree *DT,
                          LoopInfo *LI, bool PreserveLCSSA,
                          ScalarEvolution &SE) {
  // Loop structure should be the following:
  // Preheader
  //  PrologHeader
  //  ...
  //  PrologLatch
  //  PrologExit
  //   NewPreheader
  //    Header
  //    ...
  //    Latch
  //      LatchExit
  BasicBlock *Latch = L->getLoopLatch();
  assert(Latch && "Loop must have a latch");
  BasicBlock *PrologLatch = cast<BasicBlock>(VMap[Latch]);

  // Create a PHI node for each outgoing value from the original loop
  // (which means it is an outgoing value from the prolog code too).
  // The new PHI node is inserted in the prolog end basic block.
  // The new PHI node value is added as an operand of a PHI node in either
  // the loop header or the loop exit block.
  for (BasicBlock *Succ : successors(Latch)) {
    for (PHINode &PN : Succ->phis()) {
      // Add a new PHI node to the prolog end block and add the
      // appropriate incoming values.
      // TODO: This code assumes that the PrologExit (or the LatchExit block for
      // prolog loop) contains only one predecessor from the loop, i.e. the
      // PrologLatch. When supporting multiple-exiting block loops, we can have
      // two or more blocks that have the LatchExit as the target in the
      // original loop.
      PHINode *NewPN = PHINode::Create(PN.getType(), 2, PN.getName() + ".unr");
      NewPN->insertBefore(PrologExit->getFirstNonPHIIt());
      // Adding a value to the new PHI node from the original loop preheader.
      // This is the value that skips all the prolog code.
      if (L->contains(&PN)) {
        // Succ is loop header.
        NewPN->addIncoming(PN.getIncomingValueForBlock(NewPreHeader),
                           PreHeader);
      } else {
        // Succ is LatchExit.
        NewPN->addIncoming(PoisonValue::get(PN.getType()), PreHeader);
      }

      Value *V = PN.getIncomingValueForBlock(Latch);
      if (Instruction *I = dyn_cast<Instruction>(V)) {
        if (L->contains(I)) {
          V = VMap.lookup(I);
        }
      }
      // Adding a value to the new PHI node from the last prolog block
      // that was created.
      NewPN->addIncoming(V, PrologLatch);

      // Update the existing PHI node operand with the value from the
      // new PHI node.  How this is done depends on if the existing
      // PHI node is in the original loop block, or the exit block.
      if (L->contains(&PN))
        PN.setIncomingValueForBlock(NewPreHeader, NewPN);
      else
        PN.addIncoming(NewPN, PrologExit);
      SE.forgetLcssaPhiWithNewPredecessor(L, &PN);
    }
  }

  // Make sure that created prolog loop is in simplified form
  SmallVector<BasicBlock *, 4> PrologExitPreds;
  Loop *PrologLoop = LI->getLoopFor(PrologLatch);
  if (PrologLoop) {
    for (BasicBlock *PredBB : predecessors(PrologExit))
      if (PrologLoop->contains(PredBB))
        PrologExitPreds.push_back(PredBB);

    SplitBlockPredecessors(PrologExit, PrologExitPreds, ".unr-lcssa", DT, LI,
                           nullptr, PreserveLCSSA);
  }

  // Create a branch around the original loop, which is taken if there are no
  // iterations remaining to be executed after running the prologue.
  Instruction *InsertPt = PrologExit->getTerminator();
  IRBuilder<> B(InsertPt);

  assert(Count != 0 && "nonsensical Count!");

  // If BECount <u (Count - 1) then (BECount + 1) % Count == (BECount + 1)
  // This means %xtraiter is (BECount + 1) and all of the iterations of this
  // loop were executed by the prologue.  Note that if BECount <u (Count - 1)
  // then (BECount + 1) cannot unsigned-overflow.
  Value *BrLoopExit =
      B.CreateICmpULT(BECount, ConstantInt::get(BECount->getType(), Count - 1));
  // Split the exit to maintain loop canonicalization guarantees
  SmallVector<BasicBlock *, 4> Preds(predecessors(OriginalLoopLatchExit));
  SplitBlockPredecessors(OriginalLoopLatchExit, Preds, ".unr-lcssa", DT, LI,
                         nullptr, PreserveLCSSA);
  // Add the branch to the exit block (around the unrolled loop)
  MDNode *BranchWeights = nullptr;
  if (hasBranchWeightMD(*Latch->getTerminator())) {
    // Assume loop is nearly always entered.
    MDBuilder MDB(B.getContext());
    BranchWeights = MDB.createBranchWeights(UnrolledLoopHeaderWeights);
  }
  B.CreateCondBr(BrLoopExit, OriginalLoopLatchExit, NewPreHeader,
                 BranchWeights);
  InsertPt->eraseFromParent();
  if (DT) {
    auto *NewDom = DT->findNearestCommonDominator(OriginalLoopLatchExit,
                                                  PrologExit);
    DT->changeImmediateDominator(OriginalLoopLatchExit, NewDom);
  }
}

/// Assume, due to our position in the remainder loop or its guard, anywhere
/// from 0 to \p N more iterations can possibly execute.  Among such cases in
/// the original loop (with loop probability \p OriginalLoopProb), what is the
/// probability of executing at least one more iteration?
static BranchProbability
probOfNextInRemainder(BranchProbability OriginalLoopProb, unsigned N) {
  // OriginalLoopProb == 1 would produce a division by zero in the calculation
  // below.  The problem is that case indicates an always infinite loop, but a
  // remainder loop cannot be calculated at run time if the original loop is
  // infinite as infinity % UnrollCount is undefined.  We then choose
  // probabilities indicating that all remainder loop iterations will always
  // execute.
  //
  // Currently, the remainder loop here is an epilogue, which cannot be reached
  // if the original loop is infinite, so the aforementioned choice is
  // arbitrary.
  //
  // FIXME: Branch weights still need to be fixed in the case of prologues
  // (issue #135812).  In that case, the aforementioned choice seems reasonable
  // for the goal of maintaining the original loop's block frequencies.  That
  // is, an infinite loop's initial iterations are not skipped, and the prologue
  // loop body might have unique blocks that execute a finite number of times
  // if, for example, the original loop body contains conditionals like i <
  // UnrollCount.
  if (OriginalLoopProb.isOne())
    return OriginalLoopProb;

  // Each of these variables holds the original loop's probability that the
  // number of iterations it will execute is some m in the specified range.
  BranchProbability ProbOne = OriginalLoopProb;                // 1 <= m
  BranchProbability ProbTooMany = ProbOne.pow(N + 1);          // N + 1 <= m
  BranchProbability ProbNotTooMany = ProbTooMany.getCompl();   // 0 <= m <= N
  BranchProbability ProbOneNotTooMany = ProbOne - ProbTooMany; // 1 <= m <= N
  return ProbOneNotTooMany / ProbNotTooMany;
}

/// Connect the unrolling epilog code to the original loop.
/// The unrolling epilog code contains code to execute the
/// 'extra' iterations if the run-time trip count modulo the
/// unroll count is non-zero.
///
/// This function performs the following:
/// - Update PHI nodes at the epilog loop exit
/// - Create PHI nodes at the unrolling loop exit and epilog preheader to
///   combine values that exit the unrolling loop code and jump around it.
/// - Update PHI operands in the epilog loop by the new PHI nodes
/// - At the unrolling loop exit, branch around the epilog loop if extra iters
//    (ModVal) is zero.
/// - At the epilog preheader, add an llvm.assume call that extra iters is
///   non-zero.  If the unrolling loop exit is the predecessor, the above new
///   branch guarantees that assumption.  If the unrolling loop preheader is the
///   predecessor, then the required first iteration from the original loop has
///   yet to be executed, so it must be executed in the epilog loop.  If we
///   later unroll the epilog loop, that llvm.assume call somehow enables
///   ScalarEvolution to compute a epilog loop maximum trip count, which enables
///   eliminating the branch at the end of the final unrolled epilog iteration.
///
static void ConnectEpilog(Loop *L, Value *ModVal, BasicBlock *NewExit,
                          BasicBlock *Exit, BasicBlock *PreHeader,
                          BasicBlock *EpilogPreHeader, BasicBlock *NewPreHeader,
                          ValueToValueMapTy &VMap, DominatorTree *DT,
                          LoopInfo *LI, bool PreserveLCSSA, ScalarEvolution &SE,
                          unsigned Count, AssumptionCache &AC,
                          BranchProbability OriginalLoopProb) {
  BasicBlock *Latch = L->getLoopLatch();
  assert(Latch && "Loop must have a latch");
  BasicBlock *EpilogLatch = cast<BasicBlock>(VMap[Latch]);

  // Loop structure should be the following:
  //
  // PreHeader
  // NewPreHeader
  //   Header
  //   ...
  //   Latch
  // NewExit (PN)
  // EpilogPreHeader
  //   EpilogHeader
  //   ...
  //   EpilogLatch
  // Exit (EpilogPN)

  // Update PHI nodes at Exit.
  for (PHINode &PN : NewExit->phis()) {
    // PN should be used in another PHI located in Exit block as
    // Exit was split by SplitBlockPredecessors into Exit and NewExit
    // Basically it should look like:
    // NewExit:
    //   PN = PHI [I, Latch]
    // ...
    // Exit:
    //   EpilogPN = PHI [PN, EpilogPreHeader], [X, Exit2], [Y, Exit2.epil]
    //
    // Exits from non-latch blocks point to the original exit block and the
    // epilogue edges have already been added.
    //
    // There is EpilogPreHeader incoming block instead of NewExit as
    // NewExit was split 1 more time to get EpilogPreHeader.
    assert(PN.hasOneUse() && "The phi should have 1 use");
    PHINode *EpilogPN = cast<PHINode>(PN.use_begin()->getUser());
    assert(EpilogPN->getParent() == Exit && "EpilogPN should be in Exit block");

    Value *V = PN.getIncomingValueForBlock(Latch);
    Instruction *I = dyn_cast<Instruction>(V);
    if (I && L->contains(I))
      // If value comes from an instruction in the loop add VMap value.
      V = VMap.lookup(I);
    // For the instruction out of the loop, constant or undefined value
    // insert value itself.
    EpilogPN->addIncoming(V, EpilogLatch);

    assert(EpilogPN->getBasicBlockIndex(EpilogPreHeader) >= 0 &&
          "EpilogPN should have EpilogPreHeader incoming block");
    // Change EpilogPreHeader incoming block to NewExit.
    EpilogPN->setIncomingBlock(EpilogPN->getBasicBlockIndex(EpilogPreHeader),
                               NewExit);
    // Now PHIs should look like:
    // NewExit:
    //   PN = PHI [I, Latch]
    // ...
    // Exit:
    //   EpilogPN = PHI [PN, NewExit], [VMap[I], EpilogLatch]
  }

  // Create PHI nodes at NewExit (from the unrolling loop Latch) and at
  // EpilogPreHeader (from PreHeader and NewExit).  Update corresponding PHI
  // nodes in epilog loop.
  for (BasicBlock *Succ : successors(Latch)) {
    // Skip this as we already updated phis in exit blocks.
    if (!L->contains(Succ))
      continue;

    // Succ here appears to always be just L->getHeader().  Otherwise, how do we
    // know its corresponding epilog block (from VMap) is EpilogHeader and thus
    // EpilogPreHeader is the right incoming block for VPN, as set below?
    // TODO: Can we thus avoid the enclosing loop over successors?
    assert(Succ == L->getHeader() &&
           "Expect the only in-loop successor of latch to be the loop header");

    for (PHINode &PN : Succ->phis()) {
      // Add new PHI nodes to the loop exit block.
      PHINode *NewPN0 = PHINode::Create(PN.getType(), /*NumReservedValues=*/1,
                                        PN.getName() + ".unr");
      NewPN0->insertBefore(NewExit->getFirstNonPHIIt());
      // Add value to the new PHI node from the unrolling loop latch.
      NewPN0->addIncoming(PN.getIncomingValueForBlock(Latch), Latch);

      // Add new PHI nodes to EpilogPreHeader.
      PHINode *NewPN1 = PHINode::Create(PN.getType(), /*NumReservedValues=*/2,
                                        PN.getName() + ".epil.init");
      NewPN1->insertBefore(EpilogPreHeader->getFirstNonPHIIt());
      // Add value to the new PHI node from the unrolling loop preheader.
      NewPN1->addIncoming(PN.getIncomingValueForBlock(NewPreHeader), PreHeader);
      // Add value to the new PHI node from the epilog loop guard.
      NewPN1->addIncoming(NewPN0, NewExit);

      // Update the existing PHI node operand with the value from the new PHI
      // node.  Corresponding instruction in epilog loop should be PHI.
      PHINode *VPN = cast<PHINode>(VMap[&PN]);
      VPN->setIncomingValueForBlock(EpilogPreHeader, NewPN1);
    }
  }

  // In NewExit, branch around the epilog loop if no extra iters.
  Instruction *InsertPt = NewExit->getTerminator();
  IRBuilder<> B(InsertPt);
  Value *BrLoopExit = B.CreateIsNotNull(ModVal, "lcmp.mod");
  assert(Exit && "Loop must have a single exit block only");
  // Split the epilogue exit to maintain loop canonicalization guarantees
  SmallVector<BasicBlock*, 4> Preds(predecessors(Exit));
  SplitBlockPredecessors(Exit, Preds, ".epilog-lcssa", DT, LI, nullptr,
                         PreserveLCSSA);
  // Add the branch to the exit block (around the epilog loop)
  MDNode *BranchWeights = nullptr;
  if (OriginalLoopProb.isUnknown() &&
      hasBranchWeightMD(*Latch->getTerminator())) {
    // Assume equal distribution in interval [0, Count).
    MDBuilder MDB(B.getContext());
    BranchWeights = MDB.createBranchWeights(1, Count - 1);
  }
  CondBrInst *RemainderLoopGuard =
      B.CreateCondBr(BrLoopExit, EpilogPreHeader, Exit, BranchWeights);
  if (!OriginalLoopProb.isUnknown()) {
    setBranchProbability(RemainderLoopGuard,
                         probOfNextInRemainder(OriginalLoopProb, Count - 1),
                         /*ForFirstTarget=*/true);
  }
  InsertPt->eraseFromParent();
  if (DT) {
    auto *NewDom = DT->findNearestCommonDominator(Exit, NewExit);
    DT->changeImmediateDominator(Exit, NewDom);
  }

  // In EpilogPreHeader, assume extra iters is non-zero.
  IRBuilder<> B2(EpilogPreHeader, EpilogPreHeader->getFirstNonPHIIt());
  Value *ModIsNotNull = B2.CreateIsNotNull(ModVal, "lcmp.mod");
  AssumeInst *AI = cast<AssumeInst>(B2.CreateAssumption(ModIsNotNull));
  AC.registerAssumption(AI);
}

/// Create a clone of the blocks in a loop and connect them together. A new
/// loop will be created including all cloned blocks, and the iterator of the
/// new loop switched to count NewIter down to 0.
/// The cloned blocks should be inserted between InsertTop and InsertBot.
/// InsertTop should be new preheader, InsertBot new loop exit.
/// Returns the new cloned loop that is created.
static Loop *CloneLoopBlocks(Loop *L, Value *NewIter,
                             const bool UseEpilogRemainder,
                             const bool UnrollRemainder, BasicBlock *InsertTop,
                             BasicBlock *InsertBot, BasicBlock *Preheader,
                             std::vector<BasicBlock *> &NewBlocks,
                             LoopBlocksDFS &LoopBlocks, ValueToValueMapTy &VMap,
                             DominatorTree *DT, LoopInfo *LI, unsigned Count,
                             std::optional<unsigned> OriginalTripCount,
                             BranchProbability OriginalLoopProb) {
  StringRef suffix = UseEpilogRemainder ? "epil" : "prol";
  BasicBlock *Header = L->getHeader();
  BasicBlock *Latch = L->getLoopLatch();
  Function *F = Header->getParent();
  LoopBlocksDFS::RPOIterator BlockBegin = LoopBlocks.beginRPO();
  LoopBlocksDFS::RPOIterator BlockEnd = LoopBlocks.endRPO();
  Loop *ParentLoop = L->getParentLoop();
  NewLoopsMap NewLoops;
  NewLoops[ParentLoop] = ParentLoop;

  // For each block in the original loop, create a new copy,
  // and update the value map with the newly created values.
  for (LoopBlocksDFS::RPOIterator BB = BlockBegin; BB != BlockEnd; ++BB) {
    BasicBlock *NewBB = CloneBasicBlock(*BB, VMap, "." + suffix, F);
    NewBlocks.push_back(NewBB);

    addClonedBlockToLoopInfo(*BB, NewBB, LI, NewLoops);

    VMap[*BB] = NewBB;
    if (Header == *BB) {
      // For the first block, add a CFG connection to this newly
      // created block.
      InsertTop->getTerminator()->setSuccessor(0, NewBB);
    }

    if (DT) {
      if (Header == *BB) {
        // The header is dominated by the preheader.
        DT->addNewBlock(NewBB, InsertTop);
      } else {
        // Copy information from original loop to unrolled loop.
        BasicBlock *IDomBB = DT->getNode(*BB)->getIDom()->getBlock();
        DT->addNewBlock(NewBB, cast<BasicBlock>(VMap[IDomBB]));
      }
    }

    if (Latch == *BB) {
      // For the last block, create a loop back to cloned head.
      VMap.erase((*BB)->getTerminator());
      // Use an incrementing IV.  Pre-incr/post-incr is backedge/trip count.
      // Subtle: NewIter can be 0 if we wrapped when computing the trip count,
      // thus we must compare the post-increment (wrapping) value.
      BasicBlock *FirstLoopBB = cast<BasicBlock>(VMap[Header]);
      CondBrInst *LatchBR = cast<CondBrInst>(NewBB->getTerminator());
      IRBuilder<> Builder(LatchBR);
      PHINode *NewIdx =
          PHINode::Create(NewIter->getType(), 2, suffix + ".iter");
      NewIdx->insertBefore(FirstLoopBB->getFirstNonPHIIt());
      auto *Zero = ConstantInt::get(NewIdx->getType(), 0);
      auto *One = ConstantInt::get(NewIdx->getType(), 1);
      Value *IdxNext =
          Builder.CreateAdd(NewIdx, One, NewIdx->getName() + ".next");
      Value *IdxCmp = Builder.CreateICmpNE(IdxNext, NewIter, NewIdx->getName() + ".cmp");
      MDNode *BranchWeights = nullptr;
      if ((OriginalLoopProb.isUnknown() || !UseEpilogRemainder) &&
          hasBranchWeightMD(*LatchBR)) {
        uint32_t ExitWeight;
        uint32_t BackEdgeWeight;
        if (Count >= 3) {
          // Note: We do not enter this loop for zero-remainders. The check
          // is at the end of the loop. We assume equal distribution between
          // possible remainders in [1, Count).
          ExitWeight = 1;
          BackEdgeWeight = (Count - 2) / 2;
        } else {
          // Unnecessary backedge, should never be taken. The conditional
          // jump should be optimized away later.
          ExitWeight = 1;
          BackEdgeWeight = 0;
        }
        MDBuilder MDB(Builder.getContext());
        BranchWeights = MDB.createBranchWeights(BackEdgeWeight, ExitWeight);
      }
      CondBrInst *RemainderLoopLatch =
          Builder.CreateCondBr(IdxCmp, FirstLoopBB, InsertBot, BranchWeights);
      if (!OriginalLoopProb.isUnknown() && UseEpilogRemainder) {
        // Compute the total frequency of the original loop body from the
        // remainder iterations.  Once we've reached them, the first of them
        // always executes, so its frequency and probability are 1.
        double FreqRemIters = 1;
        if (Count > 2) {
          BranchProbability ProbReaching = BranchProbability::getOne();
          for (unsigned N = Count - 2; N >= 1; --N) {
            ProbReaching *= probOfNextInRemainder(OriginalLoopProb, N);
            FreqRemIters += ProbReaching.toDouble();
          }
        }
        // Solve for the loop probability that would produce that frequency.
        // Sum(i=0..inf)(Prob^i) = 1/(1-Prob) = FreqRemIters.
        BranchProbability Prob =
            BranchProbability::getBranchProbability(1 - 1 / FreqRemIters);
        setBranchProbability(RemainderLoopLatch, Prob, /*ForFirstTarget=*/true);
      }
      NewIdx->addIncoming(Zero, InsertTop);
      NewIdx->addIncoming(IdxNext, NewBB);
      LatchBR->eraseFromParent();
    }
  }

  // Change the incoming values to the ones defined in the preheader or
  // cloned loop.
  for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
    PHINode *NewPHI = cast<PHINode>(VMap[&*I]);
    unsigned idx = NewPHI->getBasicBlockIndex(Preheader);
    NewPHI->setIncomingBlock(idx, InsertTop);
    BasicBlock *NewLatch = cast<BasicBlock>(VMap[Latch]);
    idx = NewPHI->getBasicBlockIndex(Latch);
    Value *InVal = NewPHI->getIncomingValue(idx);
    NewPHI->setIncomingBlock(idx, NewLatch);
    if (Value *V = VMap.lookup(InVal))
      NewPHI->setIncomingValue(idx, V);
  }

  Loop *NewLoop = NewLoops[L];
  assert(NewLoop && "L should have been cloned");

  if (OriginalTripCount && UseEpilogRemainder)
    setLoopEstimatedTripCount(NewLoop, *OriginalTripCount % Count);

  // Add unroll disable metadata to disable future unrolling for this loop.
  if (!UnrollRemainder)
    NewLoop->setLoopAlreadyUnrolled();
  return NewLoop;
}

/// Returns true if we can profitably unroll the multi-exit loop L.
static bool canProfitablyRuntimeUnrollMultiExitLoop(
    Loop *L, const TargetTransformInfo *TTI,
    SmallVectorImpl<BasicBlock *> &OtherExits, BasicBlock *LatchExit,
    bool UseEpilogRemainder) {

  // The main pain point with multi-exit loop unrolling is that once unrolled,
  // we will not be able to merge all blocks into a straight line code.
  // There are branches within the unrolled loop that go to the OtherExits.
  // The second point is the increase in code size, but this is true
  // irrespective of multiple exits.

  // Note: Both the heuristics below are coarse grained. We are essentially
  // enabling unrolling of loops that have a single side exit other than the
  // normal LatchExit (i.e. exiting into a deoptimize block).
  // The heuristics considered are:
  // 1. low number of branches in the unrolled version.
  // 2. high predictability of these extra branches.
  // We avoid unrolling loops that have more than two exiting blocks. This
  // limits the total number of branches in the unrolled loop to be atmost
  // the unroll factor (since one of the exiting blocks is the latch block).
  SmallVector<BasicBlock*, 4> ExitingBlocks;
  L->getExitingBlocks(ExitingBlocks);
  if (ExitingBlocks.size() > 2)
    return false;

  // Allow unrolling of loops with no non latch exit blocks.
  if (OtherExits.size() == 0)
    return true;

  if (OtherExits.size() != 1)
    return false;

  // When UnrollRuntimeOtherExitPredictable is specified, we assume the other
  // exit branch is predictable even if it has no deoptimize call.
  if (UnrollRuntimeOtherExitPredictable)
    return true;

  // The second heuristic is that L has one exit other than the latchexit and
  // that exit is highly unlikely.
  if (TTI) {
    BasicBlock *LatchBB = L->getLoopLatch();
    assert(LatchBB && "Expected loop to have a latch");
    BasicBlock *NonLatchExitingBlock =
        (ExitingBlocks[0] == LatchBB) ? ExitingBlocks[1] : ExitingBlocks[0];
    auto BranchProb =
        llvm::getBranchProbability(NonLatchExitingBlock, OtherExits[0]);
    // If BranchProbability could not be extracted (returns unknown), then
    // don't return and do the check for deopt block.
    if (!BranchProb.isUnknown()) {
      auto Threshold = TTI->getPredictableBranchThreshold().getCompl();
      return BranchProb < Threshold;
    }
  }

  // We know that deoptimize blocks are rarely taken, which also implies the
  // branch leading to the deoptimize block is highly unlikely.
  return OtherExits[0]->getPostdominatingDeoptimizeCall();
  // TODO: These can be fine-tuned further to consider code size or deopt states
  // that are captured by the deoptimize exit block.
  // Also, we can extend this to support more cases, if we actually
  // know of kinds of multiexit loops that would benefit from unrolling.
}

/// Calculate ModVal = (BECount + 1) % Count on the abstract integer domain
/// accounting for the possibility of unsigned overflow in the 2s complement
/// domain. Preconditions:
/// 1) TripCount = BECount + 1 (allowing overflow)
/// 2) Log2(Count) <= BitWidth(BECount)
static Value *CreateTripRemainder(IRBuilder<> &B, Value *BECount,
                                  Value *TripCount, unsigned Count) {
  // Note that TripCount is BECount + 1.
  if (isPowerOf2_32(Count))
    // If the expression is zero, then either:
    //  1. There are no iterations to be run in the prolog/epilog loop.
    // OR
    //  2. The addition computing TripCount overflowed.
    //
    // If (2) is true, we know that TripCount really is (1 << BEWidth) and so
    // the number of iterations that remain to be run in the original loop is a
    // multiple Count == (1 << Log2(Count)) because Log2(Count) <= BEWidth (a
    // precondition of this method).
    return B.CreateAnd(TripCount, Count - 1, "xtraiter");

  // As (BECount + 1) can potentially unsigned overflow we count
  // (BECount % Count) + 1 which is overflow safe as BECount % Count < Count.
  Constant *CountC = ConstantInt::get(BECount->getType(), Count);
  Value *ModValTmp = B.CreateURem(BECount, CountC);
  Value *ModValAdd = B.CreateAdd(ModValTmp,
                                 ConstantInt::get(ModValTmp->getType(), 1));
  // At that point (BECount % Count) + 1 could be equal to Count.
  // To handle this case we need to take mod by Count one more time.
  return B.CreateURem(ModValAdd, CountC, "xtraiter");
}


/// Insert code in the prolog/epilog code when unrolling a loop with a
/// run-time trip-count.
///
/// This method assumes that the loop unroll factor is total number
/// of loop bodies in the loop after unrolling. (Some folks refer
/// to the unroll factor as the number of *extra* copies added).
/// We assume also that the loop unroll factor is a power-of-two. So, after
/// unrolling the loop, the number of loop bodies executed is 2,
/// 4, 8, etc.  Note - LLVM converts the if-then-sequence to a switch
/// instruction in SimplifyCFG.cpp.  Then, the backend decides how code for
/// the switch instruction is generated.
///
/// ***Prolog case***
///        extraiters = tripcount % loopfactor
///        if (extraiters == 0) jump Loop:
///        else jump Prol:
/// Prol:  LoopBody;
///        extraiters -= 1                 // Omitted if unroll factor is 2.
///        if (extraiters != 0) jump Prol: // Omitted if unroll factor is 2.
///        if (tripcount < loopfactor) jump End:
/// Loop:
/// ...
/// End:
///
/// ***Epilog case***
///        extraiters = tripcount % loopfactor
///        if (tripcount < loopfactor) jump LoopExit:
///        unroll_iters = tripcount - extraiters
/// Loop:  LoopBody; (executes unroll_iter times);
///        unroll_iter -= 1
///        if (unroll_iter != 0) jump Loop:
/// LoopExit:
///        if (extraiters == 0) jump EpilExit:
/// Epil:  LoopBody; (executes extraiters times)
///        extraiters -= 1                 // Omitted if unroll factor is 2.
///        if (extraiters != 0) jump Epil: // Omitted if unroll factor is 2.
/// EpilExit:

bool llvm::UnrollRuntimeLoopRemainder(
    Loop *L, unsigned Count, bool AllowExpensiveTripCount,
    bool UseEpilogRemainder, bool UnrollRemainder, bool ForgetAllSCEV,
    LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
    const TargetTransformInfo *TTI, bool PreserveLCSSA,
    unsigned SCEVExpansionBudget, bool RuntimeUnrollMultiExit,
    Loop **ResultLoop, std::optional<unsigned> OriginalTripCount,
    BranchProbability OriginalLoopProb) {
  LLVM_DEBUG(dbgs() << "Trying runtime unrolling on Loop: \n");
  LLVM_DEBUG(L->dump());
  LLVM_DEBUG(UseEpilogRemainder ? dbgs() << "Using epilog remainder.\n"
                                : dbgs() << "Using prolog remainder.\n");

  // Make sure the loop is in canonical form.
  if (!L->isLoopSimplifyForm()) {
    LLVM_DEBUG(dbgs() << "Not in simplify form!\n");
    return false;
  }

  // Guaranteed by LoopSimplifyForm.
  BasicBlock *Latch = L->getLoopLatch();
  BasicBlock *Header = L->getHeader();

  CondBrInst *LatchBR = dyn_cast<CondBrInst>(Latch->getTerminator());

  if (!LatchBR) {
    // The loop-rotate pass can be helpful to avoid this in many cases.
    LLVM_DEBUG(
        dbgs()
        << "Loop latch not terminated by a conditional branch.\n");
    return false;
  }

  unsigned ExitIndex = LatchBR->getSuccessor(0) == Header ? 1 : 0;
  BasicBlock *LatchExit = LatchBR->getSuccessor(ExitIndex);

  if (L->contains(LatchExit)) {
    // Cloning the loop basic blocks (`CloneLoopBlocks`) requires that one of the
    // targets of the Latch be an exit block out of the loop.
    LLVM_DEBUG(
        dbgs()
        << "One of the loop latch successors must be the exit block.\n");
    return false;
  }

  // These are exit blocks other than the target of the latch exiting block.
  SmallVector<BasicBlock *, 4> OtherExits;
  L->getUniqueNonLatchExitBlocks(OtherExits);
  // Support only single exit and exiting block unless multi-exit loop
  // unrolling is enabled.
  if (!L->getExitingBlock() || OtherExits.size()) {
    // We rely on LCSSA form being preserved when the exit blocks are transformed.
    // (Note that only an off-by-default mode of the old PM disables PreserveLCCA.)
    if (!PreserveLCSSA)
      return false;

    // Priority goes to UnrollRuntimeMultiExit if it's supplied.
    if (UnrollRuntimeMultiExit.getNumOccurrences()) {
      if (!UnrollRuntimeMultiExit)
        return false;
    } else {
      // Otherwise perform multi-exit unrolling, if either the target indicates
      // it is profitable or the general profitability heuristics apply.
      if (!RuntimeUnrollMultiExit &&
          !canProfitablyRuntimeUnrollMultiExitLoop(
              L, TTI, OtherExits, LatchExit, UseEpilogRemainder)) {
        LLVM_DEBUG(dbgs() << "Multiple exit/exiting blocks in loop and "
                             "multi-exit unrolling not enabled!\n");
        return false;
      }
    }
  }
  // Use Scalar Evolution to compute the trip count. This allows more loops to
  // be unrolled than relying on induction var simplification.
  if (!SE)
    return false;

  // Only unroll loops with a computable trip count.
  // We calculate the backedge count by using getExitCount on the Latch block,
  // which is proven to be the only exiting block in this loop. This is same as
  // calculating getBackedgeTakenCount on the loop (which computes SCEV for all
  // exiting blocks).
  const SCEV *BECountSC = SE->getExitCount(L, Latch);
  if (isa<SCEVCouldNotCompute>(BECountSC)) {
    LLVM_DEBUG(dbgs() << "Could not compute exit block SCEV\n");
    return false;
  }

  unsigned BEWidth = cast<IntegerType>(BECountSC->getType())->getBitWidth();

  // Add 1 since the backedge count doesn't include the first loop iteration.
  // (Note that overflow can occur, this is handled explicitly below)
  const SCEV *TripCountSC =
      SE->getAddExpr(BECountSC, SE->getConstant(BECountSC->getType(), 1));
  if (isa<SCEVCouldNotCompute>(TripCountSC)) {
    LLVM_DEBUG(dbgs() << "Could not compute trip count SCEV.\n");
    return false;
  }

  BasicBlock *PreHeader = L->getLoopPreheader();
  Instruction *PreHeaderBR = PreHeader->getTerminator();
  SCEVExpander Expander(*SE, "loop-unroll");
  if (!AllowExpensiveTripCount &&
      Expander.isHighCostExpansion(TripCountSC, L, SCEVExpansionBudget, TTI,
                                   PreHeaderBR)) {
    LLVM_DEBUG(dbgs() << "High cost for expanding trip count scev!\n");
    return false;
  }

  // This constraint lets us deal with an overflowing trip count easily; see the
  // comment on ModVal below.
  if (Log2_32(Count) > BEWidth) {
    LLVM_DEBUG(
        dbgs()
        << "Count failed constraint on overflow trip count calculation.\n");
    return false;
  }

  // Loop structure is the following:
  //
  // PreHeader
  //   Header
  //   ...
  //   Latch
  // LatchExit

  BasicBlock *NewPreHeader;
  BasicBlock *NewExit = nullptr;
  BasicBlock *PrologExit = nullptr;
  BasicBlock *EpilogPreHeader = nullptr;
  BasicBlock *PrologPreHeader = nullptr;

  if (UseEpilogRemainder) {
    // If epilog remainder
    // Split PreHeader to insert a branch around loop for unrolling.
    NewPreHeader = SplitBlock(PreHeader, PreHeader->getTerminator(), DT, LI);
    NewPreHeader->setName(PreHeader->getName() + ".new");
    // Split LatchExit to create phi nodes from branch above.
    NewExit = SplitBlockPredecessors(LatchExit, {Latch}, ".unr-lcssa", DT, LI,
                                     nullptr, PreserveLCSSA);
    // NewExit gets its DebugLoc from LatchExit, which is not part of the
    // original Loop.
    // Fix this by setting Loop's DebugLoc to NewExit.
    auto *NewExitTerminator = NewExit->getTerminator();
    NewExitTerminator->setDebugLoc(Header->getTerminator()->getDebugLoc());
    // Split NewExit to insert epilog remainder loop.
    EpilogPreHeader = SplitBlock(NewExit, NewExitTerminator, DT, LI);
    EpilogPreHeader->setName(Header->getName() + ".epil.preheader");

    // If the latch exits from multiple level of nested loops, then
    // by assumption there must be another loop exit which branches to the
    // outer loop and we must adjust the loop for the newly inserted blocks
    // to account for the fact that our epilogue is still in the same outer
    // loop. Note that this leaves loopinfo temporarily out of sync with the
    // CFG until the actual epilogue loop is inserted.
    if (auto *ParentL = L->getParentLoop())
      if (LI->getLoopFor(LatchExit) != ParentL) {
        LI->removeBlock(NewExit);
        ParentL->addBasicBlockToLoop(NewExit, *LI);
        LI->removeBlock(EpilogPreHeader);
        ParentL->addBasicBlockToLoop(EpilogPreHeader, *LI);
      }

  } else {
    // If prolog remainder
    // Split the original preheader twice to insert prolog remainder loop
    PrologPreHeader = SplitEdge(PreHeader, Header, DT, LI);
    PrologPreHeader->setName(Header->getName() + ".prol.preheader");
    PrologExit = SplitBlock(PrologPreHeader, PrologPreHeader->getTerminator(),
                            DT, LI);
    PrologExit->setName(Header->getName() + ".prol.loopexit");
    // Split PrologExit to get NewPreHeader.
    NewPreHeader = SplitBlock(PrologExit, PrologExit->getTerminator(), DT, LI);
    NewPreHeader->setName(PreHeader->getName() + ".new");
  }
  // Loop structure should be the following:
  //  Epilog             Prolog
  //
  // PreHeader         PreHeader
  // *NewPreHeader     *PrologPreHeader
  //   Header          *PrologExit
  //   ...             *NewPreHeader
  //   Latch             Header
  // *NewExit            ...
  // *EpilogPreHeader    Latch
  // LatchExit              LatchExit

  // Calculate conditions for branch around loop for unrolling
  // in epilog case and around prolog remainder loop in prolog case.
  // Compute the number of extra iterations required, which is:
  //  extra iterations = run-time trip count % loop unroll factor
  PreHeaderBR = PreHeader->getTerminator();
  IRBuilder<> B(PreHeaderBR);
  Value *TripCount = Expander.expandCodeFor(TripCountSC, TripCountSC->getType(),
                                            PreHeaderBR);
  Value *BECount;
  // If there are other exits before the latch, that may cause the latch exit
  // branch to never be executed, and the latch exit count may be poison.
  // In this case, freeze the TripCount and base BECount on the frozen
  // TripCount. We will introduce two branches using these values, and it's
  // important that they see a consistent value (which would not be guaranteed
  // if were frozen independently.)
  if ((!OtherExits.empty() || !SE->loopHasNoAbnormalExits(L)) &&
      !isGuaranteedNotToBeUndefOrPoison(TripCount, AC, PreHeaderBR, DT)) {
    TripCount = B.CreateFreeze(TripCount);
    BECount =
        B.CreateAdd(TripCount, Constant::getAllOnesValue(TripCount->getType()));
  } else {
    // If we don't need to freeze, use SCEVExpander for BECount as well, to
    // allow slightly better value reuse.
    BECount =
        Expander.expandCodeFor(BECountSC, BECountSC->getType(), PreHeaderBR);
  }

  Value * const ModVal = CreateTripRemainder(B, BECount, TripCount, Count);

  Value *BranchVal =
      UseEpilogRemainder ? B.CreateICmpULT(BECount,
                                           ConstantInt::get(BECount->getType(),
                                                            Count - 1)) :
                           B.CreateIsNotNull(ModVal, "lcmp.mod");
  BasicBlock *RemainderLoop =
      UseEpilogRemainder ? EpilogPreHeader : PrologPreHeader;
  BasicBlock *UnrollingLoop = UseEpilogRemainder ? NewPreHeader : PrologExit;
  // Branch to either remainder (extra iterations) loop or unrolling loop.
  MDNode *BranchWeights = nullptr;
  if ((OriginalLoopProb.isUnknown() || !UseEpilogRemainder) &&
      hasBranchWeightMD(*Latch->getTerminator())) {
    // Assume loop is nearly always entered.
    MDBuilder MDB(B.getContext());
    BranchWeights = MDB.createBranchWeights(EpilogHeaderWeights);
  }
  CondBrInst *UnrollingLoopGuard =
      B.CreateCondBr(BranchVal, RemainderLoop, UnrollingLoop, BranchWeights);
  if (!OriginalLoopProb.isUnknown() && UseEpilogRemainder) {
    // The original loop's first iteration always happens.  Compute the
    // probability of the original loop executing Count-1 iterations after that
    // to complete the first iteration of the unrolled loop.
    BranchProbability ProbOne = OriginalLoopProb;
    BranchProbability ProbRest = ProbOne.pow(Count - 1);
    setBranchProbability(UnrollingLoopGuard, ProbRest,
                         /*ForFirstTarget=*/false);
  }
  PreHeaderBR->eraseFromParent();
  if (DT) {
    if (UseEpilogRemainder)
      DT->changeImmediateDominator(EpilogPreHeader, PreHeader);
    else
      DT->changeImmediateDominator(PrologExit, PreHeader);
  }
  Function *F = Header->getParent();
  // Get an ordered list of blocks in the loop to help with the ordering of the
  // cloned blocks in the prolog/epilog code
  LoopBlocksDFS LoopBlocks(L);
  LoopBlocks.perform(LI);

  //
  // For each extra loop iteration, create a copy of the loop's basic blocks
  // and generate a condition that branches to the copy depending on the
  // number of 'left over' iterations.
  //
  std::vector<BasicBlock *> NewBlocks;
  ValueToValueMapTy VMap;

  // Clone all the basic blocks in the loop. If Count is 2, we don't clone
  // the loop, otherwise we create a cloned loop to execute the extra
  // iterations. This function adds the appropriate CFG connections.
  BasicBlock *InsertBot = UseEpilogRemainder ? LatchExit : PrologExit;
  BasicBlock *InsertTop = UseEpilogRemainder ? EpilogPreHeader : PrologPreHeader;
  Loop *remainderLoop =
      CloneLoopBlocks(L, ModVal, UseEpilogRemainder, UnrollRemainder, InsertTop,
                      InsertBot, NewPreHeader, NewBlocks, LoopBlocks, VMap, DT,
                      LI, Count, OriginalTripCount, OriginalLoopProb);

  // Insert the cloned blocks into the function.
  F->splice(InsertBot->getIterator(), F, NewBlocks[0]->getIterator(), F->end());

  // Now the loop blocks are cloned and the other exiting blocks from the
  // remainder are connected to the original Loop's exit blocks. The remaining
  // work is to update the phi nodes in the original loop, and take in the
  // values from the cloned region.
  for (auto *BB : OtherExits) {
    // Given we preserve LCSSA form, we know that the values used outside the
    // loop will be used through these phi nodes at the exit blocks that are
    // transformed below.
    for (PHINode &PN : BB->phis()) {
     unsigned oldNumOperands = PN.getNumIncomingValues();
     // Add the incoming values from the remainder code to the end of the phi
     // node.
     for (unsigned i = 0; i < oldNumOperands; i++){
       auto *PredBB =PN.getIncomingBlock(i);
       if (PredBB == Latch)
         // The latch exit is handled separately, see connectX
         continue;
       if (!L->contains(PredBB))
         // Even if we had dedicated exits, the code above inserted an
         // extra branch which can reach the latch exit.
         continue;

       auto *V = PN.getIncomingValue(i);
       if (Instruction *I = dyn_cast<Instruction>(V))
         if (L->contains(I))
           V = VMap.lookup(I);
       PN.addIncoming(V, cast<BasicBlock>(VMap[PredBB]));
     }
   }
#if defined(EXPENSIVE_CHECKS) && !defined(NDEBUG)
    for (BasicBlock *SuccBB : successors(BB)) {
      assert(!(llvm::is_contained(OtherExits, SuccBB) || SuccBB == LatchExit) &&
             "Breaks the definition of dedicated exits!");
    }
#endif
  }

  // Update the immediate dominator of the exit blocks and blocks that are
  // reachable from the exit blocks. This is needed because we now have paths
  // from both the original loop and the remainder code reaching the exit
  // blocks. While the IDom of these exit blocks were from the original loop,
  // now the IDom is the preheader (which decides whether the original loop or
  // remainder code should run) unless the block still has just the original
  // predecessor (such as NewExit in the case of an epilog remainder).
  if (DT && !L->getExitingBlock()) {
    SmallVector<BasicBlock *, 16> ChildrenToUpdate;
    // NB! We have to examine the dom children of all loop blocks, not just
    // those which are the IDom of the exit blocks. This is because blocks
    // reachable from the exit blocks can have their IDom as the nearest common
    // dominator of the exit blocks.
    for (auto *BB : L->blocks()) {
      auto *DomNodeBB = DT->getNode(BB);
      for (auto *DomChild : DomNodeBB->children()) {
        auto *DomChildBB = DomChild->getBlock();
        if (!L->contains(LI->getLoopFor(DomChildBB)) &&
            DomChildBB->getUniquePredecessor() != BB)
          ChildrenToUpdate.push_back(DomChildBB);
      }
    }
    for (auto *BB : ChildrenToUpdate)
      DT->changeImmediateDominator(BB, PreHeader);
  }

  // Loop structure should be the following:
  //  Epilog             Prolog
  //
  // PreHeader         PreHeader
  // NewPreHeader      PrologPreHeader
  //   Header            PrologHeader
  //   ...               ...
  //   Latch             PrologLatch
  // NewExit           PrologExit
  // EpilogPreHeader   NewPreHeader
  //   EpilogHeader      Header
  //   ...               ...
  //   EpilogLatch       Latch
  // LatchExit              LatchExit

  // Rewrite the cloned instruction operands to use the values created when the
  // clone is created.
  for (BasicBlock *BB : NewBlocks) {
    Module *M = BB->getModule();
    for (Instruction &I : *BB) {
      RemapInstruction(&I, VMap,
                       RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
      RemapDbgRecordRange(M, I.getDbgRecordRange(), VMap,
                          RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
    }
  }

  if (UseEpilogRemainder) {
    // Connect the epilog code to the original loop and update the
    // PHI functions.
    ConnectEpilog(L, ModVal, NewExit, LatchExit, PreHeader, EpilogPreHeader,
                  NewPreHeader, VMap, DT, LI, PreserveLCSSA, *SE, Count, *AC,
                  OriginalLoopProb);

    // Update counter in loop for unrolling.
    // Use an incrementing IV.  Pre-incr/post-incr is backedge/trip count.
    // Subtle: TestVal can be 0 if we wrapped when computing the trip count,
    // thus we must compare the post-increment (wrapping) value.
    IRBuilder<> B2(NewPreHeader->getTerminator());
    Value *TestVal = B2.CreateSub(TripCount, ModVal, "unroll_iter");
    CondBrInst *LatchBR = cast<CondBrInst>(Latch->getTerminator());
    PHINode *NewIdx = PHINode::Create(TestVal->getType(), 2, "niter");
    NewIdx->insertBefore(Header->getFirstNonPHIIt());
    B2.SetInsertPoint(LatchBR);
    auto *Zero = ConstantInt::get(NewIdx->getType(), 0);
    auto *One = ConstantInt::get(NewIdx->getType(), 1);
    Value *IdxNext = B2.CreateAdd(NewIdx, One, NewIdx->getName() + ".next");
    auto Pred = LatchBR->getSuccessor(0) == Header ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ;
    Value *IdxCmp = B2.CreateICmp(Pred, IdxNext, TestVal, NewIdx->getName() + ".ncmp");
    NewIdx->addIncoming(Zero, NewPreHeader);
    NewIdx->addIncoming(IdxNext, Latch);
    LatchBR->setCondition(IdxCmp);
  } else {
    // Connect the prolog code to the original loop and update the
    // PHI functions.
    ConnectProlog(L, BECount, Count, PrologExit, LatchExit, PreHeader,
                  NewPreHeader, VMap, DT, LI, PreserveLCSSA, *SE);
  }

  // If this loop is nested, then the loop unroller changes the code in the any
  // of its parent loops, so the Scalar Evolution pass needs to be run again.
  SE->forgetTopmostLoop(L);

  // Verify that the Dom Tree and Loop Info are correct.
#if defined(EXPENSIVE_CHECKS) && !defined(NDEBUG)
  if (DT) {
    assert(DT->verify(DominatorTree::VerificationLevel::Full));
    LI->verify(*DT);
  }
#endif

  // For unroll factor 2 remainder loop will have 1 iteration.
  if (Count == 2 && DT && LI && SE) {
    // TODO: This code could probably be pulled out into a helper function
    // (e.g. breakLoopBackedgeAndSimplify) and reused in loop-deletion.
    BasicBlock *RemainderLatch = remainderLoop->getLoopLatch();
    assert(RemainderLatch);
    SmallVector<BasicBlock *> RemainderBlocks(remainderLoop->getBlocks());
    breakLoopBackedge(remainderLoop, *DT, *SE, *LI, nullptr);
    remainderLoop = nullptr;

    // Simplify loop values after breaking the backedge
    const DataLayout &DL = L->getHeader()->getDataLayout();
    SmallVector<WeakTrackingVH, 16> DeadInsts;
    for (BasicBlock *BB : RemainderBlocks) {
      for (Instruction &Inst : llvm::make_early_inc_range(*BB)) {
        if (Value *V = simplifyInstruction(&Inst, {DL, nullptr, DT, AC}))
          if (LI->replacementPreservesLCSSAForm(&Inst, V))
            Inst.replaceAllUsesWith(V);
        if (isInstructionTriviallyDead(&Inst))
          DeadInsts.emplace_back(&Inst);
      }
      // We can't do recursive deletion until we're done iterating, as we might
      // have a phi which (potentially indirectly) uses instructions later in
      // the block we're iterating through.
      RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
    }

    // Merge latch into exit block.
    auto *ExitBB = RemainderLatch->getSingleSuccessor();
    assert(ExitBB && "required after breaking cond br backedge");
    DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
    MergeBlockIntoPredecessor(ExitBB, &DTU, LI);
  }

  // Canonicalize to LoopSimplifyForm both original and remainder loops. We
  // cannot rely on the LoopUnrollPass to do this because it only does
  // canonicalization for parent/subloops and not the sibling loops.
  if (OtherExits.size() > 0) {
    // Generate dedicated exit blocks for the original loop, to preserve
    // LoopSimplifyForm.
    formDedicatedExitBlocks(L, DT, LI, nullptr, PreserveLCSSA);
    // Generate dedicated exit blocks for the remainder loop if one exists, to
    // preserve LoopSimplifyForm.
    if (remainderLoop)
      formDedicatedExitBlocks(remainderLoop, DT, LI, nullptr, PreserveLCSSA);
  }

  auto UnrollResult = LoopUnrollResult::Unmodified;
  if (remainderLoop && UnrollRemainder) {
    LLVM_DEBUG(dbgs() << "Unrolling remainder loop\n");
    UnrollLoopOptions ULO;
    ULO.Count = Count - 1;
    ULO.Force = false;
    ULO.Runtime = false;
    ULO.AllowExpensiveTripCount = false;
    ULO.UnrollRemainder = false;
    ULO.ForgetAllSCEV = ForgetAllSCEV;
    assert(!getLoopConvergenceHeart(L) &&
           "A loop with a convergence heart does not allow runtime unrolling.");
    UnrollResult = UnrollLoop(remainderLoop, ULO, LI, SE, DT, AC, TTI,
                              /*ORE*/ nullptr, PreserveLCSSA);
  }

  if (ResultLoop && UnrollResult != LoopUnrollResult::FullyUnrolled)
    *ResultLoop = remainderLoop;
  NumRuntimeUnrolled++;
  return true;
}
