//===- AggressiveInstCombine.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the aggressive expression pattern combiner classes.
// Currently, it handles expression patterns for:
//  * Truncate instruction
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
#include "AggressiveInstCombineInternal.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/ProfDataUtils.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/BuildLibCalls.h"
#include "llvm/Transforms/Utils/Local.h"

using namespace llvm;
using namespace PatternMatch;

#define DEBUG_TYPE "aggressive-instcombine"

namespace llvm {
extern cl::opt<bool> ProfcheckDisableMetadataFixes;
}

STATISTIC(NumAnyOrAllBitsSet, "Number of any/all-bits-set patterns folded");
STATISTIC(NumGuardedRotates,
          "Number of guarded rotates transformed into funnel shifts");
STATISTIC(NumGuardedFunnelShifts,
          "Number of guarded funnel shifts transformed into funnel shifts");
STATISTIC(NumPopCountRecognized, "Number of popcount idioms recognized");

static cl::opt<unsigned> MaxInstrsToScan(
    "aggressive-instcombine-max-scan-instrs", cl::init(64), cl::Hidden,
    cl::desc("Max number of instructions to scan for aggressive instcombine."));

static cl::opt<unsigned> StrNCmpInlineThreshold(
    "strncmp-inline-threshold", cl::init(3), cl::Hidden,
    cl::desc("The maximum length of a constant string for a builtin string cmp "
             "call eligible for inlining. The default value is 3."));

static cl::opt<unsigned>
    MemChrInlineThreshold("memchr-inline-threshold", cl::init(3), cl::Hidden,
                          cl::desc("The maximum length of a constant string to "
                                   "inline a memchr call."));

/// Match a pattern for a bitwise funnel/rotate operation that partially guards
/// against undefined behavior by branching around the funnel-shift/rotation
/// when the shift amount is 0.
static bool foldGuardedFunnelShift(Instruction &I, const DominatorTree &DT) {
  if (I.getOpcode() != Instruction::PHI || I.getNumOperands() != 2)
    return false;

  // As with the one-use checks below, this is not strictly necessary, but we
  // are being cautious to avoid potential perf regressions on targets that
  // do not actually have a funnel/rotate instruction (where the funnel shift
  // would be expanded back into math/shift/logic ops).
  if (!isPowerOf2_32(I.getType()->getScalarSizeInBits()))
    return false;

  // Match V to funnel shift left/right and capture the source operands and
  // shift amount.
  auto matchFunnelShift = [](Value *V, Value *&ShVal0, Value *&ShVal1,
                             Value *&ShAmt) {
    unsigned Width = V->getType()->getScalarSizeInBits();

    // fshl(ShVal0, ShVal1, ShAmt)
    //  == (ShVal0 << ShAmt) | (ShVal1 >> (Width -ShAmt))
    if (match(V, m_OneUse(m_c_Or(
                     m_Shl(m_Value(ShVal0), m_Value(ShAmt)),
                     m_LShr(m_Value(ShVal1), m_Sub(m_SpecificInt(Width),
                                                   m_Deferred(ShAmt))))))) {
      return Intrinsic::fshl;
    }

    // fshr(ShVal0, ShVal1, ShAmt)
    //  == (ShVal0 >> ShAmt) | (ShVal1 << (Width - ShAmt))
    if (match(V,
              m_OneUse(m_c_Or(m_Shl(m_Value(ShVal0), m_Sub(m_SpecificInt(Width),
                                                           m_Value(ShAmt))),
                              m_LShr(m_Value(ShVal1), m_Deferred(ShAmt)))))) {
      return Intrinsic::fshr;
    }

    return Intrinsic::not_intrinsic;
  };

  // One phi operand must be a funnel/rotate operation, and the other phi
  // operand must be the source value of that funnel/rotate operation:
  // phi [ rotate(RotSrc, ShAmt), FunnelBB ], [ RotSrc, GuardBB ]
  // phi [ fshl(ShVal0, ShVal1, ShAmt), FunnelBB ], [ ShVal0, GuardBB ]
  // phi [ fshr(ShVal0, ShVal1, ShAmt), FunnelBB ], [ ShVal1, GuardBB ]
  PHINode &Phi = cast<PHINode>(I);
  unsigned FunnelOp = 0, GuardOp = 1;
  Value *P0 = Phi.getOperand(0), *P1 = Phi.getOperand(1);
  Value *ShVal0, *ShVal1, *ShAmt;
  Intrinsic::ID IID = matchFunnelShift(P0, ShVal0, ShVal1, ShAmt);
  if (IID == Intrinsic::not_intrinsic ||
      (IID == Intrinsic::fshl && ShVal0 != P1) ||
      (IID == Intrinsic::fshr && ShVal1 != P1)) {
    IID = matchFunnelShift(P1, ShVal0, ShVal1, ShAmt);
    if (IID == Intrinsic::not_intrinsic ||
        (IID == Intrinsic::fshl && ShVal0 != P0) ||
        (IID == Intrinsic::fshr && ShVal1 != P0))
      return false;
    assert((IID == Intrinsic::fshl || IID == Intrinsic::fshr) &&
           "Pattern must match funnel shift left or right");
    std::swap(FunnelOp, GuardOp);
  }

  // The incoming block with our source operand must be the "guard" block.
  // That must contain a cmp+branch to avoid the funnel/rotate when the shift
  // amount is equal to 0. The other incoming block is the block with the
  // funnel/rotate.
  BasicBlock *GuardBB = Phi.getIncomingBlock(GuardOp);
  BasicBlock *FunnelBB = Phi.getIncomingBlock(FunnelOp);
  Instruction *TermI = GuardBB->getTerminator();

  // Ensure that the shift values dominate each block.
  if (!DT.dominates(ShVal0, TermI) || !DT.dominates(ShVal1, TermI))
    return false;

  BasicBlock *PhiBB = Phi.getParent();
  if (!match(TermI, m_Br(m_SpecificICmp(CmpInst::ICMP_EQ, m_Specific(ShAmt),
                                        m_ZeroInt()),
                         m_SpecificBB(PhiBB), m_SpecificBB(FunnelBB))))
    return false;

  IRBuilder<> Builder(PhiBB, PhiBB->getFirstInsertionPt());

  if (ShVal0 == ShVal1)
    ++NumGuardedRotates;
  else
    ++NumGuardedFunnelShifts;

  // If this is not a rotate then the select was blocking poison from the
  // 'shift-by-zero' non-TVal, but a funnel shift won't - so freeze it.
  bool IsFshl = IID == Intrinsic::fshl;
  if (ShVal0 != ShVal1) {
    if (IsFshl && !llvm::isGuaranteedNotToBePoison(ShVal1))
      ShVal1 = Builder.CreateFreeze(ShVal1);
    else if (!IsFshl && !llvm::isGuaranteedNotToBePoison(ShVal0))
      ShVal0 = Builder.CreateFreeze(ShVal0);
  }

  // We matched a variation of this IR pattern:
  // GuardBB:
  //   %cmp = icmp eq i32 %ShAmt, 0
  //   br i1 %cmp, label %PhiBB, label %FunnelBB
  // FunnelBB:
  //   %sub = sub i32 32, %ShAmt
  //   %shr = lshr i32 %ShVal1, %sub
  //   %shl = shl i32 %ShVal0, %ShAmt
  //   %fsh = or i32 %shr, %shl
  //   br label %PhiBB
  // PhiBB:
  //   %cond = phi i32 [ %fsh, %FunnelBB ], [ %ShVal0, %GuardBB ]
  // -->
  // llvm.fshl.i32(i32 %ShVal0, i32 %ShVal1, i32 %ShAmt)
  Phi.replaceAllUsesWith(
      Builder.CreateIntrinsic(IID, Phi.getType(), {ShVal0, ShVal1, ShAmt}));
  return true;
}

/// This is used by foldAnyOrAllBitsSet() to capture a source value (Root) and
/// the bit indexes (Mask) needed by a masked compare. If we're matching a chain
/// of 'and' ops, then we also need to capture the fact that we saw an
/// "and X, 1", so that's an extra return value for that case.
namespace {
struct MaskOps {
  Value *Root = nullptr;
  APInt Mask;
  bool MatchAndChain;
  bool FoundAnd1 = false;

  MaskOps(unsigned BitWidth, bool MatchAnds)
      : Mask(APInt::getZero(BitWidth)), MatchAndChain(MatchAnds) {}
};
} // namespace

/// This is a recursive helper for foldAnyOrAllBitsSet() that walks through a
/// chain of 'and' or 'or' instructions looking for shift ops of a common source
/// value. Examples:
///   or (or (or X, (X >> 3)), (X >> 5)), (X >> 8)
/// returns { X, 0x129 }
///   and (and (X >> 1), 1), (X >> 4)
/// returns { X, 0x12 }
static bool matchAndOrChain(Value *V, MaskOps &MOps) {
  Value *Op0, *Op1;
  if (MOps.MatchAndChain) {
    // Recurse through a chain of 'and' operands. This requires an extra check
    // vs. the 'or' matcher: we must find an "and X, 1" instruction somewhere
    // in the chain to know that all of the high bits are cleared.
    if (match(V, m_And(m_Value(Op0), m_One()))) {
      MOps.FoundAnd1 = true;
      return matchAndOrChain(Op0, MOps);
    }
    if (match(V, m_And(m_Value(Op0), m_Value(Op1))))
      return matchAndOrChain(Op0, MOps) && matchAndOrChain(Op1, MOps);
  } else {
    // Recurse through a chain of 'or' operands.
    if (match(V, m_Or(m_Value(Op0), m_Value(Op1))))
      return matchAndOrChain(Op0, MOps) && matchAndOrChain(Op1, MOps);
  }

  // We need a shift-right or a bare value representing a compare of bit 0 of
  // the original source operand.
  Value *Candidate;
  const APInt *BitIndex = nullptr;
  if (!match(V, m_LShr(m_Value(Candidate), m_APInt(BitIndex))))
    Candidate = V;

  // Initialize result source operand.
  if (!MOps.Root)
    MOps.Root = Candidate;

  // The shift constant is out-of-range? This code hasn't been simplified.
  if (BitIndex && BitIndex->uge(MOps.Mask.getBitWidth()))
    return false;

  // Fill in the mask bit derived from the shift constant.
  MOps.Mask.setBit(BitIndex ? BitIndex->getZExtValue() : 0);
  return MOps.Root == Candidate;
}

