//===- LoopIdiomRecognize.cpp - Loop idiom recognition --------------------===//
//
// 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 pass implements an idiom recognizer that transforms simple loops into a
// non-loop form.  In cases that this kicks in, it can be a significant
// performance win.
//
// If compiling for code size we avoid idiom recognition if the resulting
// code could be larger than the code for the original loop. One way this could
// happen is if the loop is not removable after idiom recognition due to the
// presence of non-idiom instructions. The initial implementation of the
// heuristics applies to idioms in multi-block loops.
//
//===----------------------------------------------------------------------===//
//
// TODO List:
//
// Future loop memory idioms to recognize:
//   memcmp, strlen, etc.
// Future floating point idioms to recognize in -ffast-math mode:
//   fpowi
// Future integer operation idioms to recognize:
//   ctpop
//
// Beware that isel's default lowering for ctpop is highly inefficient for
// i64 and larger types when i64 is legal and the value has few bits set.  It
// would be good to enhance isel to emit a loop for ctpop in this case.
//
// This could recognize common matrix multiplies and dot product idioms and
// replace them with calls to BLAS (if linked in??).
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar/LoopIdiomRecognize.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CmpInstAnalysis.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/MemorySSAUpdater.h"
#include "llvm/Analysis/MustExecute.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/InstructionCost.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BuildLibCalls.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <utility>
#include <vector>

using namespace llvm;

#define DEBUG_TYPE "loop-idiom"

STATISTIC(NumMemSet, "Number of memset's formed from loop stores");
STATISTIC(NumMemCpy, "Number of memcpy's formed from loop load+stores");
STATISTIC(NumMemMove, "Number of memmove's formed from loop load+stores");
STATISTIC(
    NumShiftUntilBitTest,
    "Number of uncountable loops recognized as 'shift until bitttest' idiom");
STATISTIC(NumShiftUntilZero,
          "Number of uncountable loops recognized as 'shift until zero' idiom");

bool DisableLIRP::All;
static cl::opt<bool, true>
    DisableLIRPAll("disable-" DEBUG_TYPE "-all",
                   cl::desc("Options to disable Loop Idiom Recognize Pass."),
                   cl::location(DisableLIRP::All), cl::init(false),
                   cl::ReallyHidden);

bool DisableLIRP::Memset;
static cl::opt<bool, true>
    DisableLIRPMemset("disable-" DEBUG_TYPE "-memset",
                      cl::desc("Proceed with loop idiom recognize pass, but do "
                               "not convert loop(s) to memset."),
                      cl::location(DisableLIRP::Memset), cl::init(false),
                      cl::ReallyHidden);

bool DisableLIRP::Memcpy;
static cl::opt<bool, true>
    DisableLIRPMemcpy("disable-" DEBUG_TYPE "-memcpy",
                      cl::desc("Proceed with loop idiom recognize pass, but do "
                               "not convert loop(s) to memcpy."),
                      cl::location(DisableLIRP::Memcpy), cl::init(false),
                      cl::ReallyHidden);

static cl::opt<bool> UseLIRCodeSizeHeurs(
    "use-lir-code-size-heurs",
    cl::desc("Use loop idiom recognition code size heuristics when compiling"
             "with -Os/-Oz"),
    cl::init(true), cl::Hidden);

namespace {

class LoopIdiomRecognize {
  Loop *CurLoop = nullptr;
  AliasAnalysis *AA;
  DominatorTree *DT;
  LoopInfo *LI;
  ScalarEvolution *SE;
  TargetLibraryInfo *TLI;
  const TargetTransformInfo *TTI;
  const DataLayout *DL;
  OptimizationRemarkEmitter &ORE;
  bool ApplyCodeSizeHeuristics;
  std::unique_ptr<MemorySSAUpdater> MSSAU;

public:
  explicit LoopIdiomRecognize(AliasAnalysis *AA, DominatorTree *DT,
                              LoopInfo *LI, ScalarEvolution *SE,
                              TargetLibraryInfo *TLI,
                              const TargetTransformInfo *TTI, MemorySSA *MSSA,
                              const DataLayout *DL,
                              OptimizationRemarkEmitter &ORE)
      : AA(AA), DT(DT), LI(LI), SE(SE), TLI(TLI), TTI(TTI), DL(DL), ORE(ORE) {
    if (MSSA)
      MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
  }

  bool runOnLoop(Loop *L);

private:
  using StoreList = SmallVector<StoreInst *, 8>;
  using StoreListMap = MapVector<Value *, StoreList>;

  StoreListMap StoreRefsForMemset;
  StoreListMap StoreRefsForMemsetPattern;
  StoreList StoreRefsForMemcpy;
  bool HasMemset;
  bool HasMemsetPattern;
  bool HasMemcpy;

  /// Return code for isLegalStore()
  enum LegalStoreKind {
    None = 0,
    Memset,
    MemsetPattern,
    Memcpy,
    UnorderedAtomicMemcpy,
    DontUse // Dummy retval never to be used. Allows catching errors in retval
            // handling.
  };

  /// \name Countable Loop Idiom Handling
  /// @{

  bool runOnCountableLoop();
  bool runOnLoopBlock(BasicBlock *BB, const SCEV *BECount,
                      SmallVectorImpl<BasicBlock *> &ExitBlocks);

  void collectStores(BasicBlock *BB);
  LegalStoreKind isLegalStore(StoreInst *SI);
  enum class ForMemset { No, Yes };
  bool processLoopStores(SmallVectorImpl<StoreInst *> &SL, const SCEV *BECount,
                         ForMemset For);

  template <typename MemInst>
  bool processLoopMemIntrinsic(
      BasicBlock *BB,
      bool (LoopIdiomRecognize::*Processor)(MemInst *, const SCEV *),
      const SCEV *BECount);
  bool processLoopMemCpy(MemCpyInst *MCI, const SCEV *BECount);
  bool processLoopMemSet(MemSetInst *MSI, const SCEV *BECount);

  bool processLoopStridedStore(Value *DestPtr, const SCEV *StoreSizeSCEV,
                               MaybeAlign StoreAlignment, Value *StoredVal,
                               Instruction *TheStore,
                               SmallPtrSetImpl<Instruction *> &Stores,
                               const SCEVAddRecExpr *Ev, const SCEV *BECount,
                               bool IsNegStride, bool IsLoopMemset = false);
  bool processLoopStoreOfLoopLoad(StoreInst *SI, const SCEV *BECount);
  bool processLoopStoreOfLoopLoad(Value *DestPtr, Value *SourcePtr,
                                  const SCEV *StoreSize, MaybeAlign StoreAlign,
                                  MaybeAlign LoadAlign, Instruction *TheStore,
                                  Instruction *TheLoad,
                                  const SCEVAddRecExpr *StoreEv,
                                  const SCEVAddRecExpr *LoadEv,
                                  const SCEV *BECount);
  bool avoidLIRForMultiBlockLoop(bool IsMemset = false,
                                 bool IsLoopMemset = false);

  /// @}
  /// \name Noncountable Loop Idiom Handling
  /// @{

  bool runOnNoncountableLoop();

  bool recognizePopcount();
  void transformLoopToPopcount(BasicBlock *PreCondBB, Instruction *CntInst,
                               PHINode *CntPhi, Value *Var);
  bool recognizeAndInsertFFS();  /// Find First Set: ctlz or cttz
  void transformLoopToCountable(Intrinsic::ID IntrinID, BasicBlock *PreCondBB,
                                Instruction *CntInst, PHINode *CntPhi,
                                Value *Var, Instruction *DefX,
                                const DebugLoc &DL, bool ZeroCheck,
                                bool IsCntPhiUsedOutsideLoop);

  bool recognizeShiftUntilBitTest();
  bool recognizeShiftUntilZero();

  /// @}
};

class LoopIdiomRecognizeLegacyPass : public LoopPass {
public:
  static char ID;

  explicit LoopIdiomRecognizeLegacyPass() : LoopPass(ID) {
    initializeLoopIdiomRecognizeLegacyPassPass(
        *PassRegistry::getPassRegistry());
  }

  bool runOnLoop(Loop *L, LPPassManager &LPM) override {
    if (DisableLIRP::All)
      return false;

    if (skipLoop(L))
      return false;

    AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
    DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
    LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
    ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
    TargetLibraryInfo *TLI =
        &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
            *L->getHeader()->getParent());
    const TargetTransformInfo *TTI =
        &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
            *L->getHeader()->getParent());
    const DataLayout *DL = &L->getHeader()->getModule()->getDataLayout();
    auto *MSSAAnalysis = getAnalysisIfAvailable<MemorySSAWrapperPass>();
    MemorySSA *MSSA = nullptr;
    if (MSSAAnalysis)
      MSSA = &MSSAAnalysis->getMSSA();

    // For the old PM, we can't use OptimizationRemarkEmitter as an analysis
    // pass.  Function analyses need to be preserved across loop transformations
    // but ORE cannot be preserved (see comment before the pass definition).
    OptimizationRemarkEmitter ORE(L->getHeader()->getParent());

    LoopIdiomRecognize LIR(AA, DT, LI, SE, TLI, TTI, MSSA, DL, ORE);
    return LIR.runOnLoop(L);
  }

  /// This transformation requires natural loop information & requires that
  /// loop preheaders be inserted into the CFG.
  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<TargetLibraryInfoWrapperPass>();
    AU.addRequired<TargetTransformInfoWrapperPass>();
    AU.addPreserved<MemorySSAWrapperPass>();
    getLoopAnalysisUsage(AU);
  }
};

} // end anonymous namespace

char LoopIdiomRecognizeLegacyPass::ID = 0;

PreservedAnalyses LoopIdiomRecognizePass::run(Loop &L, LoopAnalysisManager &AM,
                                              LoopStandardAnalysisResults &AR,
                                              LPMUpdater &) {
  if (DisableLIRP::All)
    return PreservedAnalyses::all();

  const auto *DL = &L.getHeader()->getModule()->getDataLayout();

  // For the new PM, we also can't use OptimizationRemarkEmitter as an analysis
  // pass.  Function analyses need to be preserved across loop transformations
  // but ORE cannot be preserved (see comment before the pass definition).
  OptimizationRemarkEmitter ORE(L.getHeader()->getParent());

  LoopIdiomRecognize LIR(&AR.AA, &AR.DT, &AR.LI, &AR.SE, &AR.TLI, &AR.TTI,
                         AR.MSSA, DL, ORE);
  if (!LIR.runOnLoop(&L))
    return PreservedAnalyses::all();

  auto PA = getLoopPassPreservedAnalyses();
  if (AR.MSSA)
    PA.preserve<MemorySSAAnalysis>();
  return PA;
}

INITIALIZE_PASS_BEGIN(LoopIdiomRecognizeLegacyPass, "loop-idiom",
                      "Recognize loop idioms", false, false)
INITIALIZE_PASS_DEPENDENCY(LoopPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_END(LoopIdiomRecognizeLegacyPass, "loop-idiom",
                    "Recognize loop idioms", false, false)

Pass *llvm::createLoopIdiomPass() { return new LoopIdiomRecognizeLegacyPass(); }

static void deleteDeadInstruction(Instruction *I) {
  I->replaceAllUsesWith(UndefValue::get(I->getType()));
  I->eraseFromParent();
}

//===----------------------------------------------------------------------===//
//
//          Implementation of LoopIdiomRecognize
//
//===----------------------------------------------------------------------===//

bool LoopIdiomRecognize::runOnLoop(Loop *L) {
  CurLoop = L;
  // If the loop could not be converted to canonical form, it must have an
  // indirectbr in it, just give up.
  if (!L->getLoopPreheader())
    return false;

  // Disable loop idiom recognition if the function's name is a common idiom.
  StringRef Name = L->getHeader()->getParent()->getName();
  if (Name == "memset" || Name == "memcpy")
    return false;

  // Determine if code size heuristics need to be applied.
  ApplyCodeSizeHeuristics =
      L->getHeader()->getParent()->hasOptSize() && UseLIRCodeSizeHeurs;

  HasMemset = TLI->has(LibFunc_memset);
  HasMemsetPattern = TLI->has(LibFunc_memset_pattern16);
  HasMemcpy = TLI->has(LibFunc_memcpy);

  if (HasMemset || HasMemsetPattern || HasMemcpy)
    if (SE->hasLoopInvariantBackedgeTakenCount(L))
      return runOnCountableLoop();

  return runOnNoncountableLoop();
}

bool LoopIdiomRecognize::runOnCountableLoop() {
  const SCEV *BECount = SE->getBackedgeTakenCount(CurLoop);
  assert(!isa<SCEVCouldNotCompute>(BECount) &&
         "runOnCountableLoop() called on a loop without a predictable"
         "backedge-taken count");

  // If this loop executes exactly one time, then it should be peeled, not
  // optimized by this pass.
  if (const SCEVConstant *BECst = dyn_cast<SCEVConstant>(BECount))
    if (BECst->getAPInt() == 0)
      return false;

  SmallVector<BasicBlock *, 8> ExitBlocks;
  CurLoop->getUniqueExitBlocks(ExitBlocks);

  LLVM_DEBUG(dbgs() << DEBUG_TYPE " Scanning: F["
                    << CurLoop->getHeader()->getParent()->getName()
                    << "] Countable Loop %" << CurLoop->getHeader()->getName()
                    << "\n");

  // The following transforms hoist stores/memsets into the loop pre-header.
  // Give up if the loop has instructions that may throw.
  SimpleLoopSafetyInfo SafetyInfo;
  SafetyInfo.computeLoopSafetyInfo(CurLoop);
  if (SafetyInfo.anyBlockMayThrow())
    return false;

  bool MadeChange = false;

  // Scan all the blocks in the loop that are not in subloops.
  for (auto *BB : CurLoop->getBlocks()) {
    // Ignore blocks in subloops.
    if (LI->getLoopFor(BB) != CurLoop)
      continue;

    MadeChange |= runOnLoopBlock(BB, BECount, ExitBlocks);
  }
  return MadeChange;
}

static APInt getStoreStride(const SCEVAddRecExpr *StoreEv) {
  const SCEVConstant *ConstStride = cast<SCEVConstant>(StoreEv->getOperand(1));
  return ConstStride->getAPInt();
}

/// getMemSetPatternValue - If a strided store of the specified value is safe to
/// turn into a memset_pattern16, return a ConstantArray of 16 bytes that should
/// be passed in.  Otherwise, return null.
///
/// Note that we don't ever attempt to use memset_pattern8 or 4, because these
/// just replicate their input array and then pass on to memset_pattern16.
static Constant *getMemSetPatternValue(Value *V, const DataLayout *DL) {
  // FIXME: This could check for UndefValue because it can be merged into any
  // other valid pattern.

  // If the value isn't a constant, we can't promote it to being in a constant
  // array.  We could theoretically do a store to an alloca or something, but
  // that doesn't seem worthwhile.
  Constant *C = dyn_cast<Constant>(V);
  if (!C)
    return nullptr;

  // Only handle simple values that are a power of two bytes in size.
  uint64_t Size = DL->getTypeSizeInBits(V->getType());
  if (Size == 0 || (Size & 7) || (Size & (Size - 1)))
    return nullptr;

  // Don't care enough about darwin/ppc to implement this.
  if (DL->isBigEndian())
    return nullptr;

  // Convert to size in bytes.
  Size /= 8;

  // TODO: If CI is larger than 16-bytes, we can try slicing it in half to see
  // if the top and bottom are the same (e.g. for vectors and large integers).
  if (Size > 16)
    return nullptr;

  // If the constant is exactly 16 bytes, just use it.
  if (Size == 16)
    return C;

  // Otherwise, we'll use an array of the constants.
  unsigned ArraySize = 16 / Size;
  ArrayType *AT = ArrayType::get(V->getType(), ArraySize);
  return ConstantArray::get(AT, std::vector<Constant *>(ArraySize, C));
}

LoopIdiomRecognize::LegalStoreKind
LoopIdiomRecognize::isLegalStore(StoreInst *SI) {
  // Don't touch volatile stores.
  if (SI->isVolatile())
    return LegalStoreKind::None;
  // We only want simple or unordered-atomic stores.
  if (!SI->isUnordered())
    return LegalStoreKind::None;

  // Avoid merging nontemporal stores.
  if (SI->getMetadata(LLVMContext::MD_nontemporal))
    return LegalStoreKind::None;

  Value *StoredVal = SI->getValueOperand();
  Value *StorePtr = SI->getPointerOperand();

  // Don't convert stores of non-integral pointer types to memsets (which stores
  // integers).
  if (DL->isNonIntegralPointerType(StoredVal->getType()->getScalarType()))
    return LegalStoreKind::None;

  // Reject stores that are so large that they overflow an unsigned.
  // When storing out scalable vectors we bail out for now, since the code
  // below currently only works for constant strides.
  TypeSize SizeInBits = DL->getTypeSizeInBits(StoredVal->getType());
  if (SizeInBits.isScalable() || (SizeInBits.getFixedSize() & 7) ||
      (SizeInBits.getFixedSize() >> 32) != 0)
    return LegalStoreKind::None;

  // See if the pointer expression is an AddRec like {base,+,1} on the current
  // loop, which indicates a strided store.  If we have something else, it's a
  // random store we can't handle.
  const SCEVAddRecExpr *StoreEv =
      dyn_cast<SCEVAddRecExpr>(SE->getSCEV(StorePtr));
  if (!StoreEv || StoreEv->getLoop() != CurLoop || !StoreEv->isAffine())
    return LegalStoreKind::None;

  // Check to see if we have a constant stride.
  if (!isa<SCEVConstant>(StoreEv->getOperand(1)))
    return LegalStoreKind::None;

  // See if the store can be turned into a memset.

  // If the stored value is a byte-wise value (like i32 -1), then it may be
  // turned into a memset of i8 -1, assuming that all the consecutive bytes
  // are stored.  A store of i32 0x01020304 can never be turned into a memset,
  // but it can be turned into memset_pattern if the target supports it.
  Value *SplatValue = isBytewiseValue(StoredVal, *DL);

  // Note: memset and memset_pattern on unordered-atomic is yet not supported
  bool UnorderedAtomic = SI->isUnordered() && !SI->isSimple();

  // If we're allowed to form a memset, and the stored value would be
  // acceptable for memset, use it.
  if (!UnorderedAtomic && HasMemset && SplatValue && !DisableLIRP::Memset &&
      // Verify that the stored value is loop invariant.  If not, we can't
      // promote the memset.
      CurLoop->isLoopInvariant(SplatValue)) {
    // It looks like we can use SplatValue.
    return LegalStoreKind::Memset;
  }
  if (!UnorderedAtomic && HasMemsetPattern && !DisableLIRP::Memset &&
      // Don't create memset_pattern16s with address spaces.
      StorePtr->getType()->getPointerAddressSpace() == 0 &&
      getMemSetPatternValue(StoredVal, DL)) {
    // It looks like we can use PatternValue!
    return LegalStoreKind::MemsetPattern;
  }

  // Otherwise, see if the store can be turned into a memcpy.
  if (HasMemcpy && !DisableLIRP::Memcpy) {
    // Check to see if the stride matches the size of the store.  If so, then we
    // know that every byte is touched in the loop.
    APInt Stride = getStoreStride(StoreEv);
    unsigned StoreSize = DL->getTypeStoreSize(SI->getValueOperand()->getType());
    if (StoreSize != Stride && StoreSize != -Stride)
      return LegalStoreKind::None;

    // The store must be feeding a non-volatile load.
    LoadInst *LI = dyn_cast<LoadInst>(SI->getValueOperand());

    // Only allow non-volatile loads
    if (!LI || LI->isVolatile())
      return LegalStoreKind::None;
    // Only allow simple or unordered-atomic loads
    if (!LI->isUnordered())
      return LegalStoreKind::None;

    // See if the pointer expression is an AddRec like {base,+,1} on the current
    // loop, which indicates a strided load.  If we have something else, it's a
    // random load we can't handle.
    const SCEVAddRecExpr *LoadEv =
        dyn_cast<SCEVAddRecExpr>(SE->getSCEV(LI->getPointerOperand()));
    if (!LoadEv || LoadEv->getLoop() != CurLoop || !LoadEv->isAffine())
      return LegalStoreKind::None;

    // The store and load must share the same stride.
    if (StoreEv->getOperand(1) != LoadEv->getOperand(1))
      return LegalStoreKind::None;

    // Success.  This store can be converted into a memcpy.
    UnorderedAtomic = UnorderedAtomic || LI->isAtomic();
    return UnorderedAtomic ? LegalStoreKind::UnorderedAtomicMemcpy
                           : LegalStoreKind::Memcpy;
  }
  // This store can't be transformed into a memset/memcpy.
  return LegalStoreKind::None;
}

void LoopIdiomRecognize::collectStores(BasicBlock *BB) {
  StoreRefsForMemset.clear();
  StoreRefsForMemsetPattern.clear();
  StoreRefsForMemcpy.clear();
  for (Instruction &I : *BB) {
    StoreInst *SI = dyn_cast<StoreInst>(&I);
    if (!SI)
      continue;

    // Make sure this is a strided store with a constant stride.
    switch (isLegalStore(SI)) {
    case LegalStoreKind::None:
      // Nothing to do
      break;
    case LegalStoreKind::Memset: {
      // Find the base pointer.
      Value *Ptr = getUnderlyingObject(SI->getPointerOperand());
      StoreRefsForMemset[Ptr].push_back(SI);
    } break;
    case LegalStoreKind::MemsetPattern: {
      // Find the base pointer.
      Value *Ptr = getUnderlyingObject(SI->getPointerOperand());
      StoreRefsForMemsetPattern[Ptr].push_back(SI);
    } break;
    case LegalStoreKind::Memcpy:
    case LegalStoreKind::UnorderedAtomicMemcpy:
      StoreRefsForMemcpy.push_back(SI);
      break;
    default:
      assert(false && "unhandled return value");
      break;
    }
  }
}

/// runOnLoopBlock - Process the specified block, which lives in a counted loop
/// with the specified backedge count.  This block is known to be in the current
/// loop and not in any subloops.
bool LoopIdiomRecognize::runOnLoopBlock(
    BasicBlock *BB, const SCEV *BECount,
    SmallVectorImpl<BasicBlock *> &ExitBlocks) {
  // We can only promote stores in this block if they are unconditionally
  // executed in the loop.  For a block to be unconditionally executed, it has
  // to dominate all the exit blocks of the loop.  Verify this now.
  for (BasicBlock *ExitBlock : ExitBlocks)
    if (!DT->dominates(BB, ExitBlock))
      return false;

  bool MadeChange = false;
  // Look for store instructions, which may be optimized to memset/memcpy.
  collectStores(BB);

  // Look for a single store or sets of stores with a common base, which can be
  // optimized into a memset (memset_pattern).  The latter most commonly happens
  // with structs and handunrolled loops.
  for (auto &SL : StoreRefsForMemset)
    MadeChange |= processLoopStores(SL.second, BECount, ForMemset::Yes);

  for (auto &SL : StoreRefsForMemsetPattern)
    MadeChange |= processLoopStores(SL.second, BECount, ForMemset::No);

  // Optimize the store into a memcpy, if it feeds an similarly strided load.
  for (auto &SI : StoreRefsForMemcpy)
    MadeChange |= processLoopStoreOfLoopLoad(SI, BECount);

  MadeChange |= processLoopMemIntrinsic<MemCpyInst>(
      BB, &LoopIdiomRecognize::processLoopMemCpy, BECount);
  MadeChange |= processLoopMemIntrinsic<MemSetInst>(
      BB, &LoopIdiomRecognize::processLoopMemSet, BECount);

  return MadeChange;
}

/// See if this store(s) can be promoted to a memset.
bool LoopIdiomRecognize::processLoopStores(SmallVectorImpl<StoreInst *> &SL,
                                           const SCEV *BECount, ForMemset For) {
  // Try to find consecutive stores that can be transformed into memsets.
  SetVector<StoreInst *> Heads, Tails;
  SmallDenseMap<StoreInst *, StoreInst *> ConsecutiveChain;

  // Do a quadratic search on all of the given stores and find
  // all of the pairs of stores that follow each other.
  SmallVector<unsigned, 16> IndexQueue;
  for (unsigned i = 0, e = SL.size(); i < e; ++i) {
    assert(SL[i]->isSimple() && "Expected only non-volatile stores.");

    Value *FirstStoredVal = SL[i]->getValueOperand();
    Value *FirstStorePtr = SL[i]->getPointerOperand();
    const SCEVAddRecExpr *FirstStoreEv =
        cast<SCEVAddRecExpr>(SE->getSCEV(FirstStorePtr));
    APInt FirstStride = getStoreStride(FirstStoreEv);
    unsigned FirstStoreSize = DL->getTypeStoreSize(SL[i]->getValueOperand()->getType());

    // See if we can optimize just this store in isolation.
    if (FirstStride == FirstStoreSize || -FirstStride == FirstStoreSize) {
      Heads.insert(SL[i]);
      continue;
    }

    Value *FirstSplatValue = nullptr;
    Constant *FirstPatternValue = nullptr;

    if (For == ForMemset::Yes)
      FirstSplatValue = isBytewiseValue(FirstStoredVal, *DL);
    else
      FirstPatternValue = getMemSetPatternValue(FirstStoredVal, DL);

    assert((FirstSplatValue || FirstPatternValue) &&
           "Expected either splat value or pattern value.");

    IndexQueue.clear();
    // If a store has multiple consecutive store candidates, search Stores
    // array according to the sequence: from i+1 to e, then from i-1 to 0.
    // This is because usually pairing with immediate succeeding or preceding
    // candidate create the best chance to find memset opportunity.
    unsigned j = 0;
    for (j = i + 1; j < e; ++j)
      IndexQueue.push_back(j);
    for (j = i; j > 0; --j)
      IndexQueue.push_back(j - 1);

    for (auto &k : IndexQueue) {
      assert(SL[k]->isSimple() && "Expected only non-volatile stores.");
      Value *SecondStorePtr = SL[k]->getPointerOperand();
      const SCEVAddRecExpr *SecondStoreEv =
          cast<SCEVAddRecExpr>(SE->getSCEV(SecondStorePtr));
      APInt SecondStride = getStoreStride(SecondStoreEv);

      if (FirstStride != SecondStride)
        continue;

      Value *SecondStoredVal = SL[k]->getValueOperand();
      Value *SecondSplatValue = nullptr;
      Constant *SecondPatternValue = nullptr;

      if (For == ForMemset::Yes)
        SecondSplatValue = isBytewiseValue(SecondStoredVal, *DL);
      else
        SecondPatternValue = getMemSetPatternValue(SecondStoredVal, DL);

      assert((SecondSplatValue || SecondPatternValue) &&
             "Expected either splat value or pattern value.");

      if (isConsecutiveAccess(SL[i], SL[k], *DL, *SE, false)) {
        if (For == ForMemset::Yes) {
          if (isa<UndefValue>(FirstSplatValue))
            FirstSplatValue = SecondSplatValue;
          if (FirstSplatValue != SecondSplatValue)
            continue;
        } else {
          if (isa<UndefValue>(FirstPatternValue))
            FirstPatternValue = SecondPatternValue;
          if (FirstPatternValue != SecondPatternValue)
            continue;
        }
        Tails.insert(SL[k]);
        Heads.insert(SL[i]);
        ConsecutiveChain[SL[i]] = SL[k];
        break;
      }
    }
  }

  // We may run into multiple chains that merge into a single chain. We mark the
  // stores that we transformed so that we don't visit the same store twice.
  SmallPtrSet<Value *, 16> TransformedStores;
  bool Changed = false;

  // For stores that start but don't end a link in the chain:
  for (StoreInst *I : Heads) {
    if (Tails.count(I))
      continue;

    // We found a store instr that starts a chain. Now follow the chain and try
    // to transform it.
    SmallPtrSet<Instruction *, 8> AdjacentStores;
    StoreInst *HeadStore = I;
    unsigned StoreSize = 0;

    // Collect the chain into a list.
    while (Tails.count(I) || Heads.count(I)) {
      if (TransformedStores.count(I))
        break;
      AdjacentStores.insert(I);

      StoreSize += DL->getTypeStoreSize(I->getValueOperand()->getType());
      // Move to the next value in the chain.
      I = ConsecutiveChain[I];
    }

    Value *StoredVal = HeadStore->getValueOperand();
    Value *StorePtr = HeadStore->getPointerOperand();
    const SCEVAddRecExpr *StoreEv = cast<SCEVAddRecExpr>(SE->getSCEV(StorePtr));
    APInt Stride = getStoreStride(StoreEv);

    // Check to see if the stride matches the size of the stores.  If so, then
    // we know that every byte is touched in the loop.
    if (StoreSize != Stride && StoreSize != -Stride)
      continue;

    bool IsNegStride = StoreSize == -Stride;

    Type *IntIdxTy = DL->getIndexType(StorePtr->getType());
    const SCEV *StoreSizeSCEV = SE->getConstant(IntIdxTy, StoreSize);
    if (processLoopStridedStore(StorePtr, StoreSizeSCEV,
                                MaybeAlign(HeadStore->getAlignment()),
                                StoredVal, HeadStore, AdjacentStores, StoreEv,
                                BECount, IsNegStride)) {
      TransformedStores.insert(AdjacentStores.begin(), AdjacentStores.end());
      Changed = true;
    }
  }

  return Changed;
}

/// processLoopMemIntrinsic - Template function for calling different processor
/// functions based on mem instrinsic type.
template <typename MemInst>
bool LoopIdiomRecognize::processLoopMemIntrinsic(
    BasicBlock *BB,
    bool (LoopIdiomRecognize::*Processor)(MemInst *, const SCEV *),
    const SCEV *BECount) {
  bool MadeChange = false;
  for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;) {
    Instruction *Inst = &*I++;
    // Look for memory instructions, which may be optimized to a larger one.
    if (MemInst *MI = dyn_cast<MemInst>(Inst)) {
      WeakTrackingVH InstPtr(&*I);
      if (!(this->*Processor)(MI, BECount))
        continue;
      MadeChange = true;

      // If processing the instruction invalidated our iterator, start over from
      // the top of the block.
      if (!InstPtr)
        I = BB->begin();
    }
  }
  return MadeChange;
}