/// Match patterns that correspond to "any-bits-set" and "all-bits-set".
/// These will include a chain of 'or' or 'and'-shifted bits from a
/// common source value:
/// and (or  (lshr X, C), ...), 1 --> (X & CMask) != 0
/// and (and (lshr X, C), ...), 1 --> (X & CMask) == CMask
/// Note: "any-bits-clear" and "all-bits-clear" are variations of these patterns
/// that differ only with a final 'not' of the result. We expect that final
/// 'not' to be folded with the compare that we create here (invert predicate).
static bool foldAnyOrAllBitsSet(Instruction &I) {
  // The 'any-bits-set' ('or' chain) pattern is simpler to match because the
  // final "and X, 1" instruction must be the final op in the sequence.
  bool MatchAllBitsSet;
  if (match(&I, m_c_And(m_OneUse(m_And(m_Value(), m_Value())), m_Value())))
    MatchAllBitsSet = true;
  else if (match(&I, m_And(m_OneUse(m_Or(m_Value(), m_Value())), m_One())))
    MatchAllBitsSet = false;
  else
    return false;

  MaskOps MOps(I.getType()->getScalarSizeInBits(), MatchAllBitsSet);
  if (MatchAllBitsSet) {
    if (!matchAndOrChain(cast<BinaryOperator>(&I), MOps) || !MOps.FoundAnd1)
      return false;
  } else {
    if (!matchAndOrChain(cast<BinaryOperator>(&I)->getOperand(0), MOps))
      return false;
  }

  // The pattern was found. Create a masked compare that replaces all of the
  // shift and logic ops.
  IRBuilder<> Builder(&I);
  Constant *Mask = ConstantInt::get(I.getType(), MOps.Mask);
  Value *And = Builder.CreateAnd(MOps.Root, Mask);
  Value *Cmp = MatchAllBitsSet ? Builder.CreateICmpEQ(And, Mask)
                               : Builder.CreateIsNotNull(And);
  Value *Zext = Builder.CreateZExt(Cmp, I.getType());
  I.replaceAllUsesWith(Zext);
  ++NumAnyOrAllBitsSet;
  return true;
}

// Try to recognize below function as popcount intrinsic.
// This is the "best" algorithm from
// http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
// Also used in TargetLowering::expandCTPOP().
//
// int popcount(unsigned int i) {
//   i = i - ((i >> 1) & 0x55555555);
//   i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
//   i = ((i + (i >> 4)) & 0x0F0F0F0F);
//   return (i * 0x01010101) >> 24;
// }
static bool tryToRecognizePopCount(Instruction &I) {
  if (I.getOpcode() != Instruction::LShr)
    return false;

  Type *Ty = I.getType();
  if (!Ty->isIntOrIntVectorTy())
    return false;

  unsigned Len = Ty->getScalarSizeInBits();
  // FIXME: fix Len == 8 and other irregular type lengths.
  if (!(Len <= 128 && Len > 8 && Len % 8 == 0))
    return false;

  APInt Mask55 = APInt::getSplat(Len, APInt(8, 0x55));
  APInt Mask33 = APInt::getSplat(Len, APInt(8, 0x33));
  APInt Mask0F = APInt::getSplat(Len, APInt(8, 0x0F));
  APInt Mask01 = APInt::getSplat(Len, APInt(8, 0x01));
  APInt MaskShift = APInt(Len, Len - 8);

  Value *Op0 = I.getOperand(0);
  Value *Op1 = I.getOperand(1);
  Value *MulOp0;
  // Matching "(i * 0x01010101...) >> 24".
  if ((match(Op0, m_Mul(m_Value(MulOp0), m_SpecificInt(Mask01)))) &&
      match(Op1, m_SpecificInt(MaskShift))) {
    Value *ShiftOp0;
    // Matching "((i + (i >> 4)) & 0x0F0F0F0F...)".
    if (match(MulOp0, m_And(m_c_Add(m_LShr(m_Value(ShiftOp0), m_SpecificInt(4)),
                                    m_Deferred(ShiftOp0)),
                            m_SpecificInt(Mask0F)))) {
      Value *AndOp0;
      // Matching "(i & 0x33333333...) + ((i >> 2) & 0x33333333...)".
      if (match(ShiftOp0,
                m_c_Add(m_And(m_Value(AndOp0), m_SpecificInt(Mask33)),
                        m_And(m_LShr(m_Deferred(AndOp0), m_SpecificInt(2)),
                              m_SpecificInt(Mask33))))) {
        Value *Root, *SubOp1;
        // Matching "i - ((i >> 1) & 0x55555555...)".
        const APInt *AndMask;
        if (match(AndOp0, m_Sub(m_Value(Root), m_Value(SubOp1))) &&
            match(SubOp1, m_And(m_LShr(m_Specific(Root), m_SpecificInt(1)),
                                m_APInt(AndMask)))) {
          auto CheckAndMask = [&]() {
            if (*AndMask == Mask55)
              return true;

            // Exact match failed, see if any bits are known to be 0 where we
            // expect a 1 in the mask.
            if (!AndMask->isSubsetOf(Mask55))
              return false;

            APInt NeededMask = Mask55 & ~*AndMask;
            return MaskedValueIsZero(cast<Instruction>(SubOp1)->getOperand(0),
                                     NeededMask,
                                     SimplifyQuery(I.getDataLayout()));
          };

          if (CheckAndMask()) {
            LLVM_DEBUG(dbgs() << "Recognized popcount intrinsic\n");
            IRBuilder<> Builder(&I);
            I.replaceAllUsesWith(
                Builder.CreateIntrinsic(Intrinsic::ctpop, I.getType(), {Root}));
            ++NumPopCountRecognized;
            return true;
          }
        }
      }
    }
  }

  return false;
}

/// Fold smin(smax(fptosi(x), C1), C2) to llvm.fptosi.sat(x), providing C1 and
/// C2 saturate the value of the fp conversion. The transform is not reversable
/// as the fptosi.sat is more defined than the input - all values produce a
/// valid value for the fptosi.sat, where as some produce poison for original
/// that were out of range of the integer conversion. The reversed pattern may
/// use fmax and fmin instead. As we cannot directly reverse the transform, and
/// it is not always profitable, we make it conditional on the cost being
/// reported as lower by TTI.
static bool tryToFPToSat(Instruction &I, TargetTransformInfo &TTI) {
  // Look for min(max(fptosi, converting to fptosi_sat.
  Value *In;
  const APInt *MinC, *MaxC;
  if (!match(&I, m_SMax(m_OneUse(m_SMin(m_OneUse(m_FPToSI(m_Value(In))),
                                        m_APInt(MinC))),
                        m_APInt(MaxC))) &&
      !match(&I, m_SMin(m_OneUse(m_SMax(m_OneUse(m_FPToSI(m_Value(In))),
                                        m_APInt(MaxC))),
                        m_APInt(MinC))))
    return false;

  // Check that the constants clamp a saturate.
  if (!(*MinC + 1).isPowerOf2() || -*MaxC != *MinC + 1)
    return false;

  Type *IntTy = I.getType();
  Type *FpTy = In->getType();
  Type *SatTy =
      IntegerType::get(IntTy->getContext(), (*MinC + 1).exactLogBase2() + 1);
  if (auto *VecTy = dyn_cast<VectorType>(IntTy))
    SatTy = VectorType::get(SatTy, VecTy->getElementCount());

  // Get the cost of the intrinsic, and check that against the cost of
  // fptosi+smin+smax
  InstructionCost SatCost = TTI.getIntrinsicInstrCost(
      IntrinsicCostAttributes(Intrinsic::fptosi_sat, SatTy, {In}, {FpTy}),
      TTI::TCK_RecipThroughput);
  SatCost += TTI.getCastInstrCost(Instruction::SExt, IntTy, SatTy,
                                  TTI::CastContextHint::None,
                                  TTI::TCK_RecipThroughput);

  InstructionCost MinMaxCost = TTI.getCastInstrCost(
      Instruction::FPToSI, IntTy, FpTy, TTI::CastContextHint::None,
      TTI::TCK_RecipThroughput);
  MinMaxCost += TTI.getIntrinsicInstrCost(
      IntrinsicCostAttributes(Intrinsic::smin, IntTy, {IntTy}),
      TTI::TCK_RecipThroughput);
  MinMaxCost += TTI.getIntrinsicInstrCost(
      IntrinsicCostAttributes(Intrinsic::smax, IntTy, {IntTy}),
      TTI::TCK_RecipThroughput);

  if (SatCost >= MinMaxCost)
    return false;

  IRBuilder<> Builder(&I);
  Value *Sat =
      Builder.CreateIntrinsic(Intrinsic::fptosi_sat, {SatTy, FpTy}, In);
  I.replaceAllUsesWith(Builder.CreateSExt(Sat, IntTy));
  return true;
}

/// Try to replace a mathlib call to sqrt with the LLVM intrinsic. This avoids
/// pessimistic codegen that has to account for setting errno and can enable
/// vectorization.
static bool foldSqrt(CallInst *Call, LibFunc Func, TargetTransformInfo &TTI,
                     TargetLibraryInfo &TLI, AssumptionCache &AC,
                     DominatorTree &DT) {
  // If (1) this is a sqrt libcall, (2) we can assume that NAN is not created
  // (because NNAN or the operand arg must not be less than -0.0) and (2) we
  // would not end up lowering to a libcall anyway (which could change the value
  // of errno), then:
  // (1) errno won't be set.
  // (2) it is safe to convert this to an intrinsic call.
  Type *Ty = Call->getType();
  Value *Arg = Call->getArgOperand(0);
  if (TTI.haveFastSqrt(Ty) &&
      (Call->hasNoNaNs() ||
       cannotBeOrderedLessThanZero(
           Arg, SimplifyQuery(Call->getDataLayout(), &TLI, &DT, &AC, Call)))) {
    IRBuilder<> Builder(Call);
    Value *NewSqrt =
        Builder.CreateIntrinsic(Intrinsic::sqrt, Ty, Arg, Call, "sqrt");
    Call->replaceAllUsesWith(NewSqrt);

    // Explicitly erase the old call because a call with side effects is not
    // trivially dead.
    Call->eraseFromParent();
    return true;
  }

  return false;
}