/// processLoopMemCpy - See if this memcpy can be promoted to a large memcpy
bool LoopIdiomRecognize::processLoopMemCpy(MemCpyInst *MCI,
                                           const SCEV *BECount) {
  // We can only handle non-volatile memcpys with a constant size.
  if (MCI->isVolatile() || !isa<ConstantInt>(MCI->getLength()))
    return false;

  // If we're not allowed to hack on memcpy, we fail.
  if ((!HasMemcpy && !isa<MemCpyInlineInst>(MCI)) || DisableLIRP::Memcpy)
    return false;

  Value *Dest = MCI->getDest();
  Value *Source = MCI->getSource();
  if (!Dest || !Source)
    return false;

  // See if the load and store pointer expressions are AddRec like {base,+,1} on
  // the current loop, which indicates a strided load and store.  If we have
  // something else, it's a random load or store we can't handle.
  const SCEVAddRecExpr *StoreEv = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(Dest));
  if (!StoreEv || StoreEv->getLoop() != CurLoop || !StoreEv->isAffine())
    return false;
  const SCEVAddRecExpr *LoadEv = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(Source));
  if (!LoadEv || LoadEv->getLoop() != CurLoop || !LoadEv->isAffine())
    return false;

  // Reject memcpys that are so large that they overflow an unsigned.
  uint64_t SizeInBytes = cast<ConstantInt>(MCI->getLength())->getZExtValue();
  if ((SizeInBytes >> 32) != 0)
    return false;

  // Check if the stride matches the size of the memcpy. If so, then we know
  // that every byte is touched in the loop.
  const SCEVConstant *ConstStoreStride =
      dyn_cast<SCEVConstant>(StoreEv->getOperand(1));
  const SCEVConstant *ConstLoadStride =
      dyn_cast<SCEVConstant>(LoadEv->getOperand(1));
  if (!ConstStoreStride || !ConstLoadStride)
    return false;

  APInt StoreStrideValue = ConstStoreStride->getAPInt();
  APInt LoadStrideValue = ConstLoadStride->getAPInt();
  // Huge stride value - give up
  if (StoreStrideValue.getBitWidth() > 64 || LoadStrideValue.getBitWidth() > 64)
    return false;

  if (SizeInBytes != StoreStrideValue && SizeInBytes != -StoreStrideValue) {
    ORE.emit([&]() {
      return OptimizationRemarkMissed(DEBUG_TYPE, "SizeStrideUnequal", MCI)
             << ore::NV("Inst", "memcpy") << " in "
             << ore::NV("Function", MCI->getFunction())
             << " function will not be hoisted: "
             << ore::NV("Reason", "memcpy size is not equal to stride");
    });
    return false;
  }

  int64_t StoreStrideInt = StoreStrideValue.getSExtValue();
  int64_t LoadStrideInt = LoadStrideValue.getSExtValue();
  // Check if the load stride matches the store stride.
  if (StoreStrideInt != LoadStrideInt)
    return false;

  return processLoopStoreOfLoopLoad(
      Dest, Source, SE->getConstant(Dest->getType(), SizeInBytes),
      MCI->getDestAlign(), MCI->getSourceAlign(), MCI, MCI, StoreEv, LoadEv,
      BECount);
}

/// processLoopMemSet - See if this memset can be promoted to a large memset.
bool LoopIdiomRecognize::processLoopMemSet(MemSetInst *MSI,
                                           const SCEV *BECount) {
  // We can only handle non-volatile memsets.
  if (MSI->isVolatile())
    return false;

  // If we're not allowed to hack on memset, we fail.
  if (!HasMemset || DisableLIRP::Memset)
    return false;

  Value *Pointer = MSI->getDest();

  // See if the pointer expression is an AddRec like {base,+,1} on the current
  // loop, which indicates a strided store.  If we have something else, it's a
  // random store we can't handle.
  const SCEVAddRecExpr *Ev = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(Pointer));
  if (!Ev || Ev->getLoop() != CurLoop)
    return false;
  if (!Ev->isAffine()) {
    LLVM_DEBUG(dbgs() << "  Pointer is not affine, abort\n");
    return false;
  }

  const SCEV *PointerStrideSCEV = Ev->getOperand(1);
  const SCEV *MemsetSizeSCEV = SE->getSCEV(MSI->getLength());
  if (!PointerStrideSCEV || !MemsetSizeSCEV)
    return false;

  bool IsNegStride = false;
  const bool IsConstantSize = isa<ConstantInt>(MSI->getLength());

  if (IsConstantSize) {
    // Memset size is constant.
    // Check if the pointer stride matches the memset size. If so, then
    // we know that every byte is touched in the loop.
    LLVM_DEBUG(dbgs() << "  memset size is constant\n");
    uint64_t SizeInBytes = cast<ConstantInt>(MSI->getLength())->getZExtValue();
    const SCEVConstant *ConstStride = dyn_cast<SCEVConstant>(Ev->getOperand(1));
    if (!ConstStride)
      return false;

    APInt Stride = ConstStride->getAPInt();
    if (SizeInBytes != Stride && SizeInBytes != -Stride)
      return false;

    IsNegStride = SizeInBytes == -Stride;
  } else {
    // Memset size is non-constant.
    // Check if the pointer stride matches the memset size.
    // To be conservative, the pass would not promote pointers that aren't in
    // address space zero. Also, the pass only handles memset length and stride
    // that are invariant for the top level loop.
    LLVM_DEBUG(dbgs() << "  memset size is non-constant\n");
    if (Pointer->getType()->getPointerAddressSpace() != 0) {
      LLVM_DEBUG(dbgs() << "  pointer is not in address space zero, "
                        << "abort\n");
      return false;
    }
    if (!SE->isLoopInvariant(MemsetSizeSCEV, CurLoop)) {
      LLVM_DEBUG(dbgs() << "  memset size is not a loop-invariant, "
                        << "abort\n");
      return false;
    }

    // Compare positive direction PointerStrideSCEV with MemsetSizeSCEV
    IsNegStride = PointerStrideSCEV->isNonConstantNegative();
    const SCEV *PositiveStrideSCEV =
        IsNegStride ? SE->getNegativeSCEV(PointerStrideSCEV)
                    : PointerStrideSCEV;
    LLVM_DEBUG(dbgs() << "  MemsetSizeSCEV: " << *MemsetSizeSCEV << "\n"
                      << "  PositiveStrideSCEV: " << *PositiveStrideSCEV
                      << "\n");

    if (PositiveStrideSCEV != MemsetSizeSCEV) {
      // TODO: folding can be done to the SCEVs
      // The folding is to fold expressions that is covered by the loop guard
      // at loop entry. After the folding, compare again and proceed
      // optimization if equal.
      LLVM_DEBUG(dbgs() << "  SCEV don't match, abort\n");
      return false;
    }
  }

  // Verify that the memset value is loop invariant.  If not, we can't promote
  // the memset.
  Value *SplatValue = MSI->getValue();
  if (!SplatValue || !CurLoop->isLoopInvariant(SplatValue))
    return false;

  SmallPtrSet<Instruction *, 1> MSIs;
  MSIs.insert(MSI);
  return processLoopStridedStore(Pointer, SE->getSCEV(MSI->getLength()),
                                 MaybeAlign(MSI->getDestAlignment()),
                                 SplatValue, MSI, MSIs, Ev, BECount,
                                 IsNegStride, /*IsLoopMemset=*/true);
}

/// mayLoopAccessLocation - Return true if the specified loop might access the
/// specified pointer location, which is a loop-strided access.  The 'Access'
/// argument specifies what the verboten forms of access are (read or write).
static bool
mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L,
                      const SCEV *BECount, const SCEV *StoreSizeSCEV,
                      AliasAnalysis &AA,
                      SmallPtrSetImpl<Instruction *> &IgnoredInsts) {
  // Get the location that may be stored across the loop.  Since the access is
  // strided positively through memory, we say that the modified location starts
  // at the pointer and has infinite size.
  LocationSize AccessSize = LocationSize::afterPointer();

  // If the loop iterates a fixed number of times, we can refine the access size
  // to be exactly the size of the memset, which is (BECount+1)*StoreSize
  const SCEVConstant *BECst = dyn_cast<SCEVConstant>(BECount);
  const SCEVConstant *ConstSize = dyn_cast<SCEVConstant>(StoreSizeSCEV);
  if (BECst && ConstSize)
    AccessSize = LocationSize::precise((BECst->getValue()->getZExtValue() + 1) *
                                       ConstSize->getValue()->getZExtValue());

  // TODO: For this to be really effective, we have to dive into the pointer
  // operand in the store.  Store to &A[i] of 100 will always return may alias
  // with store of &A[100], we need to StoreLoc to be "A" with size of 100,
  // which will then no-alias a store to &A[100].
  MemoryLocation StoreLoc(Ptr, AccessSize);

  for (BasicBlock *B : L->blocks())
    for (Instruction &I : *B)
      if (!IgnoredInsts.contains(&I) &&
          isModOrRefSet(
              intersectModRef(AA.getModRefInfo(&I, StoreLoc), Access)))
        return true;
  return false;
}

// If we have a negative stride, Start refers to the end of the memory location
// we're trying to memset.  Therefore, we need to recompute the base pointer,
// which is just Start - BECount*Size.
static const SCEV *getStartForNegStride(const SCEV *Start, const SCEV *BECount,
                                        Type *IntPtr, const SCEV *StoreSizeSCEV,
                                        ScalarEvolution *SE) {
  const SCEV *Index = SE->getTruncateOrZeroExtend(BECount, IntPtr);
  if (!StoreSizeSCEV->isOne()) {
    // index = back edge count * store size
    Index = SE->getMulExpr(Index,
                           SE->getTruncateOrZeroExtend(StoreSizeSCEV, IntPtr),
                           SCEV::FlagNUW);
  }
  // base pointer = start - index * store size
  return SE->getMinusSCEV(Start, Index);
}

/// Compute trip count from the backedge taken count.
static const SCEV *getTripCount(const SCEV *BECount, Type *IntPtr,
                                Loop *CurLoop, const DataLayout *DL,
                                ScalarEvolution *SE) {
  const SCEV *TripCountS = nullptr;
  // The # stored bytes is (BECount+1).  Expand the trip count out to
  // pointer size if it isn't already.
  //
  // If we're going to need to zero extend the BE count, check if we can add
  // one to it prior to zero extending without overflow. Provided this is safe,
  // it allows better simplification of the +1.
  if (DL->getTypeSizeInBits(BECount->getType()) <
          DL->getTypeSizeInBits(IntPtr) &&
      SE->isLoopEntryGuardedByCond(
          CurLoop, ICmpInst::ICMP_NE, BECount,
          SE->getNegativeSCEV(SE->getOne(BECount->getType())))) {
    TripCountS = SE->getZeroExtendExpr(
        SE->getAddExpr(BECount, SE->getOne(BECount->getType()), SCEV::FlagNUW),
        IntPtr);
  } else {
    TripCountS = SE->getAddExpr(SE->getTruncateOrZeroExtend(BECount, IntPtr),
                                SE->getOne(IntPtr), SCEV::FlagNUW);
  }

  return TripCountS;
}

/// Compute the number of bytes as a SCEV from the backedge taken count.
///
/// This also maps the SCEV into the provided type and tries to handle the
/// computation in a way that will fold cleanly.
static const SCEV *getNumBytes(const SCEV *BECount, Type *IntPtr,
                               const SCEV *StoreSizeSCEV, Loop *CurLoop,
                               const DataLayout *DL, ScalarEvolution *SE) {
  const SCEV *TripCountSCEV = getTripCount(BECount, IntPtr, CurLoop, DL, SE);

  return SE->getMulExpr(TripCountSCEV,
                        SE->getTruncateOrZeroExtend(StoreSizeSCEV, IntPtr),
                        SCEV::FlagNUW);
}

/// processLoopStridedStore - We see a strided store of some value.  If we can
/// transform this into a memset or memset_pattern in the loop preheader, do so.
bool LoopIdiomRecognize::processLoopStridedStore(
    Value *DestPtr, const SCEV *StoreSizeSCEV, MaybeAlign StoreAlignment,
    Value *StoredVal, Instruction *TheStore,
    SmallPtrSetImpl<Instruction *> &Stores, const SCEVAddRecExpr *Ev,
    const SCEV *BECount, bool IsNegStride, bool IsLoopMemset) {
  Value *SplatValue = isBytewiseValue(StoredVal, *DL);
  Constant *PatternValue = nullptr;

  if (!SplatValue)
    PatternValue = getMemSetPatternValue(StoredVal, DL);

  assert((SplatValue || PatternValue) &&
         "Expected either splat value or pattern value.");

  // The trip count of the loop and the base pointer of the addrec SCEV is
  // guaranteed to be loop invariant, which means that it should dominate the
  // header.  This allows us to insert code for it in the preheader.
  unsigned DestAS = DestPtr->getType()->getPointerAddressSpace();
  BasicBlock *Preheader = CurLoop->getLoopPreheader();
  IRBuilder<> Builder(Preheader->getTerminator());
  SCEVExpander Expander(*SE, *DL, "loop-idiom");
  SCEVExpanderCleaner ExpCleaner(Expander, *DT);

  Type *DestInt8PtrTy = Builder.getInt8PtrTy(DestAS);
  Type *IntIdxTy = DL->getIndexType(DestPtr->getType());

  bool Changed = false;
  const SCEV *Start = Ev->getStart();
  // Handle negative strided loops.
  if (IsNegStride)
    Start = getStartForNegStride(Start, BECount, IntIdxTy, StoreSizeSCEV, SE);

  // TODO: ideally we should still be able to generate memset if SCEV expander
  // is taught to generate the dependencies at the latest point.
  if (!isSafeToExpand(Start, *SE))
    return Changed;

  // Okay, we have a strided store "p[i]" of a splattable value.  We can turn
  // this into a memset in the loop preheader now if we want.  However, this
  // would be unsafe to do if there is anything else in the loop that may read
  // or write to the aliased location.  Check for any overlap by generating the
  // base pointer and checking the region.
  Value *BasePtr =
      Expander.expandCodeFor(Start, DestInt8PtrTy, Preheader->getTerminator());

  // From here on out, conservatively report to the pass manager that we've
  // changed the IR, even if we later clean up these added instructions. There
  // may be structural differences e.g. in the order of use lists not accounted
  // for in just a textual dump of the IR. This is written as a variable, even
  // though statically all the places this dominates could be replaced with
  // 'true', with the hope that anyone trying to be clever / "more precise" with
  // the return value will read this comment, and leave them alone.
  Changed = true;

  if (mayLoopAccessLocation(BasePtr, ModRefInfo::ModRef, CurLoop, BECount,
                            StoreSizeSCEV, *AA, Stores))
    return Changed;

  if (avoidLIRForMultiBlockLoop(/*IsMemset=*/true, IsLoopMemset))
    return Changed;

  // Okay, everything looks good, insert the memset.

  const SCEV *NumBytesS =
      getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop, DL, SE);

  // TODO: ideally we should still be able to generate memset if SCEV expander
  // is taught to generate the dependencies at the latest point.
  if (!isSafeToExpand(NumBytesS, *SE))
    return Changed;

  Value *NumBytes =
      Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->getTerminator());

  CallInst *NewCall;
  if (SplatValue) {
    NewCall = Builder.CreateMemSet(BasePtr, SplatValue, NumBytes,
                                   MaybeAlign(StoreAlignment));
  } else {
    // Everything is emitted in default address space
    Type *Int8PtrTy = DestInt8PtrTy;

    Module *M = TheStore->getModule();
    StringRef FuncName = "memset_pattern16";
    FunctionCallee MSP = M->getOrInsertFunction(FuncName, Builder.getVoidTy(),
                                                Int8PtrTy, Int8PtrTy, IntIdxTy);
    inferLibFuncAttributes(M, FuncName, *TLI);

    // Otherwise we should form a memset_pattern16.  PatternValue is known to be
    // an constant array of 16-bytes.  Plop the value into a mergable global.
    GlobalVariable *GV = new GlobalVariable(*M, PatternValue->getType(), true,
                                            GlobalValue::PrivateLinkage,
                                            PatternValue, ".memset_pattern");
    GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); // Ok to merge these.
    GV->setAlignment(Align(16));
    Value *PatternPtr = ConstantExpr::getBitCast(GV, Int8PtrTy);
    NewCall = Builder.CreateCall(MSP, {BasePtr, PatternPtr, NumBytes});
  }
  NewCall->setDebugLoc(TheStore->getDebugLoc());

  if (MSSAU) {
    MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
        NewCall, nullptr, NewCall->getParent(), MemorySSA::BeforeTerminator);
    MSSAU->insertDef(cast<MemoryDef>(NewMemAcc), true);
  }

  LLVM_DEBUG(dbgs() << "  Formed memset: " << *NewCall << "\n"
                    << "    from store to: " << *Ev << " at: " << *TheStore
                    << "\n");

  ORE.emit([&]() {
    OptimizationRemark R(DEBUG_TYPE, "ProcessLoopStridedStore",
                         NewCall->getDebugLoc(), Preheader);
    R << "Transformed loop-strided store in "
      << ore::NV("Function", TheStore->getFunction())
      << " function into a call to "
      << ore::NV("NewFunction", NewCall->getCalledFunction())
      << "() intrinsic";
    if (!Stores.empty())
      R << ore::setExtraArgs();
    for (auto *I : Stores) {
      R << ore::NV("FromBlock", I->getParent()->getName())
        << ore::NV("ToBlock", Preheader->getName());
    }
    return R;
  });

  // Okay, the memset has been formed.  Zap the original store and anything that
  // feeds into it.
  for (auto *I : Stores) {
    if (MSSAU)
      MSSAU->removeMemoryAccess(I, true);
    deleteDeadInstruction(I);
  }
  if (MSSAU && VerifyMemorySSA)
    MSSAU->getMemorySSA()->verifyMemorySSA();
  ++NumMemSet;
  ExpCleaner.markResultUsed();
  return true;
}

/// If the stored value is a strided load in the same loop with the same stride
/// this may be transformable into a memcpy.  This kicks in for stuff like
/// for (i) A[i] = B[i];
bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(StoreInst *SI,
                                                    const SCEV *BECount) {
  assert(SI->isUnordered() && "Expected only non-volatile non-ordered stores.");

  Value *StorePtr = SI->getPointerOperand();
  const SCEVAddRecExpr *StoreEv = cast<SCEVAddRecExpr>(SE->getSCEV(StorePtr));
  unsigned StoreSize = DL->getTypeStoreSize(SI->getValueOperand()->getType());

  // The store must be feeding a non-volatile load.
  LoadInst *LI = cast<LoadInst>(SI->getValueOperand());
  assert(LI->isUnordered() && "Expected only non-volatile non-ordered loads.");

  // See if the pointer expression is an AddRec like {base,+,1} on the current
  // loop, which indicates a strided load.  If we have something else, it's a
  // random load we can't handle.
  Value *LoadPtr = LI->getPointerOperand();
  const SCEVAddRecExpr *LoadEv = cast<SCEVAddRecExpr>(SE->getSCEV(LoadPtr));

  const SCEV *StoreSizeSCEV = SE->getConstant(StorePtr->getType(), StoreSize);
  return processLoopStoreOfLoopLoad(StorePtr, LoadPtr, StoreSizeSCEV,
                                    SI->getAlign(), LI->getAlign(), SI, LI,
                                    StoreEv, LoadEv, BECount);
}

class MemmoveVerifier {
public:
  explicit MemmoveVerifier(const Value &LoadBasePtr, const Value &StoreBasePtr,
                           const DataLayout &DL)
      : DL(DL), LoadOff(0), StoreOff(0),
        BP1(llvm::GetPointerBaseWithConstantOffset(
            LoadBasePtr.stripPointerCasts(), LoadOff, DL)),
        BP2(llvm::GetPointerBaseWithConstantOffset(
            StoreBasePtr.stripPointerCasts(), StoreOff, DL)),
        IsSameObject(BP1 == BP2) {}

  bool loadAndStoreMayFormMemmove(unsigned StoreSize, bool IsNegStride,
                                  const Instruction &TheLoad,
                                  bool IsMemCpy) const {
    if (IsMemCpy) {
      // Ensure that LoadBasePtr is after StoreBasePtr or before StoreBasePtr
      // for negative stride.
      if ((!IsNegStride && LoadOff <= StoreOff) ||
          (IsNegStride && LoadOff >= StoreOff))
        return false;
    } else {
      // Ensure that LoadBasePtr is after StoreBasePtr or before StoreBasePtr
      // for negative stride. LoadBasePtr shouldn't overlap with StoreBasePtr.
      int64_t LoadSize =
          DL.getTypeSizeInBits(TheLoad.getType()).getFixedSize() / 8;
      if (BP1 != BP2 || LoadSize != int64_t(StoreSize))
        return false;
      if ((!IsNegStride && LoadOff < StoreOff + int64_t(StoreSize)) ||
          (IsNegStride && LoadOff + LoadSize > StoreOff))
        return false;
    }
    return true;
  }

private:
  const DataLayout &DL;
  int64_t LoadOff;
  int64_t StoreOff;
  const Value *BP1;
  const Value *BP2;

public:
  const bool IsSameObject;
};

bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
    Value *DestPtr, Value *SourcePtr, const SCEV *StoreSizeSCEV,
    MaybeAlign StoreAlign, MaybeAlign LoadAlign, Instruction *TheStore,
    Instruction *TheLoad, const SCEVAddRecExpr *StoreEv,
    const SCEVAddRecExpr *LoadEv, const SCEV *BECount) {

  // FIXME: until llvm.memcpy.inline supports dynamic sizes, we need to
  // conservatively bail here, since otherwise we may have to transform
  // llvm.memcpy.inline into llvm.memcpy which is illegal.
  if (isa<MemCpyInlineInst>(TheStore))
    return false;

  // The trip count of the loop and the base pointer of the addrec SCEV is
  // guaranteed to be loop invariant, which means that it should dominate the
  // header.  This allows us to insert code for it in the preheader.
  BasicBlock *Preheader = CurLoop->getLoopPreheader();
  IRBuilder<> Builder(Preheader->getTerminator());
  SCEVExpander Expander(*SE, *DL, "loop-idiom");

  SCEVExpanderCleaner ExpCleaner(Expander, *DT);

  bool Changed = false;
  const SCEV *StrStart = StoreEv->getStart();
  unsigned StrAS = DestPtr->getType()->getPointerAddressSpace();
  Type *IntIdxTy = Builder.getIntNTy(DL->getIndexSizeInBits(StrAS));

  APInt Stride = getStoreStride(StoreEv);
  const SCEVConstant *ConstStoreSize = dyn_cast<SCEVConstant>(StoreSizeSCEV);

  // TODO: Deal with non-constant size; Currently expect constant store size
  assert(ConstStoreSize && "store size is expected to be a constant");

  int64_t StoreSize = ConstStoreSize->getValue()->getZExtValue();
  bool IsNegStride = StoreSize == -Stride;

  // Handle negative strided loops.
  if (IsNegStride)
    StrStart =
        getStartForNegStride(StrStart, BECount, IntIdxTy, StoreSizeSCEV, SE);

  // Okay, we have a strided store "p[i]" of a loaded value.  We can turn
  // this into a memcpy in the loop preheader now if we want.  However, this
  // would be unsafe to do if there is anything else in the loop that may read
  // or write the memory region we're storing to.  This includes the load that
  // feeds the stores.  Check for an alias by generating the base address and
  // checking everything.
  Value *StoreBasePtr = Expander.expandCodeFor(
      StrStart, Builder.getInt8PtrTy(StrAS), Preheader->getTerminator());

  // From here on out, conservatively report to the pass manager that we've
  // changed the IR, even if we later clean up these added instructions. There
  // may be structural differences e.g. in the order of use lists not accounted
  // for in just a textual dump of the IR. This is written as a variable, even
  // though statically all the places this dominates could be replaced with
  // 'true', with the hope that anyone trying to be clever / "more precise" with
  // the return value will read this comment, and leave them alone.
  Changed = true;

  SmallPtrSet<Instruction *, 2> IgnoredInsts;
  IgnoredInsts.insert(TheStore);

  bool IsMemCpy = isa<MemCpyInst>(TheStore);
  const StringRef InstRemark = IsMemCpy ? "memcpy" : "load and store";

  bool LoopAccessStore =
      mayLoopAccessLocation(StoreBasePtr, ModRefInfo::ModRef, CurLoop, BECount,
                            StoreSizeSCEV, *AA, IgnoredInsts);
  if (LoopAccessStore) {
    // For memmove case it's not enough to guarantee that loop doesn't access
    // TheStore and TheLoad. Additionally we need to make sure that TheStore is
    // the only user of TheLoad.
    if (!TheLoad->hasOneUse())
      return Changed;
    IgnoredInsts.insert(TheLoad);
    if (mayLoopAccessLocation(StoreBasePtr, ModRefInfo::ModRef, CurLoop,
                              BECount, StoreSizeSCEV, *AA, IgnoredInsts)) {
      ORE.emit([&]() {
        return OptimizationRemarkMissed(DEBUG_TYPE, "LoopMayAccessStore",
                                        TheStore)
               << ore::NV("Inst", InstRemark) << " in "
               << ore::NV("Function", TheStore->getFunction())
               << " function will not be hoisted: "
               << ore::NV("Reason", "The loop may access store location");
      });
      return Changed;
    }
    IgnoredInsts.erase(TheLoad);
  }

  const SCEV *LdStart = LoadEv->getStart();
  unsigned LdAS = SourcePtr->getType()->getPointerAddressSpace();

  // Handle negative strided loops.
  if (IsNegStride)
    LdStart =
        getStartForNegStride(LdStart, BECount, IntIdxTy, StoreSizeSCEV, SE);

  // For a memcpy, we have to make sure that the input array is not being
  // mutated by the loop.
  Value *LoadBasePtr = Expander.expandCodeFor(
      LdStart, Builder.getInt8PtrTy(LdAS), Preheader->getTerminator());

  // If the store is a memcpy instruction, we must check if it will write to
  // the load memory locations. So remove it from the ignored stores.
  if (IsMemCpy)
    IgnoredInsts.erase(TheStore);
  MemmoveVerifier Verifier(*LoadBasePtr, *StoreBasePtr, *DL);
  if (mayLoopAccessLocation(LoadBasePtr, ModRefInfo::Mod, CurLoop, BECount,
                            StoreSizeSCEV, *AA, IgnoredInsts)) {
    if (!IsMemCpy) {
      ORE.emit([&]() {
        return OptimizationRemarkMissed(DEBUG_TYPE, "LoopMayAccessLoad",
                                        TheLoad)
               << ore::NV("Inst", InstRemark) << " in "
               << ore::NV("Function", TheStore->getFunction())
               << " function will not be hoisted: "
               << ore::NV("Reason", "The loop may access load location");
      });
      return Changed;
    }
    // At this point loop may access load only for memcpy in same underlying
    // object. If that's not the case bail out.
    if (!Verifier.IsSameObject)
      return Changed;
  }

  bool UseMemMove = IsMemCpy ? Verifier.IsSameObject : LoopAccessStore;
  if (UseMemMove)
    if (!Verifier.loadAndStoreMayFormMemmove(StoreSize, IsNegStride, *TheLoad,
                                             IsMemCpy))
      return Changed;

  if (avoidLIRForMultiBlockLoop())
    return Changed;

  // Okay, everything is safe, we can transform this!

  const SCEV *NumBytesS =
      getNumBytes(BECount, IntIdxTy, StoreSizeSCEV, CurLoop, DL, SE);

  Value *NumBytes =
      Expander.expandCodeFor(NumBytesS, IntIdxTy, Preheader->getTerminator());

  CallInst *NewCall = nullptr;
  // Check whether to generate an unordered atomic memcpy:
  //  If the load or store are atomic, then they must necessarily be unordered
  //  by previous checks.
  if (!TheStore->isAtomic() && !TheLoad->isAtomic()) {
    if (UseMemMove)
      NewCall = Builder.CreateMemMove(StoreBasePtr, StoreAlign, LoadBasePtr,
                                      LoadAlign, NumBytes);
    else
      NewCall = Builder.CreateMemCpy(StoreBasePtr, StoreAlign, LoadBasePtr,
                                     LoadAlign, NumBytes);
  } else {
    // For now don't support unordered atomic memmove.
    if (UseMemMove)
      return Changed;
    // We cannot allow unaligned ops for unordered load/store, so reject
    // anything where the alignment isn't at least the element size.
    assert((StoreAlign.hasValue() && LoadAlign.hasValue()) &&
           "Expect unordered load/store to have align.");
    if (StoreAlign.getValue() < StoreSize || LoadAlign.getValue() < StoreSize)
      return Changed;

    // If the element.atomic memcpy is not lowered into explicit
    // loads/stores later, then it will be lowered into an element-size
    // specific lib call. If the lib call doesn't exist for our store size, then
    // we shouldn't generate the memcpy.
    if (StoreSize > TTI->getAtomicMemIntrinsicMaxElementSize())
      return Changed;

    // Create the call.
    // Note that unordered atomic loads/stores are *required* by the spec to
    // have an alignment but non-atomic loads/stores may not.
    NewCall = Builder.CreateElementUnorderedAtomicMemCpy(
        StoreBasePtr, StoreAlign.getValue(), LoadBasePtr, LoadAlign.getValue(),
        NumBytes, StoreSize);
  }
  NewCall->setDebugLoc(TheStore->getDebugLoc());

  if (MSSAU) {
    MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB(
        NewCall, nullptr, NewCall->getParent(), MemorySSA::BeforeTerminator);
    MSSAU->insertDef(cast<MemoryDef>(NewMemAcc), true);
  }

  LLVM_DEBUG(dbgs() << "  Formed new call: " << *NewCall << "\n"
                    << "    from load ptr=" << *LoadEv << " at: " << *TheLoad
                    << "\n"
                    << "    from store ptr=" << *StoreEv << " at: " << *TheStore
                    << "\n");

  ORE.emit([&]() {
    return OptimizationRemark(DEBUG_TYPE, "ProcessLoopStoreOfLoopLoad",
                              NewCall->getDebugLoc(), Preheader)
           << "Formed a call to "
           << ore::NV("NewFunction", NewCall->getCalledFunction())
           << "() intrinsic from " << ore::NV("Inst", InstRemark)
           << " instruction in " << ore::NV("Function", TheStore->getFunction())
           << " function"
           << ore::setExtraArgs()
           << ore::NV("FromBlock", TheStore->getParent()->getName())
           << ore::NV("ToBlock", Preheader->getName());
  });

  // Okay, a new call to memcpy/memmove has been formed.  Zap the original store
  // and anything that feeds into it.
  if (MSSAU)
    MSSAU->removeMemoryAccess(TheStore, true);
  deleteDeadInstruction(TheStore);
  if (MSSAU && VerifyMemorySSA)
    MSSAU->getMemorySSA()->verifyMemorySSA();
  if (UseMemMove)
    ++NumMemMove;
  else
    ++NumMemCpy;
  ExpCleaner.markResultUsed();
  return true;
}