// Check if this array of constants represents a cttz table.
// Iterate over the elements from \p Table by trying to find/match all
// the numbers from 0 to \p InputBits that should represent cttz results.
static bool isCTTZTable(Constant *Table, const APInt &Mul, const APInt &Shift,
                        const APInt &AndMask, Type *AccessTy,
                        unsigned InputBits, const APInt &GEPIdxFactor,
                        const DataLayout &DL) {
  for (unsigned Idx = 0; Idx < InputBits; Idx++) {
    APInt Index = (APInt(InputBits, 1).shl(Idx) * Mul).lshr(Shift) & AndMask;
    ConstantInt *C = dyn_cast_or_null<ConstantInt>(
        ConstantFoldLoadFromConst(Table, AccessTy, Index * GEPIdxFactor, DL));
    if (!C || C->getValue() != Idx)
      return false;
  }

  return true;
}

// Try to recognize table-based ctz implementation.
// E.g., an example in C (for more cases please see the llvm/tests):
// int f(unsigned x) {
//    static const char table[32] =
//      {0, 1, 28, 2, 29, 14, 24, 3, 30,
//       22, 20, 15, 25, 17, 4, 8, 31, 27,
//       13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
//    return table[((unsigned)((x & -x) * 0x077CB531U)) >> 27];
// }
// this can be lowered to `cttz` instruction.
// There is also a special case when the element is 0.
//
// The (x & -x) sets the lowest non-zero bit to 1. The multiply is a de-bruijn
// sequence that contains each pattern of bits in it. The shift extracts
// the top bits after the multiply, and that index into the table should
// represent the number of trailing zeros in the original number.
//
// Here are some examples or LLVM IR for a 64-bit target:
//
// CASE 1:
// %sub = sub i32 0, %x
// %and = and i32 %sub, %x
// %mul = mul i32 %and, 125613361
// %shr = lshr i32 %mul, 27
// %idxprom = zext i32 %shr to i64
// %arrayidx = getelementptr inbounds [32 x i8], [32 x i8]* @ctz1.table, i64 0,
//     i64 %idxprom
// %0 = load i8, i8* %arrayidx, align 1, !tbaa !8
//
// CASE 2:
// %sub = sub i32 0, %x
// %and = and i32 %sub, %x
// %mul = mul i32 %and, 72416175
// %shr = lshr i32 %mul, 26
// %idxprom = zext i32 %shr to i64
// %arrayidx = getelementptr inbounds [64 x i16], [64 x i16]* @ctz2.table,
//     i64 0, i64 %idxprom
// %0 = load i16, i16* %arrayidx, align 2, !tbaa !8
//
// CASE 3:
// %sub = sub i32 0, %x
// %and = and i32 %sub, %x
// %mul = mul i32 %and, 81224991
// %shr = lshr i32 %mul, 27
// %idxprom = zext i32 %shr to i64
// %arrayidx = getelementptr inbounds [32 x i32], [32 x i32]* @ctz3.table,
//     i64 0, i64 %idxprom
// %0 = load i32, i32* %arrayidx, align 4, !tbaa !8
//
// CASE 4:
// %sub = sub i64 0, %x
// %and = and i64 %sub, %x
// %mul = mul i64 %and, 283881067100198605
// %shr = lshr i64 %mul, 58
// %arrayidx = getelementptr inbounds [64 x i8], [64 x i8]* @table, i64 0,
//     i64 %shr
// %0 = load i8, i8* %arrayidx, align 1, !tbaa !8
//
// All these can be lowered to @llvm.cttz.i32/64 intrinsics.
static bool tryToRecognizeTableBasedCttz(Instruction &I, const DataLayout &DL) {
  LoadInst *LI = dyn_cast<LoadInst>(&I);
  if (!LI)
    return false;

  Type *AccessType = LI->getType();
  if (!AccessType->isIntegerTy())
    return false;

  GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(LI->getPointerOperand());
  if (!GEP || !GEP->hasNoUnsignedSignedWrap())
    return false;

  GlobalVariable *GVTable = dyn_cast<GlobalVariable>(GEP->getPointerOperand());
  if (!GVTable || !GVTable->hasInitializer() || !GVTable->isConstant())
    return false;

  unsigned BW = DL.getIndexTypeSizeInBits(GEP->getType());
  APInt ModOffset(BW, 0);
  SmallMapVector<Value *, APInt, 4> VarOffsets;
  if (!GEP->collectOffset(DL, BW, VarOffsets, ModOffset) ||
      VarOffsets.size() != 1 || ModOffset != 0)
    return false;
  auto [GepIdx, GEPScale] = VarOffsets.front();

  Value *X1;
  const APInt *MulConst, *ShiftConst, *AndCst = nullptr;
  // Check that the gep variable index is ((x & -x) * MulConst) >> ShiftConst.
  // This might be extended to the pointer index type, and if the gep index type
  // has been replaced with an i8 then a new And (and different ShiftConst) will
  // be present.
  auto MatchInner = m_LShr(
      m_Mul(m_c_And(m_Neg(m_Value(X1)), m_Deferred(X1)), m_APInt(MulConst)),
      m_APInt(ShiftConst));
  if (!match(GepIdx, m_CastOrSelf(MatchInner)) &&
      !match(GepIdx, m_CastOrSelf(m_And(MatchInner, m_APInt(AndCst)))))
    return false;

  unsigned InputBits = X1->getType()->getScalarSizeInBits();
  if (InputBits != 16 && InputBits != 32 && InputBits != 64 && InputBits != 128)
    return false;

  if (!GEPScale.isIntN(InputBits) ||
      !isCTTZTable(GVTable->getInitializer(), *MulConst, *ShiftConst,
                   AndCst ? *AndCst : APInt::getAllOnes(InputBits), AccessType,
                   InputBits, GEPScale.zextOrTrunc(InputBits), DL))
    return false;

  ConstantInt *ZeroTableElem = cast<ConstantInt>(
      ConstantFoldLoadFromConst(GVTable->getInitializer(), AccessType, DL));
  bool DefinedForZero = ZeroTableElem->getZExtValue() == InputBits;

  IRBuilder<> B(LI);
  ConstantInt *BoolConst = B.getInt1(!DefinedForZero);
  Type *XType = X1->getType();
  auto Cttz = B.CreateIntrinsic(Intrinsic::cttz, {XType}, {X1, BoolConst});
  Value *ZExtOrTrunc = nullptr;

  if (DefinedForZero) {
    ZExtOrTrunc = B.CreateZExtOrTrunc(Cttz, AccessType);
  } else {
    // If the value in elem 0 isn't the same as InputBits, we still want to
    // produce the value from the table.
    auto Cmp = B.CreateICmpEQ(X1, ConstantInt::get(XType, 0));
    auto Select = B.CreateSelect(Cmp, B.CreateZExt(ZeroTableElem, XType), Cttz);

    // The true branch of select handles the cttz(0) case, which is rare.
    if (!ProfcheckDisableMetadataFixes) {
      if (Instruction *SelectI = dyn_cast<Instruction>(Select))
        SelectI->setMetadata(
            LLVMContext::MD_prof,
            MDBuilder(SelectI->getContext()).createUnlikelyBranchWeights());
    }

    // NOTE: If the table[0] is 0, but the cttz(0) is defined by the Target
    // it should be handled as: `cttz(x) & (typeSize - 1)`.

    ZExtOrTrunc = B.CreateZExtOrTrunc(Select, AccessType);
  }

  LI->replaceAllUsesWith(ZExtOrTrunc);

  return true;
}

/// This is used by foldLoadsRecursive() to capture a Root Load node which is
/// of type or(load, load) and recursively build the wide load. Also capture the
/// shift amount, zero extend type and loadSize.
struct LoadOps {
  LoadInst *Root = nullptr;
  LoadInst *RootInsert = nullptr;
  bool FoundRoot = false;
  uint64_t LoadSize = 0;
  uint64_t Shift = 0;
  Type *ZextType;
  AAMDNodes AATags;
};