// When compiling for codesize we avoid idiom recognition for a multi-block loop
// unless it is a loop_memset idiom or a memset/memcpy idiom in a nested loop.
//
bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(bool IsMemset,
                                                   bool IsLoopMemset) {
  if (ApplyCodeSizeHeuristics && CurLoop->getNumBlocks() > 1) {
    if (CurLoop->isOutermost() && (!IsMemset || !IsLoopMemset)) {
      LLVM_DEBUG(dbgs() << "  " << CurLoop->getHeader()->getParent()->getName()
                        << " : LIR " << (IsMemset ? "Memset" : "Memcpy")
                        << " avoided: multi-block top-level loop\n");
      return true;
    }
  }

  return false;
}

bool LoopIdiomRecognize::runOnNoncountableLoop() {
  LLVM_DEBUG(dbgs() << DEBUG_TYPE " Scanning: F["
                    << CurLoop->getHeader()->getParent()->getName()
                    << "] Noncountable Loop %"
                    << CurLoop->getHeader()->getName() << "\n");

  return recognizePopcount() || recognizeAndInsertFFS() ||
         recognizeShiftUntilBitTest() || recognizeShiftUntilZero();
}

/// Check if the given conditional branch is based on the comparison between
/// a variable and zero, and if the variable is non-zero or zero (JmpOnZero is
/// true), the control yields to the loop entry. If the branch matches the
/// behavior, the variable involved in the comparison is returned. This function
/// will be called to see if the precondition and postcondition of the loop are
/// in desirable form.
static Value *matchCondition(BranchInst *BI, BasicBlock *LoopEntry,
                             bool JmpOnZero = false) {
  if (!BI || !BI->isConditional())
    return nullptr;

  ICmpInst *Cond = dyn_cast<ICmpInst>(BI->getCondition());
  if (!Cond)
    return nullptr;

  ConstantInt *CmpZero = dyn_cast<ConstantInt>(Cond->getOperand(1));
  if (!CmpZero || !CmpZero->isZero())
    return nullptr;

  BasicBlock *TrueSucc = BI->getSuccessor(0);
  BasicBlock *FalseSucc = BI->getSuccessor(1);
  if (JmpOnZero)
    std::swap(TrueSucc, FalseSucc);

  ICmpInst::Predicate Pred = Cond->getPredicate();
  if ((Pred == ICmpInst::ICMP_NE && TrueSucc == LoopEntry) ||
      (Pred == ICmpInst::ICMP_EQ && FalseSucc == LoopEntry))
    return Cond->getOperand(0);

  return nullptr;
}

// Check if the recurrence variable `VarX` is in the right form to create
// the idiom. Returns the value coerced to a PHINode if so.
static PHINode *getRecurrenceVar(Value *VarX, Instruction *DefX,
                                 BasicBlock *LoopEntry) {
  auto *PhiX = dyn_cast<PHINode>(VarX);
  if (PhiX && PhiX->getParent() == LoopEntry &&
      (PhiX->getOperand(0) == DefX || PhiX->getOperand(1) == DefX))
    return PhiX;
  return nullptr;
}

/// Return true iff the idiom is detected in the loop.
///
/// Additionally:
/// 1) \p CntInst is set to the instruction counting the population bit.
/// 2) \p CntPhi is set to the corresponding phi node.
/// 3) \p Var is set to the value whose population bits are being counted.
///
/// The core idiom we are trying to detect is:
/// \code
///    if (x0 != 0)
///      goto loop-exit // the precondition of the loop
///    cnt0 = init-val;
///    do {
///       x1 = phi (x0, x2);
///       cnt1 = phi(cnt0, cnt2);
///
///       cnt2 = cnt1 + 1;
///        ...
///       x2 = x1 & (x1 - 1);
///        ...
///    } while(x != 0);
///
/// loop-exit:
/// \endcode
static bool detectPopcountIdiom(Loop *CurLoop, BasicBlock *PreCondBB,
                                Instruction *&CntInst, PHINode *&CntPhi,
                                Value *&Var) {
  // step 1: Check to see if the look-back branch match this pattern:
  //    "if (a!=0) goto loop-entry".
  BasicBlock *LoopEntry;
  Instruction *DefX2, *CountInst;
  Value *VarX1, *VarX0;
  PHINode *PhiX, *CountPhi;

  DefX2 = CountInst = nullptr;
  VarX1 = VarX0 = nullptr;
  PhiX = CountPhi = nullptr;
  LoopEntry = *(CurLoop->block_begin());

  // step 1: Check if the loop-back branch is in desirable form.
  {
    if (Value *T = matchCondition(
            dyn_cast<BranchInst>(LoopEntry->getTerminator()), LoopEntry))
      DefX2 = dyn_cast<Instruction>(T);
    else
      return false;
  }

  // step 2: detect instructions corresponding to "x2 = x1 & (x1 - 1)"
  {
    if (!DefX2 || DefX2->getOpcode() != Instruction::And)
      return false;

    BinaryOperator *SubOneOp;

    if ((SubOneOp = dyn_cast<BinaryOperator>(DefX2->getOperand(0))))
      VarX1 = DefX2->getOperand(1);
    else {
      VarX1 = DefX2->getOperand(0);
      SubOneOp = dyn_cast<BinaryOperator>(DefX2->getOperand(1));
    }
    if (!SubOneOp || SubOneOp->getOperand(0) != VarX1)
      return false;

    ConstantInt *Dec = dyn_cast<ConstantInt>(SubOneOp->getOperand(1));
    if (!Dec ||
        !((SubOneOp->getOpcode() == Instruction::Sub && Dec->isOne()) ||
          (SubOneOp->getOpcode() == Instruction::Add &&
           Dec->isMinusOne()))) {
      return false;
    }
  }

  // step 3: Check the recurrence of variable X
  PhiX = getRecurrenceVar(VarX1, DefX2, LoopEntry);
  if (!PhiX)
    return false;

  // step 4: Find the instruction which count the population: cnt2 = cnt1 + 1
  {
    CountInst = nullptr;
    for (Instruction &Inst : llvm::make_range(
             LoopEntry->getFirstNonPHI()->getIterator(), LoopEntry->end())) {
      if (Inst.getOpcode() != Instruction::Add)
        continue;

      ConstantInt *Inc = dyn_cast<ConstantInt>(Inst.getOperand(1));
      if (!Inc || !Inc->isOne())
        continue;

      PHINode *Phi = getRecurrenceVar(Inst.getOperand(0), &Inst, LoopEntry);
      if (!Phi)
        continue;

      // Check if the result of the instruction is live of the loop.
      bool LiveOutLoop = false;
      for (User *U : Inst.users()) {
        if ((cast<Instruction>(U))->getParent() != LoopEntry) {
          LiveOutLoop = true;
          break;
        }
      }

      if (LiveOutLoop) {
        CountInst = &Inst;
        CountPhi = Phi;
        break;
      }
    }

    if (!CountInst)
      return false;
  }

  // step 5: check if the precondition is in this form:
  //   "if (x != 0) goto loop-head ; else goto somewhere-we-don't-care;"
  {
    auto *PreCondBr = dyn_cast<BranchInst>(PreCondBB->getTerminator());
    Value *T = matchCondition(PreCondBr, CurLoop->getLoopPreheader());
    if (T != PhiX->getOperand(0) && T != PhiX->getOperand(1))
      return false;

    CntInst = CountInst;
    CntPhi = CountPhi;
    Var = T;
  }

  return true;
}

/// Return true if the idiom is detected in the loop.
///
/// Additionally:
/// 1) \p CntInst is set to the instruction Counting Leading Zeros (CTLZ)
///       or nullptr if there is no such.
/// 2) \p CntPhi is set to the corresponding phi node
///       or nullptr if there is no such.
/// 3) \p Var is set to the value whose CTLZ could be used.
/// 4) \p DefX is set to the instruction calculating Loop exit condition.
///
/// The core idiom we are trying to detect is:
/// \code
///    if (x0 == 0)
///      goto loop-exit // the precondition of the loop
///    cnt0 = init-val;
///    do {
///       x = phi (x0, x.next);   //PhiX
///       cnt = phi(cnt0, cnt.next);
///
///       cnt.next = cnt + 1;
///        ...
///       x.next = x >> 1;   // DefX
///        ...
///    } while(x.next != 0);
///
/// loop-exit:
/// \endcode
static bool detectShiftUntilZeroIdiom(Loop *CurLoop, const DataLayout &DL,
                                      Intrinsic::ID &IntrinID, Value *&InitX,
                                      Instruction *&CntInst, PHINode *&CntPhi,
                                      Instruction *&DefX) {
  BasicBlock *LoopEntry;
  Value *VarX = nullptr;

  DefX = nullptr;
  CntInst = nullptr;
  CntPhi = nullptr;
  LoopEntry = *(CurLoop->block_begin());

  // step 1: Check if the loop-back branch is in desirable form.
  if (Value *T = matchCondition(
          dyn_cast<BranchInst>(LoopEntry->getTerminator()), LoopEntry))
    DefX = dyn_cast<Instruction>(T);
  else
    return false;

  // step 2: detect instructions corresponding to "x.next = x >> 1 or x << 1"
  if (!DefX || !DefX->isShift())
    return false;
  IntrinID = DefX->getOpcode() == Instruction::Shl ? Intrinsic::cttz :
                                                     Intrinsic::ctlz;
  ConstantInt *Shft = dyn_cast<ConstantInt>(DefX->getOperand(1));
  if (!Shft || !Shft->isOne())
    return false;
  VarX = DefX->getOperand(0);

  // step 3: Check the recurrence of variable X
  PHINode *PhiX = getRecurrenceVar(VarX, DefX, LoopEntry);
  if (!PhiX)
    return false;

  InitX = PhiX->getIncomingValueForBlock(CurLoop->getLoopPreheader());

  // Make sure the initial value can't be negative otherwise the ashr in the
  // loop might never reach zero which would make the loop infinite.
  if (DefX->getOpcode() == Instruction::AShr && !isKnownNonNegative(InitX, DL))
    return false;

  // step 4: Find the instruction which count the CTLZ: cnt.next = cnt + 1
  //         or cnt.next = cnt + -1.
  // TODO: We can skip the step. If loop trip count is known (CTLZ),
  //       then all uses of "cnt.next" could be optimized to the trip count
  //       plus "cnt0". Currently it is not optimized.
  //       This step could be used to detect POPCNT instruction:
  //       cnt.next = cnt + (x.next & 1)
  for (Instruction &Inst : llvm::make_range(
           LoopEntry->getFirstNonPHI()->getIterator(), LoopEntry->end())) {
    if (Inst.getOpcode() != Instruction::Add)
      continue;

    ConstantInt *Inc = dyn_cast<ConstantInt>(Inst.getOperand(1));
    if (!Inc || (!Inc->isOne() && !Inc->isMinusOne()))
      continue;

    PHINode *Phi = getRecurrenceVar(Inst.getOperand(0), &Inst, LoopEntry);
    if (!Phi)
      continue;

    CntInst = &Inst;
    CntPhi = Phi;
    break;
  }
  if (!CntInst)
    return false;

  return true;
}

/// Recognize CTLZ or CTTZ idiom in a non-countable loop and convert the loop
/// to countable (with CTLZ / CTTZ trip count). If CTLZ / CTTZ inserted as a new
/// trip count returns true; otherwise, returns false.
bool LoopIdiomRecognize::recognizeAndInsertFFS() {
  // Give up if the loop has multiple blocks or multiple backedges.
  if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 1)
    return false;

  Intrinsic::ID IntrinID;
  Value *InitX;
  Instruction *DefX = nullptr;
  PHINode *CntPhi = nullptr;
  Instruction *CntInst = nullptr;
  // Help decide if transformation is profitable. For ShiftUntilZero idiom,
  // this is always 6.
  size_t IdiomCanonicalSize = 6;

  if (!detectShiftUntilZeroIdiom(CurLoop, *DL, IntrinID, InitX,
                                 CntInst, CntPhi, DefX))
    return false;

  bool IsCntPhiUsedOutsideLoop = false;
  for (User *U : CntPhi->users())
    if (!CurLoop->contains(cast<Instruction>(U))) {
      IsCntPhiUsedOutsideLoop = true;
      break;
    }
  bool IsCntInstUsedOutsideLoop = false;
  for (User *U : CntInst->users())
    if (!CurLoop->contains(cast<Instruction>(U))) {
      IsCntInstUsedOutsideLoop = true;
      break;
    }
  // If both CntInst and CntPhi are used outside the loop the profitability
  // is questionable.
  if (IsCntInstUsedOutsideLoop && IsCntPhiUsedOutsideLoop)
    return false;

  // For some CPUs result of CTLZ(X) intrinsic is undefined
  // when X is 0. If we can not guarantee X != 0, we need to check this
  // when expand.
  bool ZeroCheck = false;
  // It is safe to assume Preheader exist as it was checked in
  // parent function RunOnLoop.
  BasicBlock *PH = CurLoop->getLoopPreheader();

  // If we are using the count instruction outside the loop, make sure we
  // have a zero check as a precondition. Without the check the loop would run
  // one iteration for before any check of the input value. This means 0 and 1
  // would have identical behavior in the original loop and thus
  if (!IsCntPhiUsedOutsideLoop) {
    auto *PreCondBB = PH->getSinglePredecessor();
    if (!PreCondBB)
      return false;
    auto *PreCondBI = dyn_cast<BranchInst>(PreCondBB->getTerminator());
    if (!PreCondBI)
      return false;
    if (matchCondition(PreCondBI, PH) != InitX)
      return false;
    ZeroCheck = true;
  }

  // Check if CTLZ / CTTZ intrinsic is profitable. Assume it is always
  // profitable if we delete the loop.

  // the loop has only 6 instructions:
  //  %n.addr.0 = phi [ %n, %entry ], [ %shr, %while.cond ]
  //  %i.0 = phi [ %i0, %entry ], [ %inc, %while.cond ]
  //  %shr = ashr %n.addr.0, 1
  //  %tobool = icmp eq %shr, 0
  //  %inc = add nsw %i.0, 1
  //  br i1 %tobool

  const Value *Args[] = {InitX,
                         ConstantInt::getBool(InitX->getContext(), ZeroCheck)};

  // @llvm.dbg doesn't count as they have no semantic effect.
  auto InstWithoutDebugIt = CurLoop->getHeader()->instructionsWithoutDebug();
  uint32_t HeaderSize =
      std::distance(InstWithoutDebugIt.begin(), InstWithoutDebugIt.end());

  IntrinsicCostAttributes Attrs(IntrinID, InitX->getType(), Args);
  InstructionCost Cost =
    TTI->getIntrinsicInstrCost(Attrs, TargetTransformInfo::TCK_SizeAndLatency);
  if (HeaderSize != IdiomCanonicalSize &&
      Cost > TargetTransformInfo::TCC_Basic)
    return false;

  transformLoopToCountable(IntrinID, PH, CntInst, CntPhi, InitX, DefX,
                           DefX->getDebugLoc(), ZeroCheck,
                           IsCntPhiUsedOutsideLoop);
  return true;
}

/// Recognizes a population count idiom in a non-countable loop.
///
/// If detected, transforms the relevant code to issue the popcount intrinsic
/// function call, and returns true; otherwise, returns false.
bool LoopIdiomRecognize::recognizePopcount() {
  if (TTI->getPopcntSupport(32) != TargetTransformInfo::PSK_FastHardware)
    return false;

  // Counting population are usually conducted by few arithmetic instructions.
  // Such instructions can be easily "absorbed" by vacant slots in a
  // non-compact loop. Therefore, recognizing popcount idiom only makes sense
  // in a compact loop.

  // Give up if the loop has multiple blocks or multiple backedges.
  if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 1)
    return false;

  BasicBlock *LoopBody = *(CurLoop->block_begin());
  if (LoopBody->size() >= 20) {
    // The loop is too big, bail out.
    return false;
  }

  // It should have a preheader containing nothing but an unconditional branch.
  BasicBlock *PH = CurLoop->getLoopPreheader();
  if (!PH || &PH->front() != PH->getTerminator())
    return false;
  auto *EntryBI = dyn_cast<BranchInst>(PH->getTerminator());
  if (!EntryBI || EntryBI->isConditional())
    return false;

  // It should have a precondition block where the generated popcount intrinsic
  // function can be inserted.
  auto *PreCondBB = PH->getSinglePredecessor();
  if (!PreCondBB)
    return false;
  auto *PreCondBI = dyn_cast<BranchInst>(PreCondBB->getTerminator());
  if (!PreCondBI || PreCondBI->isUnconditional())
    return false;

  Instruction *CntInst;
  PHINode *CntPhi;
  Value *Val;
  if (!detectPopcountIdiom(CurLoop, PreCondBB, CntInst, CntPhi, Val))
    return false;

  transformLoopToPopcount(PreCondBB, CntInst, CntPhi, Val);
  return true;
}

static CallInst *createPopcntIntrinsic(IRBuilder<> &IRBuilder, Value *Val,
                                       const DebugLoc &DL) {
  Value *Ops[] = {Val};
  Type *Tys[] = {Val->getType()};

  Module *M = IRBuilder.GetInsertBlock()->getParent()->getParent();
  Function *Func = Intrinsic::getDeclaration(M, Intrinsic::ctpop, Tys);
  CallInst *CI = IRBuilder.CreateCall(Func, Ops);
  CI->setDebugLoc(DL);

  return CI;
}

static CallInst *createFFSIntrinsic(IRBuilder<> &IRBuilder, Value *Val,
                                    const DebugLoc &DL, bool ZeroCheck,
                                    Intrinsic::ID IID) {
  Value *Ops[] = {Val, IRBuilder.getInt1(ZeroCheck)};
  Type *Tys[] = {Val->getType()};

  Module *M = IRBuilder.GetInsertBlock()->getParent()->getParent();
  Function *Func = Intrinsic::getDeclaration(M, IID, Tys);
  CallInst *CI = IRBuilder.CreateCall(Func, Ops);
  CI->setDebugLoc(DL);

  return CI;
}

/// Transform the following loop (Using CTLZ, CTTZ is similar):
/// loop:
///   CntPhi = PHI [Cnt0, CntInst]
///   PhiX = PHI [InitX, DefX]
///   CntInst = CntPhi + 1
///   DefX = PhiX >> 1
///   LOOP_BODY
///   Br: loop if (DefX != 0)
/// Use(CntPhi) or Use(CntInst)
///
/// Into:
/// If CntPhi used outside the loop:
///   CountPrev = BitWidth(InitX) - CTLZ(InitX >> 1)
///   Count = CountPrev + 1
/// else
///   Count = BitWidth(InitX) - CTLZ(InitX)
/// loop:
///   CntPhi = PHI [Cnt0, CntInst]
///   PhiX = PHI [InitX, DefX]
///   PhiCount = PHI [Count, Dec]
///   CntInst = CntPhi + 1
///   DefX = PhiX >> 1
///   Dec = PhiCount - 1
///   LOOP_BODY
///   Br: loop if (Dec != 0)
/// Use(CountPrev + Cnt0) // Use(CntPhi)
/// or
/// Use(Count + Cnt0) // Use(CntInst)
///
/// If LOOP_BODY is empty the loop will be deleted.
/// If CntInst and DefX are not used in LOOP_BODY they will be removed.
void LoopIdiomRecognize::transformLoopToCountable(
    Intrinsic::ID IntrinID, BasicBlock *Preheader, Instruction *CntInst,
    PHINode *CntPhi, Value *InitX, Instruction *DefX, const DebugLoc &DL,
    bool ZeroCheck, bool IsCntPhiUsedOutsideLoop) {
  BranchInst *PreheaderBr = cast<BranchInst>(Preheader->getTerminator());

  // Step 1: Insert the CTLZ/CTTZ instruction at the end of the preheader block
  IRBuilder<> Builder(PreheaderBr);
  Builder.SetCurrentDebugLocation(DL);

  // If there are no uses of CntPhi crate:
  //   Count = BitWidth - CTLZ(InitX);
  //   NewCount = Count;
  // If there are uses of CntPhi create:
  //   NewCount = BitWidth - CTLZ(InitX >> 1);
  //   Count = NewCount + 1;
  Value *InitXNext;
  if (IsCntPhiUsedOutsideLoop) {
    if (DefX->getOpcode() == Instruction::AShr)
      InitXNext = Builder.CreateAShr(InitX, 1);
    else if (DefX->getOpcode() == Instruction::LShr)
      InitXNext = Builder.CreateLShr(InitX, 1);
    else if (DefX->getOpcode() == Instruction::Shl) // cttz
      InitXNext = Builder.CreateShl(InitX, 1);
    else
      llvm_unreachable("Unexpected opcode!");
  } else
    InitXNext = InitX;
  Value *Count =
      createFFSIntrinsic(Builder, InitXNext, DL, ZeroCheck, IntrinID);
  Type *CountTy = Count->getType();
  Count = Builder.CreateSub(
      ConstantInt::get(CountTy, CountTy->getIntegerBitWidth()), Count);
  Value *NewCount = Count;
  if (IsCntPhiUsedOutsideLoop)
    Count = Builder.CreateAdd(Count, ConstantInt::get(CountTy, 1));

  NewCount = Builder.CreateZExtOrTrunc(NewCount, CntInst->getType());

  Value *CntInitVal = CntPhi->getIncomingValueForBlock(Preheader);
  if (cast<ConstantInt>(CntInst->getOperand(1))->isOne()) {
    // If the counter was being incremented in the loop, add NewCount to the
    // counter's initial value, but only if the initial value is not zero.
    ConstantInt *InitConst = dyn_cast<ConstantInt>(CntInitVal);
    if (!InitConst || !InitConst->isZero())
      NewCount = Builder.CreateAdd(NewCount, CntInitVal);
  } else {
    // If the count was being decremented in the loop, subtract NewCount from
    // the counter's initial value.
    NewCount = Builder.CreateSub(CntInitVal, NewCount);
  }

  // Step 2: Insert new IV and loop condition:
  // loop:
  //   ...
  //   PhiCount = PHI [Count, Dec]
  //   ...
  //   Dec = PhiCount - 1
  //   ...
  //   Br: loop if (Dec != 0)
  BasicBlock *Body = *(CurLoop->block_begin());
  auto *LbBr = cast<BranchInst>(Body->getTerminator());
  ICmpInst *LbCond = cast<ICmpInst>(LbBr->getCondition());

  PHINode *TcPhi = PHINode::Create(CountTy, 2, "tcphi", &Body->front());

  Builder.SetInsertPoint(LbCond);
  Instruction *TcDec = cast<Instruction>(Builder.CreateSub(
      TcPhi, ConstantInt::get(CountTy, 1), "tcdec", false, true));

  TcPhi->addIncoming(Count, Preheader);
  TcPhi->addIncoming(TcDec, Body);

  CmpInst::Predicate Pred =
      (LbBr->getSuccessor(0) == Body) ? CmpInst::ICMP_NE : CmpInst::ICMP_EQ;
  LbCond->setPredicate(Pred);
  LbCond->setOperand(0, TcDec);
  LbCond->setOperand(1, ConstantInt::get(CountTy, 0));

  // Step 3: All the references to the original counter outside
  //  the loop are replaced with the NewCount
  if (IsCntPhiUsedOutsideLoop)
    CntPhi->replaceUsesOutsideBlock(NewCount, Body);
  else
    CntInst->replaceUsesOutsideBlock(NewCount, Body);

  // step 4: Forget the "non-computable" trip-count SCEV associated with the
  //   loop. The loop would otherwise not be deleted even if it becomes empty.
  SE->forgetLoop(CurLoop);
}

void LoopIdiomRecognize::transformLoopToPopcount(BasicBlock *PreCondBB,
                                                 Instruction *CntInst,
                                                 PHINode *CntPhi, Value *Var) {
  BasicBlock *PreHead = CurLoop->getLoopPreheader();
  auto *PreCondBr = cast<BranchInst>(PreCondBB->getTerminator());
  const DebugLoc &DL = CntInst->getDebugLoc();

  // Assuming before transformation, the loop is following:
  //  if (x) // the precondition
  //     do { cnt++; x &= x - 1; } while(x);

  // Step 1: Insert the ctpop instruction at the end of the precondition block
  IRBuilder<> Builder(PreCondBr);
  Value *PopCnt, *PopCntZext, *NewCount, *TripCnt;
  {
    PopCnt = createPopcntIntrinsic(Builder, Var, DL);
    NewCount = PopCntZext =
        Builder.CreateZExtOrTrunc(PopCnt, cast<IntegerType>(CntPhi->getType()));

    if (NewCount != PopCnt)
      (cast<Instruction>(NewCount))->setDebugLoc(DL);

    // TripCnt is exactly the number of iterations the loop has
    TripCnt = NewCount;

    // If the population counter's initial value is not zero, insert Add Inst.
    Value *CntInitVal = CntPhi->getIncomingValueForBlock(PreHead);
    ConstantInt *InitConst = dyn_cast<ConstantInt>(CntInitVal);
    if (!InitConst || !InitConst->isZero()) {
      NewCount = Builder.CreateAdd(NewCount, CntInitVal);
      (cast<Instruction>(NewCount))->setDebugLoc(DL);
    }
  }

  // Step 2: Replace the precondition from "if (x == 0) goto loop-exit" to
  //   "if (NewCount == 0) loop-exit". Without this change, the intrinsic
  //   function would be partial dead code, and downstream passes will drag
  //   it back from the precondition block to the preheader.
  {
    ICmpInst *PreCond = cast<ICmpInst>(PreCondBr->getCondition());

    Value *Opnd0 = PopCntZext;
    Value *Opnd1 = ConstantInt::get(PopCntZext->getType(), 0);
    if (PreCond->getOperand(0) != Var)
      std::swap(Opnd0, Opnd1);

    ICmpInst *NewPreCond = cast<ICmpInst>(
        Builder.CreateICmp(PreCond->getPredicate(), Opnd0, Opnd1));
    PreCondBr->setCondition(NewPreCond);

    RecursivelyDeleteTriviallyDeadInstructions(PreCond, TLI);
  }

  // Step 3: Note that the population count is exactly the trip count of the
  // loop in question, which enable us to convert the loop from noncountable
  // loop into a countable one. The benefit is twofold:
  //
  //  - If the loop only counts population, the entire loop becomes dead after
  //    the transformation. It is a lot easier to prove a countable loop dead
  //    than to prove a noncountable one. (In some C dialects, an infinite loop
  //    isn't dead even if it computes nothing useful. In general, DCE needs
  //    to prove a noncountable loop finite before safely delete it.)
  //
  //  - If the loop also performs something else, it remains alive.
  //    Since it is transformed to countable form, it can be aggressively
  //    optimized by some optimizations which are in general not applicable
  //    to a noncountable loop.
  //
  // After this step, this loop (conceptually) would look like following:
  //   newcnt = __builtin_ctpop(x);
  //   t = newcnt;
  //   if (x)
  //     do { cnt++; x &= x-1; t--) } while (t > 0);
  BasicBlock *Body = *(CurLoop->block_begin());
  {
    auto *LbBr = cast<BranchInst>(Body->getTerminator());
    ICmpInst *LbCond = cast<ICmpInst>(LbBr->getCondition());
    Type *Ty = TripCnt->getType();

    PHINode *TcPhi = PHINode::Create(Ty, 2, "tcphi", &Body->front());

    Builder.SetInsertPoint(LbCond);
    Instruction *TcDec = cast<Instruction>(
        Builder.CreateSub(TcPhi, ConstantInt::get(Ty, 1),
                          "tcdec", false, true));

    TcPhi->addIncoming(TripCnt, PreHead);
    TcPhi->addIncoming(TcDec, Body);

    CmpInst::Predicate Pred =
        (LbBr->getSuccessor(0) == Body) ? CmpInst::ICMP_UGT : CmpInst::ICMP_SLE;
    LbCond->setPredicate(Pred);
    LbCond->setOperand(0, TcDec);
    LbCond->setOperand(1, ConstantInt::get(Ty, 0));
  }

  // Step 4: All the references to the original population counter outside
  //  the loop are replaced with the NewCount -- the value returned from
  //  __builtin_ctpop().
  CntInst->replaceUsesOutsideBlock(NewCount, Body);

  // step 5: Forget the "non-computable" trip-count SCEV associated with the
  //   loop. The loop would otherwise not be deleted even if it becomes empty.
  SE->forgetLoop(CurLoop);
}