// Identify and Merge consecutive loads recursively which is of the form
// (ZExt(L1) << shift1) | (ZExt(L2) << shift2) -> ZExt(L3) << shift1
// (ZExt(L1) << shift1) | ZExt(L2) -> ZExt(L3)
static bool foldLoadsRecursive(Value *V, LoadOps &LOps, const DataLayout &DL,
                               AliasAnalysis &AA) {
  uint64_t ShAmt2;
  Value *X;
  Instruction *L1, *L2;

  // Go to the last node with loads.
  if (match(V,
            m_OneUse(m_c_Or(m_Value(X), m_OneUse(m_ShlOrSelf(
                                            m_OneUse(m_ZExt(m_Instruction(L2))),
                                            ShAmt2)))))) {
    if (!foldLoadsRecursive(X, LOps, DL, AA) && LOps.FoundRoot)
      // Avoid Partial chain merge.
      return false;
  } else
    return false;

  // Check if the pattern has loads
  LoadInst *LI1 = LOps.Root;
  uint64_t ShAmt1 = LOps.Shift;
  if (LOps.FoundRoot == false &&
      match(X, m_OneUse(
                   m_ShlOrSelf(m_OneUse(m_ZExt(m_Instruction(L1))), ShAmt1)))) {
    LI1 = dyn_cast<LoadInst>(L1);
  }
  LoadInst *LI2 = dyn_cast<LoadInst>(L2);

  // Check if loads are same, atomic, volatile and having same address space.
  if (LI1 == LI2 || !LI1 || !LI2 || !LI1->isSimple() || !LI2->isSimple() ||
      LI1->getPointerAddressSpace() != LI2->getPointerAddressSpace())
    return false;

  // Check if Loads come from same BB.
  if (LI1->getParent() != LI2->getParent())
    return false;

  // Find the data layout
  bool IsBigEndian = DL.isBigEndian();

  // Check if loads are consecutive and same size.
  Value *Load1Ptr = LI1->getPointerOperand();
  APInt Offset1(DL.getIndexTypeSizeInBits(Load1Ptr->getType()), 0);
  Load1Ptr =
      Load1Ptr->stripAndAccumulateConstantOffsets(DL, Offset1,
                                                  /* AllowNonInbounds */ true);

  Value *Load2Ptr = LI2->getPointerOperand();
  APInt Offset2(DL.getIndexTypeSizeInBits(Load2Ptr->getType()), 0);
  Load2Ptr =
      Load2Ptr->stripAndAccumulateConstantOffsets(DL, Offset2,
                                                  /* AllowNonInbounds */ true);

  // Verify if both loads have same base pointers
  uint64_t LoadSize1 = LI1->getType()->getPrimitiveSizeInBits();
  uint64_t LoadSize2 = LI2->getType()->getPrimitiveSizeInBits();
  if (Load1Ptr != Load2Ptr)
    return false;

  // Make sure that there are no padding bits.
  if (!DL.typeSizeEqualsStoreSize(LI1->getType()) ||
      !DL.typeSizeEqualsStoreSize(LI2->getType()))
    return false;

  // Alias Analysis to check for stores b/w the loads.
  LoadInst *Start = LOps.FoundRoot ? LOps.RootInsert : LI1, *End = LI2;
  MemoryLocation Loc;
  if (!Start->comesBefore(End)) {
    std::swap(Start, End);
    // If LOps.RootInsert comes after LI2, since we use LI2 as the new insert
    // point, we should make sure whether the memory region accessed by LOps
    // isn't modified.
    if (LOps.FoundRoot)
      Loc = MemoryLocation(
          LOps.Root->getPointerOperand(),
          LocationSize::precise(DL.getTypeStoreSize(
              IntegerType::get(LI1->getContext(), LOps.LoadSize))),
          LOps.AATags);
    else
      Loc = MemoryLocation::get(End);
  } else
    Loc = MemoryLocation::get(End);
  unsigned NumScanned = 0;
  for (Instruction &Inst :
       make_range(Start->getIterator(), End->getIterator())) {
    if (Inst.mayWriteToMemory() && isModSet(AA.getModRefInfo(&Inst, Loc)))
      return false;

    if (++NumScanned > MaxInstrsToScan)
      return false;
  }

  // Make sure Load with lower Offset is at LI1
  bool Reverse = false;
  if (Offset2.slt(Offset1)) {
    std::swap(LI1, LI2);
    std::swap(ShAmt1, ShAmt2);
    std::swap(Offset1, Offset2);
    std::swap(Load1Ptr, Load2Ptr);
    std::swap(LoadSize1, LoadSize2);
    Reverse = true;
  }

  // Big endian swap the shifts
  if (IsBigEndian)
    std::swap(ShAmt1, ShAmt2);

  // First load is always LI1. This is where we put the new load.
  // Use the merged load size available from LI1 for forward loads.
  if (LOps.FoundRoot) {
    if (!Reverse)
      LoadSize1 = LOps.LoadSize;
    else
      LoadSize2 = LOps.LoadSize;
  }

  // Verify if shift amount and load index aligns and verifies that loads
  // are consecutive.
  uint64_t ShiftDiff = IsBigEndian ? LoadSize2 : LoadSize1;
  uint64_t PrevSize =
      DL.getTypeStoreSize(IntegerType::get(LI1->getContext(), LoadSize1));
  if ((ShAmt2 - ShAmt1) != ShiftDiff || (Offset2 - Offset1) != PrevSize)
    return false;

  // Update LOps
  AAMDNodes AATags1 = LOps.AATags;
  AAMDNodes AATags2 = LI2->getAAMetadata();
  if (LOps.FoundRoot == false) {
    LOps.FoundRoot = true;
    AATags1 = LI1->getAAMetadata();
  }
  LOps.LoadSize = LoadSize1 + LoadSize2;
  LOps.RootInsert = Start;

  // Concatenate the AATags of the Merged Loads.
  LOps.AATags = AATags1.concat(AATags2);

  LOps.Root = LI1;
  LOps.Shift = ShAmt1;
  LOps.ZextType = X->getType();
  return true;
}

// For a given BB instruction, evaluate all loads in the chain that form a
// pattern which suggests that the loads can be combined. The one and only use
// of the loads is to form a wider load.
static bool foldConsecutiveLoads(Instruction &I, const DataLayout &DL,
                                 TargetTransformInfo &TTI, AliasAnalysis &AA,
                                 const DominatorTree &DT) {
  // Only consider load chains of scalar values.
  if (isa<VectorType>(I.getType()))
    return false;

  LoadOps LOps;
  if (!foldLoadsRecursive(&I, LOps, DL, AA) || !LOps.FoundRoot)
    return false;

  IRBuilder<> Builder(&I);
  LoadInst *NewLoad = nullptr, *LI1 = LOps.Root;

  IntegerType *WiderType = IntegerType::get(I.getContext(), LOps.LoadSize);
  // TTI based checks if we want to proceed with wider load
  bool Allowed = TTI.isTypeLegal(WiderType);
  if (!Allowed)
    return false;

  unsigned AS = LI1->getPointerAddressSpace();
  unsigned Fast = 0;
  Allowed = TTI.allowsMisalignedMemoryAccesses(I.getContext(), LOps.LoadSize,
                                               AS, LI1->getAlign(), &Fast);
  if (!Allowed || !Fast)
    return false;

  // Get the Index and Ptr for the new GEP.
  Value *Load1Ptr = LI1->getPointerOperand();
  Builder.SetInsertPoint(LOps.RootInsert);
  if (!DT.dominates(Load1Ptr, LOps.RootInsert)) {
    APInt Offset1(DL.getIndexTypeSizeInBits(Load1Ptr->getType()), 0);
    Load1Ptr = Load1Ptr->stripAndAccumulateConstantOffsets(
        DL, Offset1, /* AllowNonInbounds */ true);
    Load1Ptr = Builder.CreatePtrAdd(Load1Ptr, Builder.getInt(Offset1));
  }
  // Generate wider load.
  NewLoad = Builder.CreateAlignedLoad(WiderType, Load1Ptr, LI1->getAlign(),
                                      LI1->isVolatile(), "");
  NewLoad->takeName(LI1);
  // Set the New Load AATags Metadata.
  if (LOps.AATags)
    NewLoad->setAAMetadata(LOps.AATags);

  Value *NewOp = NewLoad;
  // Check if zero extend needed.
  if (LOps.ZextType)
    NewOp = Builder.CreateZExt(NewOp, LOps.ZextType);

  // Check if shift needed. We need to shift with the amount of load1
  // shift if not zero.
  if (LOps.Shift)
    NewOp = Builder.CreateShl(NewOp, LOps.Shift);
  I.replaceAllUsesWith(NewOp);

  return true;
}

/// ValWidth bits starting at ValOffset of Val stored at PtrBase+PtrOffset.
struct PartStore {
  Value *PtrBase;
  APInt PtrOffset;
  Value *Val;
  uint64_t ValOffset;
  uint64_t ValWidth;
  StoreInst *Store;

  bool isCompatibleWith(const PartStore &Other) const {
    return PtrBase == Other.PtrBase && Val == Other.Val;
  }

  bool operator<(const PartStore &Other) const {
    return PtrOffset.slt(Other.PtrOffset);
  }
};