/// Match loop-invariant value.
template <typename SubPattern_t> struct match_LoopInvariant {
  SubPattern_t SubPattern;
  const Loop *L;

  match_LoopInvariant(const SubPattern_t &SP, const Loop *L)
      : SubPattern(SP), L(L) {}

  template <typename ITy> bool match(ITy *V) {
    return L->isLoopInvariant(V) && SubPattern.match(V);
  }
};

/// Matches if the value is loop-invariant.
template <typename Ty>
inline match_LoopInvariant<Ty> m_LoopInvariant(const Ty &M, const Loop *L) {
  return match_LoopInvariant<Ty>(M, L);
}

/// Return true if the idiom is detected in the loop.
///
/// The core idiom we are trying to detect is:
/// \code
///   entry:
///     <...>
///     %bitmask = shl i32 1, %bitpos
///     br label %loop
///
///   loop:
///     %x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
///     %x.curr.bitmasked = and i32 %x.curr, %bitmask
///     %x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
///     %x.next = shl i32 %x.curr, 1
///     <...>
///     br i1 %x.curr.isbitunset, label %loop, label %end
///
///   end:
///     %x.curr.res = phi i32 [ %x.curr, %loop ] <...>
///     %x.next.res = phi i32 [ %x.next, %loop ] <...>
///     <...>
/// \endcode
static bool detectShiftUntilBitTestIdiom(Loop *CurLoop, Value *&BaseX,
                                         Value *&BitMask, Value *&BitPos,
                                         Value *&CurrX, Instruction *&NextX) {
  LLVM_DEBUG(dbgs() << DEBUG_TYPE
             " Performing shift-until-bittest idiom detection.\n");

  // Give up if the loop has multiple blocks or multiple backedges.
  if (CurLoop->getNumBlocks() != 1 || CurLoop->getNumBackEdges() != 1) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad block/backedge count.\n");
    return false;
  }

  BasicBlock *LoopHeaderBB = CurLoop->getHeader();
  BasicBlock *LoopPreheaderBB = CurLoop->getLoopPreheader();
  assert(LoopPreheaderBB && "There is always a loop preheader.");

  using namespace PatternMatch;

  // Step 1: Check if the loop backedge is in desirable form.

  ICmpInst::Predicate Pred;
  Value *CmpLHS, *CmpRHS;
  BasicBlock *TrueBB, *FalseBB;
  if (!match(LoopHeaderBB->getTerminator(),
             m_Br(m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS)),
                  m_BasicBlock(TrueBB), m_BasicBlock(FalseBB)))) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad backedge structure.\n");
    return false;
  }

  // Step 2: Check if the backedge's condition is in desirable form.

  auto MatchVariableBitMask = [&]() {
    return ICmpInst::isEquality(Pred) && match(CmpRHS, m_Zero()) &&
           match(CmpLHS,
                 m_c_And(m_Value(CurrX),
                         m_CombineAnd(
                             m_Value(BitMask),
                             m_LoopInvariant(m_Shl(m_One(), m_Value(BitPos)),
                                             CurLoop))));
  };
  auto MatchConstantBitMask = [&]() {
    return ICmpInst::isEquality(Pred) && match(CmpRHS, m_Zero()) &&
           match(CmpLHS, m_And(m_Value(CurrX),
                               m_CombineAnd(m_Value(BitMask), m_Power2()))) &&
           (BitPos = ConstantExpr::getExactLogBase2(cast<Constant>(BitMask)));
  };
  auto MatchDecomposableConstantBitMask = [&]() {
    APInt Mask;
    return llvm::decomposeBitTestICmp(CmpLHS, CmpRHS, Pred, CurrX, Mask) &&
           ICmpInst::isEquality(Pred) && Mask.isPowerOf2() &&
           (BitMask = ConstantInt::get(CurrX->getType(), Mask)) &&
           (BitPos = ConstantInt::get(CurrX->getType(), Mask.logBase2()));
  };

  if (!MatchVariableBitMask() && !MatchConstantBitMask() &&
      !MatchDecomposableConstantBitMask()) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad backedge comparison.\n");
    return false;
  }

  // Step 3: Check if the recurrence is in desirable form.
  auto *CurrXPN = dyn_cast<PHINode>(CurrX);
  if (!CurrXPN || CurrXPN->getParent() != LoopHeaderBB) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Not an expected PHI node.\n");
    return false;
  }

  BaseX = CurrXPN->getIncomingValueForBlock(LoopPreheaderBB);
  NextX =
      dyn_cast<Instruction>(CurrXPN->getIncomingValueForBlock(LoopHeaderBB));

  assert(CurLoop->isLoopInvariant(BaseX) &&
         "Expected BaseX to be avaliable in the preheader!");

  if (!NextX || !match(NextX, m_Shl(m_Specific(CurrX), m_One()))) {
    // FIXME: support right-shift?
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad recurrence.\n");
    return false;
  }

  // Step 4: Check if the backedge's destinations are in desirable form.

  assert(ICmpInst::isEquality(Pred) &&
         "Should only get equality predicates here.");

  // cmp-br is commutative, so canonicalize to a single variant.
  if (Pred != ICmpInst::Predicate::ICMP_EQ) {
    Pred = ICmpInst::getInversePredicate(Pred);
    std::swap(TrueBB, FalseBB);
  }

  // We expect to exit loop when comparison yields false,
  // so when it yields true we should branch back to loop header.
  if (TrueBB != LoopHeaderBB) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad backedge flow.\n");
    return false;
  }

  // Okay, idiom checks out.
  return true;
}

/// Look for the following loop:
/// \code
///   entry:
///     <...>
///     %bitmask = shl i32 1, %bitpos
///     br label %loop
///
///   loop:
///     %x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
///     %x.curr.bitmasked = and i32 %x.curr, %bitmask
///     %x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
///     %x.next = shl i32 %x.curr, 1
///     <...>
///     br i1 %x.curr.isbitunset, label %loop, label %end
///
///   end:
///     %x.curr.res = phi i32 [ %x.curr, %loop ] <...>
///     %x.next.res = phi i32 [ %x.next, %loop ] <...>
///     <...>
/// \endcode
///
/// And transform it into:
/// \code
///   entry:
///     %bitmask = shl i32 1, %bitpos
///     %lowbitmask = add i32 %bitmask, -1
///     %mask = or i32 %lowbitmask, %bitmask
///     %x.masked = and i32 %x, %mask
///     %x.masked.numleadingzeros = call i32 @llvm.ctlz.i32(i32 %x.masked,
///                                                         i1 true)
///     %x.masked.numactivebits = sub i32 32, %x.masked.numleadingzeros
///     %x.masked.leadingonepos = add i32 %x.masked.numactivebits, -1
///     %backedgetakencount = sub i32 %bitpos, %x.masked.leadingonepos
///     %tripcount = add i32 %backedgetakencount, 1
///     %x.curr = shl i32 %x, %backedgetakencount
///     %x.next = shl i32 %x, %tripcount
///     br label %loop
///
///   loop:
///     %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.next, %loop ]
///     %loop.iv.next = add nuw i32 %loop.iv, 1
///     %loop.ivcheck = icmp eq i32 %loop.iv.next, %tripcount
///     <...>
///     br i1 %loop.ivcheck, label %end, label %loop
///
///   end:
///     %x.curr.res = phi i32 [ %x.curr, %loop ] <...>
///     %x.next.res = phi i32 [ %x.next, %loop ] <...>
///     <...>
/// \endcode
bool LoopIdiomRecognize::recognizeShiftUntilBitTest() {
  bool MadeChange = false;

  Value *X, *BitMask, *BitPos, *XCurr;
  Instruction *XNext;
  if (!detectShiftUntilBitTestIdiom(CurLoop, X, BitMask, BitPos, XCurr,
                                    XNext)) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE
               " shift-until-bittest idiom detection failed.\n");
    return MadeChange;
  }
  LLVM_DEBUG(dbgs() << DEBUG_TYPE " shift-until-bittest idiom detected!\n");

  // Ok, it is the idiom we were looking for, we *could* transform this loop,
  // but is it profitable to transform?

  BasicBlock *LoopHeaderBB = CurLoop->getHeader();
  BasicBlock *LoopPreheaderBB = CurLoop->getLoopPreheader();
  assert(LoopPreheaderBB && "There is always a loop preheader.");

  BasicBlock *SuccessorBB = CurLoop->getExitBlock();
  assert(SuccessorBB && "There is only a single successor.");

  IRBuilder<> Builder(LoopPreheaderBB->getTerminator());
  Builder.SetCurrentDebugLocation(cast<Instruction>(XCurr)->getDebugLoc());

  Intrinsic::ID IntrID = Intrinsic::ctlz;
  Type *Ty = X->getType();
  unsigned Bitwidth = Ty->getScalarSizeInBits();

  TargetTransformInfo::TargetCostKind CostKind =
      TargetTransformInfo::TCK_SizeAndLatency;

  // The rewrite is considered to be unprofitable iff and only iff the
  // intrinsic/shift we'll use are not cheap. Note that we are okay with *just*
  // making the loop countable, even if nothing else changes.
  IntrinsicCostAttributes Attrs(
      IntrID, Ty, {UndefValue::get(Ty), /*is_zero_undef=*/Builder.getTrue()});
  InstructionCost Cost = TTI->getIntrinsicInstrCost(Attrs, CostKind);
  if (Cost > TargetTransformInfo::TCC_Basic) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE
               " Intrinsic is too costly, not beneficial\n");
    return MadeChange;
  }
  if (TTI->getArithmeticInstrCost(Instruction::Shl, Ty, CostKind) >
      TargetTransformInfo::TCC_Basic) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Shift is too costly, not beneficial\n");
    return MadeChange;
  }

  // Ok, transform appears worthwhile.
  MadeChange = true;

  // Step 1: Compute the loop trip count.

  Value *LowBitMask = Builder.CreateAdd(BitMask, Constant::getAllOnesValue(Ty),
                                        BitPos->getName() + ".lowbitmask");
  Value *Mask =
      Builder.CreateOr(LowBitMask, BitMask, BitPos->getName() + ".mask");
  Value *XMasked = Builder.CreateAnd(X, Mask, X->getName() + ".masked");
  CallInst *XMaskedNumLeadingZeros = Builder.CreateIntrinsic(
      IntrID, Ty, {XMasked, /*is_zero_undef=*/Builder.getTrue()},
      /*FMFSource=*/nullptr, XMasked->getName() + ".numleadingzeros");
  Value *XMaskedNumActiveBits = Builder.CreateSub(
      ConstantInt::get(Ty, Ty->getScalarSizeInBits()), XMaskedNumLeadingZeros,
      XMasked->getName() + ".numactivebits", /*HasNUW=*/true,
      /*HasNSW=*/Bitwidth != 2);
  Value *XMaskedLeadingOnePos =
      Builder.CreateAdd(XMaskedNumActiveBits, Constant::getAllOnesValue(Ty),
                        XMasked->getName() + ".leadingonepos", /*HasNUW=*/false,
                        /*HasNSW=*/Bitwidth > 2);

  Value *LoopBackedgeTakenCount = Builder.CreateSub(
      BitPos, XMaskedLeadingOnePos, CurLoop->getName() + ".backedgetakencount",
      /*HasNUW=*/true, /*HasNSW=*/true);
  // We know loop's backedge-taken count, but what's loop's trip count?
  // Note that while NUW is always safe, while NSW is only for bitwidths != 2.
  Value *LoopTripCount =
      Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
                        CurLoop->getName() + ".tripcount", /*HasNUW=*/true,
                        /*HasNSW=*/Bitwidth != 2);

  // Step 2: Compute the recurrence's final value without a loop.

  // NewX is always safe to compute, because `LoopBackedgeTakenCount`
  // will always be smaller than `bitwidth(X)`, i.e. we never get poison.
  Value *NewX = Builder.CreateShl(X, LoopBackedgeTakenCount);
  NewX->takeName(XCurr);
  if (auto *I = dyn_cast<Instruction>(NewX))
    I->copyIRFlags(XNext, /*IncludeWrapFlags=*/true);

  Value *NewXNext;
  // Rewriting XNext is more complicated, however, because `X << LoopTripCount`
  // will be poison iff `LoopTripCount == bitwidth(X)` (which will happen
  // iff `BitPos` is `bitwidth(x) - 1` and `X` is `1`). So unless we know
  // that isn't the case, we'll need to emit an alternative, safe IR.
  if (XNext->hasNoSignedWrap() || XNext->hasNoUnsignedWrap() ||
      PatternMatch::match(
          BitPos, PatternMatch::m_SpecificInt_ICMP(
                      ICmpInst::ICMP_NE, APInt(Ty->getScalarSizeInBits(),
                                               Ty->getScalarSizeInBits() - 1))))
    NewXNext = Builder.CreateShl(X, LoopTripCount);
  else {
    // Otherwise, just additionally shift by one. It's the smallest solution,
    // alternatively, we could check that NewX is INT_MIN (or BitPos is )
    // and select 0 instead.
    NewXNext = Builder.CreateShl(NewX, ConstantInt::get(Ty, 1));
  }

  NewXNext->takeName(XNext);
  if (auto *I = dyn_cast<Instruction>(NewXNext))
    I->copyIRFlags(XNext, /*IncludeWrapFlags=*/true);

  // Step 3: Adjust the successor basic block to recieve the computed
  //         recurrence's final value instead of the recurrence itself.

  XCurr->replaceUsesOutsideBlock(NewX, LoopHeaderBB);
  XNext->replaceUsesOutsideBlock(NewXNext, LoopHeaderBB);

  // Step 4: Rewrite the loop into a countable form, with canonical IV.

  // The new canonical induction variable.
  Builder.SetInsertPoint(&LoopHeaderBB->front());
  auto *IV = Builder.CreatePHI(Ty, 2, CurLoop->getName() + ".iv");

  // The induction itself.
  // Note that while NUW is always safe, while NSW is only for bitwidths != 2.
  Builder.SetInsertPoint(LoopHeaderBB->getTerminator());
  auto *IVNext =
      Builder.CreateAdd(IV, ConstantInt::get(Ty, 1), IV->getName() + ".next",
                        /*HasNUW=*/true, /*HasNSW=*/Bitwidth != 2);

  // The loop trip count check.
  auto *IVCheck = Builder.CreateICmpEQ(IVNext, LoopTripCount,
                                       CurLoop->getName() + ".ivcheck");
  Builder.CreateCondBr(IVCheck, SuccessorBB, LoopHeaderBB);
  LoopHeaderBB->getTerminator()->eraseFromParent();

  // Populate the IV PHI.
  IV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
  IV->addIncoming(IVNext, LoopHeaderBB);

  // Step 5: Forget the "non-computable" trip-count SCEV associated with the
  //   loop. The loop would otherwise not be deleted even if it becomes empty.

  SE->forgetLoop(CurLoop);

  // Other passes will take care of actually deleting the loop if possible.

  LLVM_DEBUG(dbgs() << DEBUG_TYPE " shift-until-bittest idiom optimized!\n");

  ++NumShiftUntilBitTest;
  return MadeChange;
}

/// Return true if the idiom is detected in the loop.
///
/// The core idiom we are trying to detect is:
/// \code
///   entry:
///     <...>
///     %start = <...>
///     %extraoffset = <...>
///     <...>
///     br label %for.cond
///
///   loop:
///     %iv = phi i8 [ %start, %entry ], [ %iv.next, %for.cond ]
///     %nbits = add nsw i8 %iv, %extraoffset
///     %val.shifted = {{l,a}shr,shl} i8 %val, %nbits
///     %val.shifted.iszero = icmp eq i8 %val.shifted, 0
///     %iv.next = add i8 %iv, 1
///     <...>
///     br i1 %val.shifted.iszero, label %end, label %loop
///
///   end:
///     %iv.res = phi i8 [ %iv, %loop ] <...>
///     %nbits.res = phi i8 [ %nbits, %loop ] <...>
///     %val.shifted.res = phi i8 [ %val.shifted, %loop ] <...>
///     %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ] <...>
///     %iv.next.res = phi i8 [ %iv.next, %loop ] <...>
///     <...>
/// \endcode
static bool detectShiftUntilZeroIdiom(Loop *CurLoop, ScalarEvolution *SE,
                                      Instruction *&ValShiftedIsZero,
                                      Intrinsic::ID &IntrinID, Instruction *&IV,
                                      Value *&Start, Value *&Val,
                                      const SCEV *&ExtraOffsetExpr,
                                      bool &InvertedCond) {
  LLVM_DEBUG(dbgs() << DEBUG_TYPE
             " Performing shift-until-zero idiom detection.\n");

  // Give up if the loop has multiple blocks or multiple backedges.
  if (CurLoop->getNumBlocks() != 1 || CurLoop->getNumBackEdges() != 1) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad block/backedge count.\n");
    return false;
  }

  Instruction *ValShifted, *NBits, *IVNext;
  Value *ExtraOffset;

  BasicBlock *LoopHeaderBB = CurLoop->getHeader();
  BasicBlock *LoopPreheaderBB = CurLoop->getLoopPreheader();
  assert(LoopPreheaderBB && "There is always a loop preheader.");

  using namespace PatternMatch;

  // Step 1: Check if the loop backedge, condition is in desirable form.

  ICmpInst::Predicate Pred;
  BasicBlock *TrueBB, *FalseBB;
  if (!match(LoopHeaderBB->getTerminator(),
             m_Br(m_Instruction(ValShiftedIsZero), m_BasicBlock(TrueBB),
                  m_BasicBlock(FalseBB))) ||
      !match(ValShiftedIsZero,
             m_ICmp(Pred, m_Instruction(ValShifted), m_Zero())) ||
      !ICmpInst::isEquality(Pred)) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad backedge structure.\n");
    return false;
  }

  // Step 2: Check if the comparison's operand is in desirable form.
  // FIXME: Val could be a one-input PHI node, which we should look past.
  if (!match(ValShifted, m_Shift(m_LoopInvariant(m_Value(Val), CurLoop),
                                 m_Instruction(NBits)))) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad comparisons value computation.\n");
    return false;
  }
  IntrinID = ValShifted->getOpcode() == Instruction::Shl ? Intrinsic::cttz
                                                         : Intrinsic::ctlz;

  // Step 3: Check if the shift amount is in desirable form.

  if (match(NBits, m_c_Add(m_Instruction(IV),
                           m_LoopInvariant(m_Value(ExtraOffset), CurLoop))) &&
      (NBits->hasNoSignedWrap() || NBits->hasNoUnsignedWrap()))
    ExtraOffsetExpr = SE->getNegativeSCEV(SE->getSCEV(ExtraOffset));
  else if (match(NBits,
                 m_Sub(m_Instruction(IV),
                       m_LoopInvariant(m_Value(ExtraOffset), CurLoop))) &&
           NBits->hasNoSignedWrap())
    ExtraOffsetExpr = SE->getSCEV(ExtraOffset);
  else {
    IV = NBits;
    ExtraOffsetExpr = SE->getZero(NBits->getType());
  }

  // Step 4: Check if the recurrence is in desirable form.
  auto *IVPN = dyn_cast<PHINode>(IV);
  if (!IVPN || IVPN->getParent() != LoopHeaderBB) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Not an expected PHI node.\n");
    return false;
  }

  Start = IVPN->getIncomingValueForBlock(LoopPreheaderBB);
  IVNext = dyn_cast<Instruction>(IVPN->getIncomingValueForBlock(LoopHeaderBB));

  if (!IVNext || !match(IVNext, m_Add(m_Specific(IVPN), m_One()))) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad recurrence.\n");
    return false;
  }

  // Step 4: Check if the backedge's destinations are in desirable form.

  assert(ICmpInst::isEquality(Pred) &&
         "Should only get equality predicates here.");

  // cmp-br is commutative, so canonicalize to a single variant.
  InvertedCond = Pred != ICmpInst::Predicate::ICMP_EQ;
  if (InvertedCond) {
    Pred = ICmpInst::getInversePredicate(Pred);
    std::swap(TrueBB, FalseBB);
  }

  // We expect to exit loop when comparison yields true,
  // so when it yields false we should branch back to loop header.
  if (FalseBB != LoopHeaderBB) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Bad backedge flow.\n");
    return false;
  }

  // The new, countable, loop will certainly only run a known number of
  // iterations, It won't be infinite. But the old loop might be infinite
  // under certain conditions. For logical shifts, the value will become zero
  // after at most bitwidth(%Val) loop iterations. However, for arithmetic
  // right-shift, iff the sign bit was set, the value will never become zero,
  // and the loop may never finish.
  if (ValShifted->getOpcode() == Instruction::AShr &&
      !isMustProgress(CurLoop) && !SE->isKnownNonNegative(SE->getSCEV(Val))) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE " Can not prove the loop is finite.\n");
    return false;
  }

  // Okay, idiom checks out.
  return true;
}

/// Look for the following loop:
/// \code
///   entry:
///     <...>
///     %start = <...>
///     %extraoffset = <...>
///     <...>
///     br label %for.cond
///
///   loop:
///     %iv = phi i8 [ %start, %entry ], [ %iv.next, %for.cond ]
///     %nbits = add nsw i8 %iv, %extraoffset
///     %val.shifted = {{l,a}shr,shl} i8 %val, %nbits
///     %val.shifted.iszero = icmp eq i8 %val.shifted, 0
///     %iv.next = add i8 %iv, 1
///     <...>
///     br i1 %val.shifted.iszero, label %end, label %loop
///
///   end:
///     %iv.res = phi i8 [ %iv, %loop ] <...>
///     %nbits.res = phi i8 [ %nbits, %loop ] <...>
///     %val.shifted.res = phi i8 [ %val.shifted, %loop ] <...>
///     %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ] <...>
///     %iv.next.res = phi i8 [ %iv.next, %loop ] <...>
///     <...>
/// \endcode
///
/// And transform it into:
/// \code
///   entry:
///     <...>
///     %start = <...>
///     %extraoffset = <...>
///     <...>
///     %val.numleadingzeros = call i8 @llvm.ct{l,t}z.i8(i8 %val, i1 0)
///     %val.numactivebits = sub i8 8, %val.numleadingzeros
///     %extraoffset.neg = sub i8 0, %extraoffset
///     %tmp = add i8 %val.numactivebits, %extraoffset.neg
///     %iv.final = call i8 @llvm.smax.i8(i8 %tmp, i8 %start)
///     %loop.tripcount = sub i8 %iv.final, %start
///     br label %loop
///
///   loop:
///     %loop.iv = phi i8 [ 0, %entry ], [ %loop.iv.next, %loop ]
///     %loop.iv.next = add i8 %loop.iv, 1
///     %loop.ivcheck = icmp eq i8 %loop.iv.next, %loop.tripcount
///     %iv = add i8 %loop.iv, %start
///     <...>
///     br i1 %loop.ivcheck, label %end, label %loop
///
///   end:
///     %iv.res = phi i8 [ %iv.final, %loop ] <...>
///     <...>
/// \endcode
bool LoopIdiomRecognize::recognizeShiftUntilZero() {
  bool MadeChange = false;

  Instruction *ValShiftedIsZero;
  Intrinsic::ID IntrID;
  Instruction *IV;
  Value *Start, *Val;
  const SCEV *ExtraOffsetExpr;
  bool InvertedCond;
  if (!detectShiftUntilZeroIdiom(CurLoop, SE, ValShiftedIsZero, IntrID, IV,
                                 Start, Val, ExtraOffsetExpr, InvertedCond)) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE
               " shift-until-zero idiom detection failed.\n");
    return MadeChange;
  }
  LLVM_DEBUG(dbgs() << DEBUG_TYPE " shift-until-zero idiom detected!\n");

  // Ok, it is the idiom we were looking for, we *could* transform this loop,
  // but is it profitable to transform?

  BasicBlock *LoopHeaderBB = CurLoop->getHeader();
  BasicBlock *LoopPreheaderBB = CurLoop->getLoopPreheader();
  assert(LoopPreheaderBB && "There is always a loop preheader.");

  BasicBlock *SuccessorBB = CurLoop->getExitBlock();
  assert(SuccessorBB && "There is only a single successor.");

  IRBuilder<> Builder(LoopPreheaderBB->getTerminator());
  Builder.SetCurrentDebugLocation(IV->getDebugLoc());

  Type *Ty = Val->getType();
  unsigned Bitwidth = Ty->getScalarSizeInBits();

  TargetTransformInfo::TargetCostKind CostKind =
      TargetTransformInfo::TCK_SizeAndLatency;

  // The rewrite is considered to be unprofitable iff and only iff the
  // intrinsic we'll use are not cheap. Note that we are okay with *just*
  // making the loop countable, even if nothing else changes.
  IntrinsicCostAttributes Attrs(
      IntrID, Ty, {UndefValue::get(Ty), /*is_zero_undef=*/Builder.getFalse()});
  InstructionCost Cost = TTI->getIntrinsicInstrCost(Attrs, CostKind);
  if (Cost > TargetTransformInfo::TCC_Basic) {
    LLVM_DEBUG(dbgs() << DEBUG_TYPE
               " Intrinsic is too costly, not beneficial\n");
    return MadeChange;
  }

  // Ok, transform appears worthwhile.
  MadeChange = true;

  bool OffsetIsZero = false;
  if (auto *ExtraOffsetExprC = dyn_cast<SCEVConstant>(ExtraOffsetExpr))
    OffsetIsZero = ExtraOffsetExprC->isZero();

  // Step 1: Compute the loop's final IV value / trip count.

  CallInst *ValNumLeadingZeros = Builder.CreateIntrinsic(
      IntrID, Ty, {Val, /*is_zero_undef=*/Builder.getFalse()},
      /*FMFSource=*/nullptr, Val->getName() + ".numleadingzeros");
  Value *ValNumActiveBits = Builder.CreateSub(
      ConstantInt::get(Ty, Ty->getScalarSizeInBits()), ValNumLeadingZeros,
      Val->getName() + ".numactivebits", /*HasNUW=*/true,
      /*HasNSW=*/Bitwidth != 2);

  SCEVExpander Expander(*SE, *DL, "loop-idiom");
  Expander.setInsertPoint(&*Builder.GetInsertPoint());
  Value *ExtraOffset = Expander.expandCodeFor(ExtraOffsetExpr);

  Value *ValNumActiveBitsOffset = Builder.CreateAdd(
      ValNumActiveBits, ExtraOffset, ValNumActiveBits->getName() + ".offset",
      /*HasNUW=*/OffsetIsZero, /*HasNSW=*/true);
  Value *IVFinal = Builder.CreateIntrinsic(Intrinsic::smax, {Ty},
                                           {ValNumActiveBitsOffset, Start},
                                           /*FMFSource=*/nullptr, "iv.final");

  auto *LoopBackedgeTakenCount = cast<Instruction>(Builder.CreateSub(
      IVFinal, Start, CurLoop->getName() + ".backedgetakencount",
      /*HasNUW=*/OffsetIsZero, /*HasNSW=*/true));
  // FIXME: or when the offset was `add nuw`

  // We know loop's backedge-taken count, but what's loop's trip count?
  Value *LoopTripCount =
      Builder.CreateAdd(LoopBackedgeTakenCount, ConstantInt::get(Ty, 1),
                        CurLoop->getName() + ".tripcount", /*HasNUW=*/true,
                        /*HasNSW=*/Bitwidth != 2);

  // Step 2: Adjust the successor basic block to recieve the original
  //         induction variable's final value instead of the orig. IV itself.

  IV->replaceUsesOutsideBlock(IVFinal, LoopHeaderBB);

  // Step 3: Rewrite the loop into a countable form, with canonical IV.

  // The new canonical induction variable.
  Builder.SetInsertPoint(&LoopHeaderBB->front());
  auto *CIV = Builder.CreatePHI(Ty, 2, CurLoop->getName() + ".iv");

  // The induction itself.
  Builder.SetInsertPoint(LoopHeaderBB->getFirstNonPHI());
  auto *CIVNext =
      Builder.CreateAdd(CIV, ConstantInt::get(Ty, 1), CIV->getName() + ".next",
                        /*HasNUW=*/true, /*HasNSW=*/Bitwidth != 2);

  // The loop trip count check.
  auto *CIVCheck = Builder.CreateICmpEQ(CIVNext, LoopTripCount,
                                        CurLoop->getName() + ".ivcheck");
  auto *NewIVCheck = CIVCheck;
  if (InvertedCond) {
    NewIVCheck = Builder.CreateNot(CIVCheck);
    NewIVCheck->takeName(ValShiftedIsZero);
  }

  // The original IV, but rebased to be an offset to the CIV.
  auto *IVDePHId = Builder.CreateAdd(CIV, Start, "", /*HasNUW=*/false,
                                     /*HasNSW=*/true); // FIXME: what about NUW?
  IVDePHId->takeName(IV);

  // The loop terminator.
  Builder.SetInsertPoint(LoopHeaderBB->getTerminator());
  Builder.CreateCondBr(CIVCheck, SuccessorBB, LoopHeaderBB);
  LoopHeaderBB->getTerminator()->eraseFromParent();

  // Populate the IV PHI.
  CIV->addIncoming(ConstantInt::get(Ty, 0), LoopPreheaderBB);
  CIV->addIncoming(CIVNext, LoopHeaderBB);

  // Step 4: Forget the "non-computable" trip-count SCEV associated with the
  //   loop. The loop would otherwise not be deleted even if it becomes empty.

  SE->forgetLoop(CurLoop);

  // Step 5: Try to cleanup the loop's body somewhat.
  IV->replaceAllUsesWith(IVDePHId);
  IV->eraseFromParent();

  ValShiftedIsZero->replaceAllUsesWith(NewIVCheck);
  ValShiftedIsZero->eraseFromParent();

  // Other passes will take care of actually deleting the loop if possible.

  LLVM_DEBUG(dbgs() << DEBUG_TYPE " shift-until-zero idiom optimized!\n");

  ++NumShiftUntilZero;
  return MadeChange;
}