static std::optional<PartStore> matchPartStore(Instruction &I,
                                               const DataLayout &DL) {
  auto *Store = dyn_cast<StoreInst>(&I);
  if (!Store || !Store->isSimple())
    return std::nullopt;

  Value *StoredVal = Store->getValueOperand();
  Type *StoredTy = StoredVal->getType();
  if (!StoredTy->isIntegerTy() || !DL.typeSizeEqualsStoreSize(StoredTy))
    return std::nullopt;

  uint64_t ValWidth = StoredTy->getPrimitiveSizeInBits();
  uint64_t ValOffset;
  Value *Val;
  if (!match(StoredVal, m_Trunc(m_LShrOrSelf(m_Value(Val), ValOffset))))
    return std::nullopt;

  Value *Ptr = Store->getPointerOperand();
  APInt PtrOffset(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
  Value *PtrBase = Ptr->stripAndAccumulateConstantOffsets(
      DL, PtrOffset, /*AllowNonInbounds=*/true);
  return {{PtrBase, PtrOffset, Val, ValOffset, ValWidth, Store}};
}

static bool mergeConsecutivePartStores(ArrayRef<PartStore> Parts,
                                       unsigned Width, const DataLayout &DL,
                                       TargetTransformInfo &TTI) {
  if (Parts.size() < 2)
    return false;

  // Check whether combining the stores is profitable.
  // FIXME: We could generate smaller stores if we can't produce a large one.
  const PartStore &First = Parts.front();
  LLVMContext &Ctx = First.Store->getContext();
  Type *NewTy = Type::getIntNTy(Ctx, Width);
  unsigned Fast = 0;
  if (!TTI.isTypeLegal(NewTy) ||
      !TTI.allowsMisalignedMemoryAccesses(Ctx, Width,
                                          First.Store->getPointerAddressSpace(),
                                          First.Store->getAlign(), &Fast) ||
      !Fast)
    return false;

  // Generate the combined store.
  IRBuilder<> Builder(First.Store);
  Value *Val = First.Val;
  if (First.ValOffset != 0)
    Val = Builder.CreateLShr(Val, First.ValOffset);
  Val = Builder.CreateZExtOrTrunc(Val, NewTy);
  StoreInst *Store = Builder.CreateAlignedStore(
      Val, First.Store->getPointerOperand(), First.Store->getAlign());

  // Merge various metadata onto the new store.
  AAMDNodes AATags = First.Store->getAAMetadata();
  SmallVector<Instruction *> Stores = {First.Store};
  Stores.reserve(Parts.size());
  SmallVector<DebugLoc> DbgLocs = {First.Store->getDebugLoc()};
  DbgLocs.reserve(Parts.size());
  for (const PartStore &Part : drop_begin(Parts)) {
    AATags = AATags.concat(Part.Store->getAAMetadata());
    Stores.push_back(Part.Store);
    DbgLocs.push_back(Part.Store->getDebugLoc());
  }
  Store->setAAMetadata(AATags);
  Store->mergeDIAssignID(Stores);
  Store->setDebugLoc(DebugLoc::getMergedLocations(DbgLocs));

  // Remove the old stores.
  for (const PartStore &Part : Parts)
    Part.Store->eraseFromParent();

  return true;
}

static bool mergePartStores(SmallVectorImpl<PartStore> &Parts,
                            const DataLayout &DL, TargetTransformInfo &TTI) {
  if (Parts.size() < 2)
    return false;

  // We now have multiple parts of the same value stored to the same pointer.
  // Sort the parts by pointer offset, and make sure they are consistent with
  // the value offsets. Also check that the value is fully covered without
  // overlaps.
  bool Changed = false;
  llvm::sort(Parts);
  int64_t LastEndOffsetFromFirst = 0;
  const PartStore *First = &Parts[0];
  for (const PartStore &Part : Parts) {
    APInt PtrOffsetFromFirst = Part.PtrOffset - First->PtrOffset;
    int64_t ValOffsetFromFirst = Part.ValOffset - First->ValOffset;
    if (PtrOffsetFromFirst * 8 != ValOffsetFromFirst ||
        LastEndOffsetFromFirst != ValOffsetFromFirst) {
      Changed |= mergeConsecutivePartStores(ArrayRef(First, &Part),
                                            LastEndOffsetFromFirst, DL, TTI);
      First = &Part;
      LastEndOffsetFromFirst = Part.ValWidth;
      continue;
    }

    LastEndOffsetFromFirst = ValOffsetFromFirst + Part.ValWidth;
  }

  Changed |= mergeConsecutivePartStores(ArrayRef(First, Parts.end()),
                                        LastEndOffsetFromFirst, DL, TTI);
  return Changed;
}

static bool foldConsecutiveStores(BasicBlock &BB, const DataLayout &DL,
                                  TargetTransformInfo &TTI, AliasAnalysis &AA) {
  // FIXME: Add big endian support.
  if (DL.isBigEndian())
    return false;

  BatchAAResults BatchAA(AA);
  SmallVector<PartStore, 8> Parts;
  bool MadeChange = false;
  for (Instruction &I : make_early_inc_range(BB)) {
    if (std::optional<PartStore> Part = matchPartStore(I, DL)) {
      if (Parts.empty() || Part->isCompatibleWith(Parts[0])) {
        Parts.push_back(std::move(*Part));
        continue;
      }

      MadeChange |= mergePartStores(Parts, DL, TTI);
      Parts.clear();
      Parts.push_back(std::move(*Part));
      continue;
    }

    if (Parts.empty())
      continue;

    if (I.mayThrow() ||
        (I.mayReadOrWriteMemory() &&
         isModOrRefSet(BatchAA.getModRefInfo(
             &I, MemoryLocation::getBeforeOrAfter(Parts[0].PtrBase))))) {
      MadeChange |= mergePartStores(Parts, DL, TTI);
      Parts.clear();
      continue;
    }
  }

  MadeChange |= mergePartStores(Parts, DL, TTI);
  return MadeChange;
}

/// Combine away instructions providing they are still equivalent when compared
/// against 0. i.e do they have any bits set.
static Value *optimizeShiftInOrChain(Value *V, IRBuilder<> &Builder) {
  auto *I = dyn_cast<Instruction>(V);
  if (!I || I->getOpcode() != Instruction::Or || !I->hasOneUse())
    return nullptr;

  Value *A;

  // Look deeper into the chain of or's, combining away shl (so long as they are
  // nuw or nsw).
  Value *Op0 = I->getOperand(0);
  if (match(Op0, m_CombineOr(m_NSWShl(m_Value(A), m_Value()),
                             m_NUWShl(m_Value(A), m_Value()))))
    Op0 = A;
  else if (auto *NOp = optimizeShiftInOrChain(Op0, Builder))
    Op0 = NOp;

  Value *Op1 = I->getOperand(1);
  if (match(Op1, m_CombineOr(m_NSWShl(m_Value(A), m_Value()),
                             m_NUWShl(m_Value(A), m_Value()))))
    Op1 = A;
  else if (auto *NOp = optimizeShiftInOrChain(Op1, Builder))
    Op1 = NOp;

  if (Op0 != I->getOperand(0) || Op1 != I->getOperand(1))
    return Builder.CreateOr(Op0, Op1);
  return nullptr;
}

static bool foldICmpOrChain(Instruction &I, const DataLayout &DL,
                            TargetTransformInfo &TTI, AliasAnalysis &AA,
                            const DominatorTree &DT) {
  CmpPredicate Pred;
  Value *Op0;
  if (!match(&I, m_ICmp(Pred, m_Value(Op0), m_Zero())) ||
      !ICmpInst::isEquality(Pred))
    return false;

  // If the chain or or's matches a load, combine to that before attempting to
  // remove shifts.
  if (auto OpI = dyn_cast<Instruction>(Op0))
    if (OpI->getOpcode() == Instruction::Or)
      if (foldConsecutiveLoads(*OpI, DL, TTI, AA, DT))
        return true;

  IRBuilder<> Builder(&I);
  // icmp eq/ne or(shl(a), b), 0 -> icmp eq/ne or(a, b), 0
  if (auto *Res = optimizeShiftInOrChain(Op0, Builder)) {
    I.replaceAllUsesWith(Builder.CreateICmp(Pred, Res, I.getOperand(1)));
    return true;
  }

  return false;
}

// Calculate GEP Stride and accumulated const ModOffset. Return Stride and
// ModOffset
static std::pair<APInt, APInt>
getStrideAndModOffsetOfGEP(Value *PtrOp, const DataLayout &DL) {
  unsigned BW = DL.getIndexTypeSizeInBits(PtrOp->getType());
  std::optional<APInt> Stride;
  APInt ModOffset(BW, 0);
  // Return a minimum gep stride, greatest common divisor of consective gep
  // index scales(c.f. Bézout's identity).
  while (auto *GEP = dyn_cast<GEPOperator>(PtrOp)) {
    SmallMapVector<Value *, APInt, 4> VarOffsets;
    if (!GEP->collectOffset(DL, BW, VarOffsets, ModOffset))
      break;

    for (auto [V, Scale] : VarOffsets) {
      // Only keep a power of two factor for non-inbounds
      if (!GEP->hasNoUnsignedSignedWrap())
        Scale = APInt::getOneBitSet(Scale.getBitWidth(), Scale.countr_zero());

      if (!Stride)
        Stride = Scale;
      else
        Stride = APIntOps::GreatestCommonDivisor(*Stride, Scale);
    }

    PtrOp = GEP->getPointerOperand();
  }

  // Check whether pointer arrives back at Global Variable via at least one GEP.
  // Even if it doesn't, we can check by alignment.
  if (!isa<GlobalVariable>(PtrOp) || !Stride)
    return {APInt(BW, 1), APInt(BW, 0)};

  // In consideration of signed GEP indices, non-negligible offset become
  // remainder of division by minimum GEP stride.
  ModOffset = ModOffset.srem(*Stride);
  if (ModOffset.isNegative())
    ModOffset += *Stride;

  return {*Stride, ModOffset};
}

/// If C is a constant patterned array and all valid loaded results for given
/// alignment are same to a constant, return that constant.
static bool foldPatternedLoads(Instruction &I, const DataLayout &DL) {
  auto *LI = dyn_cast<LoadInst>(&I);
  if (!LI || LI->isVolatile())
    return false;

  // We can only fold the load if it is from a constant global with definitive
  // initializer. Skip expensive logic if this is not the case.
  auto *PtrOp = LI->getPointerOperand();
  auto *GV = dyn_cast<GlobalVariable>(getUnderlyingObject(PtrOp));
  if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
    return false;

  // Bail for large initializers in excess of 4K to avoid too many scans.
  Constant *C = GV->getInitializer();
  uint64_t GVSize = DL.getTypeAllocSize(C->getType());
  if (!GVSize || 4096 < GVSize)
    return false;

  Type *LoadTy = LI->getType();
  unsigned BW = DL.getIndexTypeSizeInBits(PtrOp->getType());
  auto [Stride, ConstOffset] = getStrideAndModOffsetOfGEP(PtrOp, DL);

  // Any possible offset could be multiple of GEP stride. And any valid
  // offset is multiple of load alignment, so checking only multiples of bigger
  // one is sufficient to say results' equality.
  if (auto LA = LI->getAlign();
      LA <= GV->getAlign().valueOrOne() && Stride.getZExtValue() < LA.value()) {
    ConstOffset = APInt(BW, 0);
    Stride = APInt(BW, LA.value());
  }

  Constant *Ca = ConstantFoldLoadFromConst(C, LoadTy, ConstOffset, DL);
  if (!Ca)
    return false;

  unsigned E = GVSize - DL.getTypeStoreSize(LoadTy);
  for (; ConstOffset.getZExtValue() <= E; ConstOffset += Stride)
    if (Ca != ConstantFoldLoadFromConst(C, LoadTy, ConstOffset, DL))
      return false;

  I.replaceAllUsesWith(Ca);

  return true;
}

namespace {
class StrNCmpInliner {
public:
  StrNCmpInliner(CallInst *CI, LibFunc Func, DomTreeUpdater *DTU,
                 const DataLayout &DL)
      : CI(CI), Func(Func), DTU(DTU), DL(DL) {}

  bool optimizeStrNCmp();

private:
  void inlineCompare(Value *LHS, StringRef RHS, uint64_t N, bool Swapped);

  CallInst *CI;
  LibFunc Func;
  DomTreeUpdater *DTU;
  const DataLayout &DL;
};

} // namespace

/// First we normalize calls to strncmp/strcmp to the form of
/// compare(s1, s2, N), which means comparing first N bytes of s1 and s2
/// (without considering '\0').
///
/// Examples:
///
/// \code
///   strncmp(s, "a", 3) -> compare(s, "a", 2)
///   strncmp(s, "abc", 3) -> compare(s, "abc", 3)
///   strncmp(s, "a\0b", 3) -> compare(s, "a\0b", 2)
///   strcmp(s, "a") -> compare(s, "a", 2)
///
///   char s2[] = {'a'}
///   strncmp(s, s2, 3) -> compare(s, s2, 3)
///
///   char s2[] = {'a', 'b', 'c', 'd'}
///   strncmp(s, s2, 3) -> compare(s, s2, 3)
/// \endcode
///
/// We only handle cases where N and exactly one of s1 and s2 are constant.
/// Cases that s1 and s2 are both constant are already handled by the
/// instcombine pass.
///
/// We do not handle cases where N > StrNCmpInlineThreshold.
///
/// We also do not handles cases where N < 2, which are already
/// handled by the instcombine pass.
///
bool StrNCmpInliner::optimizeStrNCmp() {
  if (StrNCmpInlineThreshold < 2)
    return false;

  if (!isOnlyUsedInZeroComparison(CI))
    return false;

  Value *Str1P = CI->getArgOperand(0);
  Value *Str2P = CI->getArgOperand(1);
  // Should be handled elsewhere.
  if (Str1P == Str2P)
    return false;

  StringRef Str1, Str2;
  bool HasStr1 = getConstantStringInfo(Str1P, Str1, /*TrimAtNul=*/false);
  bool HasStr2 = getConstantStringInfo(Str2P, Str2, /*TrimAtNul=*/false);
  if (HasStr1 == HasStr2)
    return false;

  // Note that '\0' and characters after it are not trimmed.
  StringRef Str = HasStr1 ? Str1 : Str2;
  Value *StrP = HasStr1 ? Str2P : Str1P;

  size_t Idx = Str.find('\0');
  uint64_t N = Idx == StringRef::npos ? UINT64_MAX : Idx + 1;
  if (Func == LibFunc_strncmp) {
    if (auto *ConstInt = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
      N = std::min(N, ConstInt->getZExtValue());
    else
      return false;
  }
  // Now N means how many bytes we need to compare at most.
  if (N > Str.size() || N < 2 || N > StrNCmpInlineThreshold)
    return false;

  // Cases where StrP has two or more dereferenceable bytes might be better
  // optimized elsewhere.
  bool CanBeNull = false, CanBeFreed = false;
  if (StrP->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed) > 1)
    return false;
  inlineCompare(StrP, Str, N, HasStr1);
  return true;
}

/// Convert
///
/// \code
///   ret = compare(s1, s2, N)
/// \endcode
///
/// into
///
/// \code
///   ret = (int)s1[0] - (int)s2[0]
///   if (ret != 0)
///     goto NE
///   ...
///   ret = (int)s1[N-2] - (int)s2[N-2]
///   if (ret != 0)
///     goto NE
///   ret = (int)s1[N-1] - (int)s2[N-1]
///   NE:
/// \endcode
///
/// CFG before and after the transformation:
///
/// (before)
/// BBCI
///
/// (after)
/// BBCI -> BBSubs[0] (sub,icmp) --NE-> BBNE -> BBTail
///                 |                    ^
///                 E                    |
///                 |                    |
///        BBSubs[1] (sub,icmp) --NE-----+
///                ...                   |
///        BBSubs[N-1]    (sub) ---------+
///
void StrNCmpInliner::inlineCompare(Value *LHS, StringRef RHS, uint64_t N,
                                   bool Swapped) {
  auto &Ctx = CI->getContext();
  IRBuilder<> B(Ctx);
  // We want these instructions to be recognized as inlined instructions for the
  // compare call, but we don't have a source location for the definition of
  // that function, since we're generating that code now. Because the generated
  // code is a viable point for a memory access error, we make the pragmatic
  // choice here to directly use CI's location so that we have useful
  // attribution for the generated code.
  B.SetCurrentDebugLocation(CI->getDebugLoc());

  BasicBlock *BBCI = CI->getParent();
  BasicBlock *BBTail =
      SplitBlock(BBCI, CI, DTU, nullptr, nullptr, BBCI->getName() + ".tail");

  SmallVector<BasicBlock *> BBSubs;
  for (uint64_t I = 0; I < N; ++I)
    BBSubs.push_back(
        BasicBlock::Create(Ctx, "sub_" + Twine(I), BBCI->getParent(), BBTail));
  BasicBlock *BBNE = BasicBlock::Create(Ctx, "ne", BBCI->getParent(), BBTail);

  cast<BranchInst>(BBCI->getTerminator())->setSuccessor(0, BBSubs[0]);

  B.SetInsertPoint(BBNE);
  PHINode *Phi = B.CreatePHI(CI->getType(), N);
  B.CreateBr(BBTail);

  Value *Base = LHS;
  for (uint64_t i = 0; i < N; ++i) {
    B.SetInsertPoint(BBSubs[i]);
    Value *VL =
        B.CreateZExt(B.CreateLoad(B.getInt8Ty(),
                                  B.CreateInBoundsPtrAdd(Base, B.getInt64(i))),
                     CI->getType());
    Value *VR =
        ConstantInt::get(CI->getType(), static_cast<unsigned char>(RHS[i]));
    Value *Sub = Swapped ? B.CreateSub(VR, VL) : B.CreateSub(VL, VR);
    if (i < N - 1) {
      BranchInst *CondBrInst = B.CreateCondBr(
          B.CreateICmpNE(Sub, ConstantInt::get(CI->getType(), 0)), BBNE,
          BBSubs[i + 1]);

      Function *F = CI->getFunction();
      assert(F && "Instruction does not belong to a function!");
      std::optional<Function::ProfileCount> EC = F->getEntryCount();
      if (EC && EC->getCount() > 0)
        setExplicitlyUnknownBranchWeights(*CondBrInst, DEBUG_TYPE);
    } else {
      B.CreateBr(BBNE);
    }

    Phi->addIncoming(Sub, BBSubs[i]);
  }

  CI->replaceAllUsesWith(Phi);
  CI->eraseFromParent();

  if (DTU) {
    SmallVector<DominatorTree::UpdateType, 8> Updates;
    Updates.push_back({DominatorTree::Insert, BBCI, BBSubs[0]});
    for (uint64_t i = 0; i < N; ++i) {
      if (i < N - 1)
        Updates.push_back({DominatorTree::Insert, BBSubs[i], BBSubs[i + 1]});
      Updates.push_back({DominatorTree::Insert, BBSubs[i], BBNE});
    }
    Updates.push_back({DominatorTree::Insert, BBNE, BBTail});
    Updates.push_back({DominatorTree::Delete, BBCI, BBTail});
    DTU->applyUpdates(Updates);
  }
}

/// Convert memchr with a small constant string into a switch
static bool foldMemChr(CallInst *Call, DomTreeUpdater *DTU,
                       const DataLayout &DL) {
  if (isa<Constant>(Call->getArgOperand(1)))
    return false;

  StringRef Str;
  Value *Base = Call->getArgOperand(0);
  if (!getConstantStringInfo(Base, Str, /*TrimAtNul=*/false))
    return false;

  uint64_t N = Str.size();
  if (auto *ConstInt = dyn_cast<ConstantInt>(Call->getArgOperand(2))) {
    uint64_t Val = ConstInt->getZExtValue();
    // Ignore the case that n is larger than the size of string.
    if (Val > N)
      return false;
    N = Val;
  } else
    return false;

  if (N > MemChrInlineThreshold)
    return false;

  BasicBlock *BB = Call->getParent();
  BasicBlock *BBNext = SplitBlock(BB, Call, DTU);
  IRBuilder<> IRB(BB);
  IRB.SetCurrentDebugLocation(Call->getDebugLoc());
  IntegerType *ByteTy = IRB.getInt8Ty();
  BB->getTerminator()->eraseFromParent();
  SwitchInst *SI = IRB.CreateSwitch(
      IRB.CreateTrunc(Call->getArgOperand(1), ByteTy), BBNext, N);
  // We can't know the precise weights here, as they would depend on the value
  // distribution of Call->getArgOperand(1). So we just mark it as "unknown".
  setExplicitlyUnknownBranchWeightsIfProfiled(*SI, DEBUG_TYPE);
  Type *IndexTy = DL.getIndexType(Call->getType());
  SmallVector<DominatorTree::UpdateType, 8> Updates;

  BasicBlock *BBSuccess = BasicBlock::Create(
      Call->getContext(), "memchr.success", BB->getParent(), BBNext);
  IRB.SetInsertPoint(BBSuccess);
  PHINode *IndexPHI = IRB.CreatePHI(IndexTy, N, "memchr.idx");
  Value *FirstOccursLocation = IRB.CreateInBoundsPtrAdd(Base, IndexPHI);
  IRB.CreateBr(BBNext);
  if (DTU)
    Updates.push_back({DominatorTree::Insert, BBSuccess, BBNext});

  SmallPtrSet<ConstantInt *, 4> Cases;
  for (uint64_t I = 0; I < N; ++I) {
    ConstantInt *CaseVal = ConstantInt::get(ByteTy, Str[I]);
    if (!Cases.insert(CaseVal).second)
      continue;

    BasicBlock *BBCase = BasicBlock::Create(Call->getContext(), "memchr.case",
                                            BB->getParent(), BBSuccess);
    SI->addCase(CaseVal, BBCase);
    IRB.SetInsertPoint(BBCase);
    IndexPHI->addIncoming(ConstantInt::get(IndexTy, I), BBCase);
    IRB.CreateBr(BBSuccess);
    if (DTU) {
      Updates.push_back({DominatorTree::Insert, BB, BBCase});
      Updates.push_back({DominatorTree::Insert, BBCase, BBSuccess});
    }
  }

  PHINode *PHI =
      PHINode::Create(Call->getType(), 2, Call->getName(), BBNext->begin());
  PHI->addIncoming(Constant::getNullValue(Call->getType()), BB);
  PHI->addIncoming(FirstOccursLocation, BBSuccess);

  Call->replaceAllUsesWith(PHI);
  Call->eraseFromParent();

  if (DTU)
    DTU->applyUpdates(Updates);

  return true;
}

static bool foldLibCalls(Instruction &I, TargetTransformInfo &TTI,
                         TargetLibraryInfo &TLI, AssumptionCache &AC,
                         DominatorTree &DT, const DataLayout &DL,
                         bool &MadeCFGChange) {

  auto *CI = dyn_cast<CallInst>(&I);
  if (!CI || CI->isNoBuiltin())
    return false;

  Function *CalledFunc = CI->getCalledFunction();
  if (!CalledFunc)
    return false;

  LibFunc LF;
  if (!TLI.getLibFunc(*CalledFunc, LF) ||
      !isLibFuncEmittable(CI->getModule(), &TLI, LF))
    return false;

  DomTreeUpdater DTU(&DT, DomTreeUpdater::UpdateStrategy::Lazy);

  switch (LF) {
  case LibFunc_sqrt:
  case LibFunc_sqrtf:
  case LibFunc_sqrtl:
    return foldSqrt(CI, LF, TTI, TLI, AC, DT);
  case LibFunc_strcmp:
  case LibFunc_strncmp:
    if (StrNCmpInliner(CI, LF, &DTU, DL).optimizeStrNCmp()) {
      MadeCFGChange = true;
      return true;
    }
    break;
  case LibFunc_memchr:
    if (foldMemChr(CI, &DTU, DL)) {
      MadeCFGChange = true;
      return true;
    }
    break;
  default:;
  }
  return false;
}

/// Match high part of long multiplication.
///
/// Considering a multiply made up of high and low parts, we can split the
/// multiply into:
///  x * y == (xh*T + xl) * (yh*T + yl)
/// where xh == x>>32 and xl == x & 0xffffffff. T = 2^32.
/// This expands to
///  xh*yh*T*T + xh*yl*T + xl*yh*T + xl*yl
/// which can be drawn as
/// [  xh*yh  ]
///      [  xh*yl  ]
///      [  xl*yh  ]
///           [  xl*yl  ]
/// We are looking for the "high" half, which is xh*yh + xh*yl>>32 + xl*yh>>32 +
/// some carrys. The carry makes this difficult and there are multiple ways of
/// representing it. The ones we attempt to support here are:
///  Carry:  xh*yh + carry + lowsum
///          carry = lowsum < xh*yl ? 0x1000000 : 0
///          lowsum = xh*yl + xl*yh + (xl*yl>>32)
///  Ladder: xh*yh + c2>>32 + c3>>32
///          c2 = xh*yl + (xl*yl>>32); c3 = c2&0xffffffff + xl*yh
///       or c2 = (xl*yh&0xffffffff) + xh*yl + (xl*yl>>32); c3 = xl*yh
///  Carry4: xh*yh + carry + crosssum>>32 + (xl*yl + crosssum&0xffffffff) >> 32
///          crosssum = xh*yl + xl*yh
///          carry = crosssum < xh*yl ? 0x1000000 : 0
///  Ladder4: xh*yh + (xl*yh)>>32 + (xh*yl)>>32 + low>>32;
///          low = (xl*yl)>>32 + (xl*yh)&0xffffffff + (xh*yl)&0xffffffff
///
/// They all start by matching xh*yh + 2 or 3 other operands. The bottom of the
/// tree is xh*yh, xh*yl, xl*yh and xl*yl.
static bool foldMulHigh(Instruction &I) {
  Type *Ty = I.getType();
  if (!Ty->isIntOrIntVectorTy())
    return false;

  unsigned BitWidth = Ty->getScalarSizeInBits();
  APInt LowMask = APInt::getLowBitsSet(BitWidth, BitWidth / 2);
  if (BitWidth % 2 != 0)
    return false;

  auto CreateMulHigh = [&](Value *X, Value *Y) {
    IRBuilder<> Builder(&I);
    Type *NTy = Ty->getWithNewBitWidth(BitWidth * 2);
    Value *XExt = Builder.CreateZExt(X, NTy);
    Value *YExt = Builder.CreateZExt(Y, NTy);
    Value *Mul = Builder.CreateMul(XExt, YExt, "", /*HasNUW=*/true);
    Value *High = Builder.CreateLShr(Mul, BitWidth);
    Value *Res = Builder.CreateTrunc(High, Ty, "", /*HasNUW=*/true);
    Res->takeName(&I);
    I.replaceAllUsesWith(Res);
    LLVM_DEBUG(dbgs() << "Created long multiply from parts of " << *X << " and "
                      << *Y << "\n");
    return true;
  };

  // Common check routines for X_lo*Y_lo and X_hi*Y_lo
  auto CheckLoLo = [&](Value *XlYl, Value *X, Value *Y) {
    return match(XlYl, m_c_Mul(m_And(m_Specific(X), m_SpecificInt(LowMask)),
                               m_And(m_Specific(Y), m_SpecificInt(LowMask))));
  };
  auto CheckHiLo = [&](Value *XhYl, Value *X, Value *Y) {
    return match(XhYl,
                 m_c_Mul(m_LShr(m_Specific(X), m_SpecificInt(BitWidth / 2)),
                         m_And(m_Specific(Y), m_SpecificInt(LowMask))));
  };

  auto FoldMulHighCarry = [&](Value *X, Value *Y, Instruction *Carry,
                              Instruction *B) {
    // Looking for LowSum >> 32 and carry (select)
    if (Carry->getOpcode() != Instruction::Select)
      std::swap(Carry, B);

    // Carry = LowSum < XhYl ? 0x100000000 : 0
    Value *LowSum, *XhYl;
    if (!match(Carry,
               m_OneUse(m_Select(
                   m_OneUse(m_SpecificICmp(ICmpInst::ICMP_ULT, m_Value(LowSum),
                                           m_Value(XhYl))),
                   m_SpecificInt(APInt::getOneBitSet(BitWidth, BitWidth / 2)),
                   m_Zero()))))
      return false;

    // XhYl can be Xh*Yl or Xl*Yh
    if (!CheckHiLo(XhYl, X, Y)) {
      if (CheckHiLo(XhYl, Y, X))
        std::swap(X, Y);
      else
        return false;
    }
    if (XhYl->hasNUsesOrMore(3))
      return false;

    // B = LowSum >> 32
    if (!match(B, m_OneUse(m_LShr(m_Specific(LowSum),
                                  m_SpecificInt(BitWidth / 2)))) ||
        LowSum->hasNUsesOrMore(3))
      return false;

    // LowSum = XhYl + XlYh + XlYl>>32
    Value *XlYh, *XlYl;
    auto XlYlHi = m_LShr(m_Value(XlYl), m_SpecificInt(BitWidth / 2));
    if (!match(LowSum,
               m_c_Add(m_Specific(XhYl),
                       m_OneUse(m_c_Add(m_OneUse(m_Value(XlYh)), XlYlHi)))) &&
        !match(LowSum, m_c_Add(m_OneUse(m_Value(XlYh)),
                               m_OneUse(m_c_Add(m_Specific(XhYl), XlYlHi)))) &&
        !match(LowSum,
               m_c_Add(XlYlHi, m_OneUse(m_c_Add(m_Specific(XhYl),
                                                m_OneUse(m_Value(XlYh)))))))
      return false;

    // Check XlYl and XlYh
    if (!CheckLoLo(XlYl, X, Y))
      return false;
    if (!CheckHiLo(XlYh, Y, X))
      return false;

    return CreateMulHigh(X, Y);
  };

  auto FoldMulHighLadder = [&](Value *X, Value *Y, Instruction *A,
                               Instruction *B) {
    //  xh*yh + c2>>32 + c3>>32
    //    c2 = xh*yl + (xl*yl>>32); c3 = c2&0xffffffff + xl*yh
    // or c2 = (xl*yh&0xffffffff) + xh*yl + (xl*yl>>32); c3 = xh*yl
    Value *XlYh, *XhYl, *XlYl, *C2, *C3;
    // Strip off the two expected shifts.
    if (!match(A, m_LShr(m_Value(C2), m_SpecificInt(BitWidth / 2))) ||
        !match(B, m_LShr(m_Value(C3), m_SpecificInt(BitWidth / 2))))
      return false;

    if (match(C3, m_c_Add(m_Add(m_Value(), m_Value()), m_Value())))
      std::swap(C2, C3);
    // Try to match c2 = (xl*yh&0xffffffff) + xh*yl + (xl*yl>>32)
    if (match(C2,
              m_c_Add(m_c_Add(m_And(m_Specific(C3), m_SpecificInt(LowMask)),
                              m_Value(XlYh)),
                      m_LShr(m_Value(XlYl), m_SpecificInt(BitWidth / 2)))) ||
        match(C2, m_c_Add(m_c_Add(m_And(m_Specific(C3), m_SpecificInt(LowMask)),
                                  m_LShr(m_Value(XlYl),
                                         m_SpecificInt(BitWidth / 2))),
                          m_Value(XlYh))) ||
        match(C2, m_c_Add(m_c_Add(m_LShr(m_Value(XlYl),
                                         m_SpecificInt(BitWidth / 2)),
                                  m_Value(XlYh)),
                          m_And(m_Specific(C3), m_SpecificInt(LowMask))))) {
      XhYl = C3;
    } else {
      // Match c3 = c2&0xffffffff + xl*yh
      if (!match(C3, m_c_Add(m_And(m_Specific(C2), m_SpecificInt(LowMask)),
                             m_Value(XlYh))))
        std::swap(C2, C3);
      if (!match(C3, m_c_Add(m_OneUse(
                                 m_And(m_Specific(C2), m_SpecificInt(LowMask))),
                             m_Value(XlYh))) ||
          !C3->hasOneUse() || C2->hasNUsesOrMore(3))
        return false;

      // Match c2 = xh*yl + (xl*yl >> 32)
      if (!match(C2, m_c_Add(m_LShr(m_Value(XlYl), m_SpecificInt(BitWidth / 2)),
                             m_Value(XhYl))))
        return false;
    }

    // Match XhYl and XlYh - they can appear either way around.
    if (!CheckHiLo(XlYh, Y, X))
      std::swap(XlYh, XhYl);
    if (!CheckHiLo(XlYh, Y, X))
      return false;
    if (!CheckHiLo(XhYl, X, Y))
      return false;
    if (!CheckLoLo(XlYl, X, Y))
      return false;

    return CreateMulHigh(X, Y);
  };

  auto FoldMulHighLadder4 = [&](Value *X, Value *Y, Instruction *A,
                                Instruction *B, Instruction *C) {
    ///  Ladder4: xh*yh + (xl*yh)>>32 + (xh+yl)>>32 + low>>32;
    ///           low = (xl*yl)>>32 + (xl*yh)&0xffffffff + (xh*yl)&0xffffffff

    // Find A = Low >> 32 and B/C = XhYl>>32, XlYh>>32.
    auto ShiftAdd =
        m_LShr(m_Add(m_Value(), m_Value()), m_SpecificInt(BitWidth / 2));
    if (!match(A, ShiftAdd))
      std::swap(A, B);
    if (!match(A, ShiftAdd))
      std::swap(A, C);
    Value *Low;
    if (!match(A, m_LShr(m_OneUse(m_Value(Low)), m_SpecificInt(BitWidth / 2))))
      return false;

    // Match B == XhYl>>32 and C == XlYh>>32
    Value *XhYl, *XlYh;
    if (!match(B, m_LShr(m_Value(XhYl), m_SpecificInt(BitWidth / 2))) ||
        !match(C, m_LShr(m_Value(XlYh), m_SpecificInt(BitWidth / 2))))
      return false;
    if (!CheckHiLo(XhYl, X, Y))
      std::swap(XhYl, XlYh);
    if (!CheckHiLo(XhYl, X, Y) || XhYl->hasNUsesOrMore(3))
      return false;
    if (!CheckHiLo(XlYh, Y, X) || XlYh->hasNUsesOrMore(3))
      return false;

    // Match Low as XlYl>>32 + XhYl&0xffffffff + XlYh&0xffffffff
    Value *XlYl;
    if (!match(
            Low,
            m_c_Add(
                m_OneUse(m_c_Add(
                    m_OneUse(m_And(m_Specific(XhYl), m_SpecificInt(LowMask))),
                    m_OneUse(m_And(m_Specific(XlYh), m_SpecificInt(LowMask))))),
                m_OneUse(
                    m_LShr(m_Value(XlYl), m_SpecificInt(BitWidth / 2))))) &&
        !match(
            Low,
            m_c_Add(
                m_OneUse(m_c_Add(
                    m_OneUse(m_And(m_Specific(XhYl), m_SpecificInt(LowMask))),
                    m_OneUse(
                        m_LShr(m_Value(XlYl), m_SpecificInt(BitWidth / 2))))),
                m_OneUse(m_And(m_Specific(XlYh), m_SpecificInt(LowMask))))) &&
        !match(
            Low,
            m_c_Add(
                m_OneUse(m_c_Add(
                    m_OneUse(m_And(m_Specific(XlYh), m_SpecificInt(LowMask))),
                    m_OneUse(
                        m_LShr(m_Value(XlYl), m_SpecificInt(BitWidth / 2))))),
                m_OneUse(m_And(m_Specific(XhYl), m_SpecificInt(LowMask))))))
      return false;
    if (!CheckLoLo(XlYl, X, Y))
      return false;

    return CreateMulHigh(X, Y);
  };

  auto FoldMulHighCarry4 = [&](Value *X, Value *Y, Instruction *Carry,
                               Instruction *B, Instruction *C) {
    //  xh*yh + carry + crosssum>>32 + (xl*yl + crosssum&0xffffffff) >> 32
    //  crosssum = xh*yl+xl*yh
    //  carry = crosssum < xh*yl ? 0x1000000 : 0
    if (Carry->getOpcode() != Instruction::Select)
      std::swap(Carry, B);
    if (Carry->getOpcode() != Instruction::Select)
      std::swap(Carry, C);

    // Carry = CrossSum < XhYl ? 0x100000000 : 0
    Value *CrossSum, *XhYl;
    if (!match(Carry,
               m_OneUse(m_Select(
                   m_OneUse(m_SpecificICmp(ICmpInst::ICMP_ULT,
                                           m_Value(CrossSum), m_Value(XhYl))),
                   m_SpecificInt(APInt::getOneBitSet(BitWidth, BitWidth / 2)),
                   m_Zero()))))
      return false;

    if (!match(B, m_LShr(m_Specific(CrossSum), m_SpecificInt(BitWidth / 2))))
      std::swap(B, C);
    if (!match(B, m_LShr(m_Specific(CrossSum), m_SpecificInt(BitWidth / 2))))
      return false;

    Value *XlYl, *LowAccum;
    if (!match(C, m_LShr(m_Value(LowAccum), m_SpecificInt(BitWidth / 2))) ||
        !match(LowAccum, m_c_Add(m_OneUse(m_LShr(m_Value(XlYl),
                                                 m_SpecificInt(BitWidth / 2))),
                                 m_OneUse(m_And(m_Specific(CrossSum),
                                                m_SpecificInt(LowMask))))) ||
        LowAccum->hasNUsesOrMore(3))
      return false;
    if (!CheckLoLo(XlYl, X, Y))
      return false;

    if (!CheckHiLo(XhYl, X, Y))
      std::swap(X, Y);
    if (!CheckHiLo(XhYl, X, Y))
      return false;
    Value *XlYh;
    if (!match(CrossSum, m_c_Add(m_Specific(XhYl), m_OneUse(m_Value(XlYh)))) ||
        !CheckHiLo(XlYh, Y, X) || CrossSum->hasNUsesOrMore(4) ||
        XhYl->hasNUsesOrMore(3))
      return false;

    return CreateMulHigh(X, Y);
  };

  // X and Y are the two inputs, A, B and C are other parts of the pattern
  // (crosssum>>32, carry, etc).
  Value *X, *Y;
  Instruction *A, *B, *C;
  auto HiHi = m_OneUse(m_Mul(m_LShr(m_Value(X), m_SpecificInt(BitWidth / 2)),
                             m_LShr(m_Value(Y), m_SpecificInt(BitWidth / 2))));
  if ((match(&I, m_c_Add(HiHi, m_OneUse(m_Add(m_Instruction(A),
                                              m_Instruction(B))))) ||
       match(&I, m_c_Add(m_Instruction(A),
                         m_OneUse(m_c_Add(HiHi, m_Instruction(B)))))) &&
      A->hasOneUse() && B->hasOneUse())
    if (FoldMulHighCarry(X, Y, A, B) || FoldMulHighLadder(X, Y, A, B))
      return true;

  if ((match(&I, m_c_Add(HiHi, m_OneUse(m_c_Add(
                                   m_Instruction(A),
                                   m_OneUse(m_Add(m_Instruction(B),
                                                  m_Instruction(C))))))) ||
       match(&I, m_c_Add(m_Instruction(A),
                         m_OneUse(m_c_Add(
                             HiHi, m_OneUse(m_Add(m_Instruction(B),
                                                  m_Instruction(C))))))) ||
       match(&I, m_c_Add(m_Instruction(A),
                         m_OneUse(m_c_Add(
                             m_Instruction(B),
                             m_OneUse(m_c_Add(HiHi, m_Instruction(C))))))) ||
       match(&I,
             m_c_Add(m_OneUse(m_c_Add(HiHi, m_Instruction(A))),
                     m_OneUse(m_Add(m_Instruction(B), m_Instruction(C)))))) &&
      A->hasOneUse() && B->hasOneUse() && C->hasOneUse())
    return FoldMulHighCarry4(X, Y, A, B, C) ||
           FoldMulHighLadder4(X, Y, A, B, C);

  return false;
}

/// This is the entry point for folds that could be implemented in regular
/// InstCombine, but they are separated because they are not expected to
/// occur frequently and/or have more than a constant-length pattern match.
static bool foldUnusualPatterns(Function &F, DominatorTree &DT,
                                TargetTransformInfo &TTI,
                                TargetLibraryInfo &TLI, AliasAnalysis &AA,
                                AssumptionCache &AC, bool &MadeCFGChange) {
  bool MadeChange = false;
  for (BasicBlock &BB : F) {
    // Ignore unreachable basic blocks.
    if (!DT.isReachableFromEntry(&BB))
      continue;

    const DataLayout &DL = F.getDataLayout();

    // Walk the block backwards for efficiency. We're matching a chain of
    // use->defs, so we're more likely to succeed by starting from the bottom.
    // Also, we want to avoid matching partial patterns.
    // TODO: It would be more efficient if we removed dead instructions
    // iteratively in this loop rather than waiting until the end.
    for (Instruction &I : make_early_inc_range(llvm::reverse(BB))) {
      MadeChange |= foldAnyOrAllBitsSet(I);
      MadeChange |= foldGuardedFunnelShift(I, DT);
      MadeChange |= tryToRecognizePopCount(I);
      MadeChange |= tryToFPToSat(I, TTI);
      MadeChange |= tryToRecognizeTableBasedCttz(I, DL);
      MadeChange |= foldConsecutiveLoads(I, DL, TTI, AA, DT);
      MadeChange |= foldPatternedLoads(I, DL);
      MadeChange |= foldICmpOrChain(I, DL, TTI, AA, DT);
      MadeChange |= foldMulHigh(I);
      // NOTE: This function introduces erasing of the instruction `I`, so it
      // needs to be called at the end of this sequence, otherwise we may make
      // bugs.
      MadeChange |= foldLibCalls(I, TTI, TLI, AC, DT, DL, MadeCFGChange);
    }

    // Do this separately to avoid redundantly scanning stores multiple times.
    MadeChange |= foldConsecutiveStores(BB, DL, TTI, AA);
  }

  // We're done with transforms, so remove dead instructions.
  if (MadeChange)
    for (BasicBlock &BB : F)
      SimplifyInstructionsInBlock(&BB);

  return MadeChange;
}

/// This is the entry point for all transforms. Pass manager differences are
/// handled in the callers of this function.
static bool runImpl(Function &F, AssumptionCache &AC, TargetTransformInfo &TTI,
                    TargetLibraryInfo &TLI, DominatorTree &DT,
                    AliasAnalysis &AA, bool &MadeCFGChange) {
  bool MadeChange = false;
  const DataLayout &DL = F.getDataLayout();
  TruncInstCombine TIC(AC, TLI, DL, DT);
  MadeChange |= TIC.run(F);
  MadeChange |= foldUnusualPatterns(F, DT, TTI, TLI, AA, AC, MadeCFGChange);
  return MadeChange;
}

PreservedAnalyses AggressiveInstCombinePass::run(Function &F,
                                                 FunctionAnalysisManager &AM) {
  auto &AC = AM.getResult<AssumptionAnalysis>(F);
  auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
  auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
  auto &TTI = AM.getResult<TargetIRAnalysis>(F);
  auto &AA = AM.getResult<AAManager>(F);
  bool MadeCFGChange = false;
  if (!runImpl(F, AC, TTI, TLI, DT, AA, MadeCFGChange)) {
    // No changes, all analyses are preserved.
    return PreservedAnalyses::all();
  }
  // Mark all the analyses that instcombine updates as preserved.
  PreservedAnalyses PA;
  if (MadeCFGChange)
    PA.preserve<DominatorTreeAnalysis>();
  else
    PA.preserveSet<CFGAnalyses>();
  return PA;
}
