//===- InstCombineShifts.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 visitShl, visitLShr, and visitAShr functions.
//
//===----------------------------------------------------------------------===//

#include "InstCombineInternal.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
using namespace llvm;
using namespace PatternMatch;

#define DEBUG_TYPE "instcombine"

// Given pattern:
//   (x shiftopcode Q) shiftopcode K
// we should rewrite it as
//   x shiftopcode (Q+K)  iff (Q+K) u< bitwidth(x) and
//
// This is valid for any shift, but they must be identical, and we must be
// careful in case we have (zext(Q)+zext(K)) and look past extensions,
// (Q+K) must not overflow or else (Q+K) u< bitwidth(x) is bogus.
//
// AnalyzeForSignBitExtraction indicates that we will only analyze whether this
// pattern has any 2 right-shifts that sum to 1 less than original bit width.
Value *InstCombinerImpl::reassociateShiftAmtsOfTwoSameDirectionShifts(
    BinaryOperator *Sh0, const SimplifyQuery &SQ,
    bool AnalyzeForSignBitExtraction) {
  // Look for a shift of some instruction, ignore zext of shift amount if any.
  Instruction *Sh0Op0;
  Value *ShAmt0;
  if (!match(Sh0,
             m_Shift(m_Instruction(Sh0Op0), m_ZExtOrSelf(m_Value(ShAmt0)))))
    return nullptr;

  // If there is a truncation between the two shifts, we must make note of it
  // and look through it. The truncation imposes additional constraints on the
  // transform.
  Instruction *Sh1;
  Value *Trunc = nullptr;
  match(Sh0Op0,
        m_CombineOr(m_CombineAnd(m_Trunc(m_Instruction(Sh1)), m_Value(Trunc)),
                    m_Instruction(Sh1)));

  // Inner shift: (x shiftopcode ShAmt1)
  // Like with other shift, ignore zext of shift amount if any.
  Value *X, *ShAmt1;
  if (!match(Sh1, m_Shift(m_Value(X), m_ZExtOrSelf(m_Value(ShAmt1)))))
    return nullptr;

  // We have two shift amounts from two different shifts. The types of those
  // shift amounts may not match. If that's the case let's bailout now..
  if (ShAmt0->getType() != ShAmt1->getType())
    return nullptr;

  // As input, we have the following pattern:
  //   Sh0 (Sh1 X, Q), K
  // We want to rewrite that as:
  //   Sh x, (Q+K)  iff (Q+K) u< bitwidth(x)
  // While we know that originally (Q+K) would not overflow
  // (because  2 * (N-1) u<= iN -1), we have looked past extensions of
  // shift amounts. so it may now overflow in smaller bitwidth.
  // To ensure that does not happen, we need to ensure that the total maximal
  // shift amount is still representable in that smaller bit width.
  unsigned MaximalPossibleTotalShiftAmount =
      (Sh0->getType()->getScalarSizeInBits() - 1) +
      (Sh1->getType()->getScalarSizeInBits() - 1);
  APInt MaximalRepresentableShiftAmount =
      APInt::getAllOnesValue(ShAmt0->getType()->getScalarSizeInBits());
  if (MaximalRepresentableShiftAmount.ult(MaximalPossibleTotalShiftAmount))
    return nullptr;

  // We are only looking for signbit extraction if we have two right shifts.
  bool HadTwoRightShifts = match(Sh0, m_Shr(m_Value(), m_Value())) &&
                           match(Sh1, m_Shr(m_Value(), m_Value()));
  // ... and if it's not two right-shifts, we know the answer already.
  if (AnalyzeForSignBitExtraction && !HadTwoRightShifts)
    return nullptr;

  // The shift opcodes must be identical, unless we are just checking whether
  // this pattern can be interpreted as a sign-bit-extraction.
  Instruction::BinaryOps ShiftOpcode = Sh0->getOpcode();
  bool IdenticalShOpcodes = Sh0->getOpcode() == Sh1->getOpcode();
  if (!IdenticalShOpcodes && !AnalyzeForSignBitExtraction)
    return nullptr;

  // If we saw truncation, we'll need to produce extra instruction,
  // and for that one of the operands of the shift must be one-use,
  // unless of course we don't actually plan to produce any instructions here.
  if (Trunc && !AnalyzeForSignBitExtraction &&
      !match(Sh0, m_c_BinOp(m_OneUse(m_Value()), m_Value())))
    return nullptr;

  // Can we fold (ShAmt0+ShAmt1) ?
  auto *NewShAmt = dyn_cast_or_null<Constant>(
      SimplifyAddInst(ShAmt0, ShAmt1, /*isNSW=*/false, /*isNUW=*/false,
                      SQ.getWithInstruction(Sh0)));
  if (!NewShAmt)
    return nullptr; // Did not simplify.
  unsigned NewShAmtBitWidth = NewShAmt->getType()->getScalarSizeInBits();
  unsigned XBitWidth = X->getType()->getScalarSizeInBits();
  // Is the new shift amount smaller than the bit width of inner/new shift?
  if (!match(NewShAmt, m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT,
                                          APInt(NewShAmtBitWidth, XBitWidth))))
    return nullptr; // FIXME: could perform constant-folding.

  // If there was a truncation, and we have a right-shift, we can only fold if
  // we are left with the original sign bit. Likewise, if we were just checking
  // that this is a sighbit extraction, this is the place to check it.
  // FIXME: zero shift amount is also legal here, but we can't *easily* check
  // more than one predicate so it's not really worth it.
  if (HadTwoRightShifts && (Trunc || AnalyzeForSignBitExtraction)) {
    // If it's not a sign bit extraction, then we're done.
    if (!match(NewShAmt,
               m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ,
                                  APInt(NewShAmtBitWidth, XBitWidth - 1))))
      return nullptr;
    // If it is, and that was the question, return the base value.
    if (AnalyzeForSignBitExtraction)
      return X;
  }

  assert(IdenticalShOpcodes && "Should not get here with different shifts.");

  // All good, we can do this fold.
  NewShAmt = ConstantExpr::getZExtOrBitCast(NewShAmt, X->getType());

  BinaryOperator *NewShift = BinaryOperator::Create(ShiftOpcode, X, NewShAmt);

  // The flags can only be propagated if there wasn't a trunc.
  if (!Trunc) {
    // If the pattern did not involve trunc, and both of the original shifts
    // had the same flag set, preserve the flag.
    if (ShiftOpcode == Instruction::BinaryOps::Shl) {
      NewShift->setHasNoUnsignedWrap(Sh0->hasNoUnsignedWrap() &&
                                     Sh1->hasNoUnsignedWrap());
      NewShift->setHasNoSignedWrap(Sh0->hasNoSignedWrap() &&
                                   Sh1->hasNoSignedWrap());
    } else {
      NewShift->setIsExact(Sh0->isExact() && Sh1->isExact());
    }
  }

  Instruction *Ret = NewShift;
  if (Trunc) {
    Builder.Insert(NewShift);
    Ret = CastInst::Create(Instruction::Trunc, NewShift, Sh0->getType());
  }

  return Ret;
}

// If we have some pattern that leaves only some low bits set, and then performs
// left-shift of those bits, if none of the bits that are left after the final
// shift are modified by the mask, we can omit the mask.
//
// There are many variants to this pattern:
//   a)  (x & ((1 << MaskShAmt) - 1)) << ShiftShAmt
//   b)  (x & (~(-1 << MaskShAmt))) << ShiftShAmt
//   c)  (x & (-1 >> MaskShAmt)) << ShiftShAmt
//   d)  (x & ((-1 << MaskShAmt) >> MaskShAmt)) << ShiftShAmt
//   e)  ((x << MaskShAmt) l>> MaskShAmt) << ShiftShAmt
//   f)  ((x << MaskShAmt) a>> MaskShAmt) << ShiftShAmt
// All these patterns can be simplified to just:
//   x << ShiftShAmt
// iff:
//   a,b)     (MaskShAmt+ShiftShAmt) u>= bitwidth(x)
//   c,d,e,f) (ShiftShAmt-MaskShAmt) s>= 0 (i.e. ShiftShAmt u>= MaskShAmt)
static Instruction *
dropRedundantMaskingOfLeftShiftInput(BinaryOperator *OuterShift,
                                     const SimplifyQuery &Q,
                                     InstCombiner::BuilderTy &Builder) {
  assert(OuterShift->getOpcode() == Instruction::BinaryOps::Shl &&
         "The input must be 'shl'!");

  Value *Masked, *ShiftShAmt;
  match(OuterShift,
        m_Shift(m_Value(Masked), m_ZExtOrSelf(m_Value(ShiftShAmt))));

  // *If* there is a truncation between an outer shift and a possibly-mask,
  // then said truncation *must* be one-use, else we can't perform the fold.
  Value *Trunc;
  if (match(Masked, m_CombineAnd(m_Trunc(m_Value(Masked)), m_Value(Trunc))) &&
      !Trunc->hasOneUse())
    return nullptr;

  Type *NarrowestTy = OuterShift->getType();
  Type *WidestTy = Masked->getType();
  bool HadTrunc = WidestTy != NarrowestTy;

  // The mask must be computed in a type twice as wide to ensure
  // that no bits are lost if the sum-of-shifts is wider than the base type.
  Type *ExtendedTy = WidestTy->getExtendedType();

  Value *MaskShAmt;

  // ((1 << MaskShAmt) - 1)
  auto MaskA = m_Add(m_Shl(m_One(), m_Value(MaskShAmt)), m_AllOnes());
  // (~(-1 << maskNbits))
  auto MaskB = m_Xor(m_Shl(m_AllOnes(), m_Value(MaskShAmt)), m_AllOnes());
  // (-1 >> MaskShAmt)
  auto MaskC = m_Shr(m_AllOnes(), m_Value(MaskShAmt));
  // ((-1 << MaskShAmt) >> MaskShAmt)
  auto MaskD =
      m_Shr(m_Shl(m_AllOnes(), m_Value(MaskShAmt)), m_Deferred(MaskShAmt));

  Value *X;
  Constant *NewMask;

  if (match(Masked, m_c_And(m_CombineOr(MaskA, MaskB), m_Value(X)))) {
    // Peek through an optional zext of the shift amount.
    match(MaskShAmt, m_ZExtOrSelf(m_Value(MaskShAmt)));

    // We have two shift amounts from two different shifts. The types of those
    // shift amounts may not match. If that's the case let's bailout now.
    if (MaskShAmt->getType() != ShiftShAmt->getType())
      return nullptr;

    // Can we simplify (MaskShAmt+ShiftShAmt) ?
    auto *SumOfShAmts = dyn_cast_or_null<Constant>(SimplifyAddInst(
        MaskShAmt, ShiftShAmt, /*IsNSW=*/false, /*IsNUW=*/false, Q));
    if (!SumOfShAmts)
      return nullptr; // Did not simplify.
    // In this pattern SumOfShAmts correlates with the number of low bits
    // that shall remain in the root value (OuterShift).

    // An extend of an undef value becomes zero because the high bits are never
    // completely unknown. Replace the the `undef` shift amounts with final
    // shift bitwidth to ensure that the value remains undef when creating the
    // subsequent shift op.
    SumOfShAmts = Constant::replaceUndefsWith(
        SumOfShAmts, ConstantInt::get(SumOfShAmts->getType()->getScalarType(),
                                      ExtendedTy->getScalarSizeInBits()));
    auto *ExtendedSumOfShAmts = ConstantExpr::getZExt(SumOfShAmts, ExtendedTy);
    // And compute the mask as usual: ~(-1 << (SumOfShAmts))
    auto *ExtendedAllOnes = ConstantExpr::getAllOnesValue(ExtendedTy);
    auto *ExtendedInvertedMask =
        ConstantExpr::getShl(ExtendedAllOnes, ExtendedSumOfShAmts);
    NewMask = ConstantExpr::getNot(ExtendedInvertedMask);
  } else if (match(Masked, m_c_And(m_CombineOr(MaskC, MaskD), m_Value(X))) ||
             match(Masked, m_Shr(m_Shl(m_Value(X), m_Value(MaskShAmt)),
                                 m_Deferred(MaskShAmt)))) {
    // Peek through an optional zext of the shift amount.
    match(MaskShAmt, m_ZExtOrSelf(m_Value(MaskShAmt)));

    // We have two shift amounts from two different shifts. The types of those
    // shift amounts may not match. If that's the case let's bailout now.
    if (MaskShAmt->getType() != ShiftShAmt->getType())
      return nullptr;

    // Can we simplify (ShiftShAmt-MaskShAmt) ?
    auto *ShAmtsDiff = dyn_cast_or_null<Constant>(SimplifySubInst(
        ShiftShAmt, MaskShAmt, /*IsNSW=*/false, /*IsNUW=*/false, Q));
    if (!ShAmtsDiff)
      return nullptr; // Did not simplify.
    // In this pattern ShAmtsDiff correlates with the number of high bits that
    // shall be unset in the root value (OuterShift).

    // An extend of an undef value becomes zero because the high bits are never
    // completely unknown. Replace the the `undef` shift amounts with negated
    // bitwidth of innermost shift to ensure that the value remains undef when
    // creating the subsequent shift op.
    unsigned WidestTyBitWidth = WidestTy->getScalarSizeInBits();
    ShAmtsDiff = Constant::replaceUndefsWith(
        ShAmtsDiff, ConstantInt::get(ShAmtsDiff->getType()->getScalarType(),
                                     -WidestTyBitWidth));
    auto *ExtendedNumHighBitsToClear = ConstantExpr::getZExt(
        ConstantExpr::getSub(ConstantInt::get(ShAmtsDiff->getType(),
                                              WidestTyBitWidth,
                                              /*isSigned=*/false),
                             ShAmtsDiff),
        ExtendedTy);
    // And compute the mask as usual: (-1 l>> (NumHighBitsToClear))
    auto *ExtendedAllOnes = ConstantExpr::getAllOnesValue(ExtendedTy);
    NewMask =
        ConstantExpr::getLShr(ExtendedAllOnes, ExtendedNumHighBitsToClear);
  } else
    return nullptr; // Don't know anything about this pattern.

  NewMask = ConstantExpr::getTrunc(NewMask, NarrowestTy);

  // Does this mask has any unset bits? If not then we can just not apply it.
  bool NeedMask = !match(NewMask, m_AllOnes());

  // If we need to apply a mask, there are several more restrictions we have.
  if (NeedMask) {
    // The old masking instruction must go away.
    if (!Masked->hasOneUse())
      return nullptr;
    // The original "masking" instruction must not have been`ashr`.
    if (match(Masked, m_AShr(m_Value(), m_Value())))
      return nullptr;
  }

  // If we need to apply truncation, let's do it first, since we can.
  // We have already ensured that the old truncation will go away.
  if (HadTrunc)
    X = Builder.CreateTrunc(X, NarrowestTy);

  // No 'NUW'/'NSW'! We no longer know that we won't shift-out non-0 bits.
  // We didn't change the Type of this outermost shift, so we can just do it.
  auto *NewShift = BinaryOperator::Create(OuterShift->getOpcode(), X,
                                          OuterShift->getOperand(1));
  if (!NeedMask)
    return NewShift;

  Builder.Insert(NewShift);
  return BinaryOperator::Create(Instruction::And, NewShift, NewMask);
}

/// If we have a shift-by-constant of a bitwise logic op that itself has a
/// shift-by-constant operand with identical opcode, we may be able to convert
/// that into 2 independent shifts followed by the logic op. This eliminates a
/// a use of an intermediate value (reduces dependency chain).
static Instruction *foldShiftOfShiftedLogic(BinaryOperator &I,
                                            InstCombiner::BuilderTy &Builder) {
  assert(I.isShift() && "Expected a shift as input");
  auto *LogicInst = dyn_cast<BinaryOperator>(I.getOperand(0));
  if (!LogicInst || !LogicInst->isBitwiseLogicOp() || !LogicInst->hasOneUse())
    return nullptr;

  Constant *C0, *C1;
  if (!match(I.getOperand(1), m_Constant(C1)))
    return nullptr;

  Instruction::BinaryOps ShiftOpcode = I.getOpcode();
  Type *Ty = I.getType();

  // Find a matching one-use shift by constant. The fold is not valid if the sum
  // of the shift values equals or exceeds bitwidth.
  // TODO: Remove the one-use check if the other logic operand (Y) is constant.
  Value *X, *Y;
  auto matchFirstShift = [&](Value *V) {
    BinaryOperator *BO;
    APInt Threshold(Ty->getScalarSizeInBits(), Ty->getScalarSizeInBits());
    return match(V, m_BinOp(BO)) && BO->getOpcode() == ShiftOpcode &&
           match(V, m_OneUse(m_Shift(m_Value(X), m_Constant(C0)))) &&
           match(ConstantExpr::getAdd(C0, C1),
                 m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold));
  };

  // Logic ops are commutative, so check each operand for a match.
  if (matchFirstShift(LogicInst->getOperand(0)))
    Y = LogicInst->getOperand(1);
  else if (matchFirstShift(LogicInst->getOperand(1)))
    Y = LogicInst->getOperand(0);
  else
    return nullptr;

  // shift (logic (shift X, C0), Y), C1 -> logic (shift X, C0+C1), (shift Y, C1)
  Constant *ShiftSumC = ConstantExpr::getAdd(C0, C1);
  Value *NewShift1 = Builder.CreateBinOp(ShiftOpcode, X, ShiftSumC);
  Value *NewShift2 = Builder.CreateBinOp(ShiftOpcode, Y, I.getOperand(1));
  return BinaryOperator::Create(LogicInst->getOpcode(), NewShift1, NewShift2);
}

Instruction *InstCombinerImpl::commonShiftTransforms(BinaryOperator &I) {
  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
  assert(Op0->getType() == Op1->getType());

  // If the shift amount is a one-use `sext`, we can demote it to `zext`.
  Value *Y;
  if (match(Op1, m_OneUse(m_SExt(m_Value(Y))))) {
    Value *NewExt = Builder.CreateZExt(Y, I.getType(), Op1->getName());
    return BinaryOperator::Create(I.getOpcode(), Op0, NewExt);
  }

  // See if we can fold away this shift.
  if (SimplifyDemandedInstructionBits(I))
    return &I;

  // Try to fold constant and into select arguments.
  if (isa<Constant>(Op0))
    if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
      if (Instruction *R = FoldOpIntoSelect(I, SI))
        return R;

  if (Constant *CUI = dyn_cast<Constant>(Op1))
    if (Instruction *Res = FoldShiftByConstant(Op0, CUI, I))
      return Res;

  if (auto *NewShift = cast_or_null<Instruction>(
          reassociateShiftAmtsOfTwoSameDirectionShifts(&I, SQ)))
    return NewShift;

  // (C1 shift (A add C2)) -> (C1 shift C2) shift A)
  // iff A and C2 are both positive.
  Value *A;
  Constant *C;
  if (match(Op0, m_Constant()) && match(Op1, m_Add(m_Value(A), m_Constant(C))))
    if (isKnownNonNegative(A, DL, 0, &AC, &I, &DT) &&
        isKnownNonNegative(C, DL, 0, &AC, &I, &DT))
      return BinaryOperator::Create(
          I.getOpcode(), Builder.CreateBinOp(I.getOpcode(), Op0, C), A);

  // X shift (A srem C) -> X shift (A and (C - 1)) iff C is a power of 2.
  // Because shifts by negative values (which could occur if A were negative)
  // are undefined.
  if (Op1->hasOneUse() && match(Op1, m_SRem(m_Value(A), m_Constant(C))) &&
      match(C, m_Power2())) {
    // FIXME: Should this get moved into SimplifyDemandedBits by saying we don't
    // demand the sign bit (and many others) here??
    Constant *Mask = ConstantExpr::getSub(C, ConstantInt::get(I.getType(), 1));
    Value *Rem = Builder.CreateAnd(A, Mask, Op1->getName());
    return replaceOperand(I, 1, Rem);
  }

  if (Instruction *Logic = foldShiftOfShiftedLogic(I, Builder))
    return Logic;

  return nullptr;
}

/// Return true if we can simplify two logical (either left or right) shifts
/// that have constant shift amounts: OuterShift (InnerShift X, C1), C2.
static bool canEvaluateShiftedShift(unsigned OuterShAmt, bool IsOuterShl,
                                    Instruction *InnerShift,
                                    InstCombinerImpl &IC, Instruction *CxtI) {
  assert(InnerShift->isLogicalShift() && "Unexpected instruction type");

  // We need constant scalar or constant splat shifts.
  const APInt *InnerShiftConst;
  if (!match(InnerShift->getOperand(1), m_APInt(InnerShiftConst)))
    return false;

  // Two logical shifts in the same direction:
  // shl (shl X, C1), C2 -->  shl X, C1 + C2
  // lshr (lshr X, C1), C2 --> lshr X, C1 + C2
  bool IsInnerShl = InnerShift->getOpcode() == Instruction::Shl;
  if (IsInnerShl == IsOuterShl)
    return true;

  // Equal shift amounts in opposite directions become bitwise 'and':
  // lshr (shl X, C), C --> and X, C'
  // shl (lshr X, C), C --> and X, C'
  if (*InnerShiftConst == OuterShAmt)
    return true;

  // If the 2nd shift is bigger than the 1st, we can fold:
  // lshr (shl X, C1), C2 -->  and (shl X, C1 - C2), C3
  // shl (lshr X, C1), C2 --> and (lshr X, C1 - C2), C3
  // but it isn't profitable unless we know the and'd out bits are already zero.
  // Also, check that the inner shift is valid (less than the type width) or
  // we'll crash trying to produce the bit mask for the 'and'.
  unsigned TypeWidth = InnerShift->getType()->getScalarSizeInBits();
  if (InnerShiftConst->ugt(OuterShAmt) && InnerShiftConst->ult(TypeWidth)) {
    unsigned InnerShAmt = InnerShiftConst->getZExtValue();
    unsigned MaskShift =
        IsInnerShl ? TypeWidth - InnerShAmt : InnerShAmt - OuterShAmt;
    APInt Mask = APInt::getLowBitsSet(TypeWidth, OuterShAmt) << MaskShift;
    if (IC.MaskedValueIsZero(InnerShift->getOperand(0), Mask, 0, CxtI))
      return true;
  }

  return false;
}

/// See if we can compute the specified value, but shifted logically to the left
/// or right by some number of bits. This should return true if the expression
/// can be computed for the same cost as the current expression tree. This is
/// used to eliminate extraneous shifting from things like:
///      %C = shl i128 %A, 64
///      %D = shl i128 %B, 96
///      %E = or i128 %C, %D
///      %F = lshr i128 %E, 64
/// where the client will ask if E can be computed shifted right by 64-bits. If
/// this succeeds, getShiftedValue() will be called to produce the value.
static bool canEvaluateShifted(Value *V, unsigned NumBits, bool IsLeftShift,
                               InstCombinerImpl &IC, Instruction *CxtI) {
  // We can always evaluate constants shifted.
  if (isa<Constant>(V))
    return true;

  Instruction *I = dyn_cast<Instruction>(V);
  if (!I) return false;

  // We can't mutate something that has multiple uses: doing so would
  // require duplicating the instruction in general, which isn't profitable.
  if (!I->hasOneUse()) return false;

  switch (I->getOpcode()) {
  default: return false;
  case Instruction::And:
  case Instruction::Or:
  case Instruction::Xor:
    // Bitwise operators can all arbitrarily be arbitrarily evaluated shifted.
    return canEvaluateShifted(I->getOperand(0), NumBits, IsLeftShift, IC, I) &&
           canEvaluateShifted(I->getOperand(1), NumBits, IsLeftShift, IC, I);

  case Instruction::Shl:
  case Instruction::LShr:
    return canEvaluateShiftedShift(NumBits, IsLeftShift, I, IC, CxtI);

  case Instruction::Select: {
    SelectInst *SI = cast<SelectInst>(I);
    Value *TrueVal = SI->getTrueValue();
    Value *FalseVal = SI->getFalseValue();
    return canEvaluateShifted(TrueVal, NumBits, IsLeftShift, IC, SI) &&
           canEvaluateShifted(FalseVal, NumBits, IsLeftShift, IC, SI);
  }
  case Instruction::PHI: {
    // We can change a phi if we can change all operands.  Note that we never
    // get into trouble with cyclic PHIs here because we only consider
    // instructions with a single use.
    PHINode *PN = cast<PHINode>(I);
    for (Value *IncValue : PN->incoming_values())
      if (!canEvaluateShifted(IncValue, NumBits, IsLeftShift, IC, PN))
        return false;
    return true;
  }
  }
}

/// Fold OuterShift (InnerShift X, C1), C2.
/// See canEvaluateShiftedShift() for the constraints on these instructions.
static Value *foldShiftedShift(BinaryOperator *InnerShift, unsigned OuterShAmt,
                               bool IsOuterShl,
                               InstCombiner::BuilderTy &Builder) {
  bool IsInnerShl = InnerShift->getOpcode() == Instruction::Shl;
  Type *ShType = InnerShift->getType();
  unsigned TypeWidth = ShType->getScalarSizeInBits();

  // We only accept shifts-by-a-constant in canEvaluateShifted().
  const APInt *C1;
  match(InnerShift->getOperand(1), m_APInt(C1));
  unsigned InnerShAmt = C1->getZExtValue();

  // Change the shift amount and clear the appropriate IR flags.
  auto NewInnerShift = [&](unsigned ShAmt) {
    InnerShift->setOperand(1, ConstantInt::get(ShType, ShAmt));
    if (IsInnerShl) {
      InnerShift->setHasNoUnsignedWrap(false);
      InnerShift->setHasNoSignedWrap(false);
    } else {
      InnerShift->setIsExact(false);
    }
    return InnerShift;
  };

  // Two logical shifts in the same direction:
  // shl (shl X, C1), C2 -->  shl X, C1 + C2
  // lshr (lshr X, C1), C2 --> lshr X, C1 + C2
  if (IsInnerShl == IsOuterShl) {
    // If this is an oversized composite shift, then unsigned shifts get 0.
    if (InnerShAmt + OuterShAmt >= TypeWidth)
      return Constant::getNullValue(ShType);

    return NewInnerShift(InnerShAmt + OuterShAmt);
  }

  // Equal shift amounts in opposite directions become bitwise 'and':
  // lshr (shl X, C), C --> and X, C'
  // shl (lshr X, C), C --> and X, C'
  if (InnerShAmt == OuterShAmt) {
    APInt Mask = IsInnerShl
                     ? APInt::getLowBitsSet(TypeWidth, TypeWidth - OuterShAmt)
                     : APInt::getHighBitsSet(TypeWidth, TypeWidth - OuterShAmt);
    Value *And = Builder.CreateAnd(InnerShift->getOperand(0),
                                   ConstantInt::get(ShType, Mask));
    if (auto *AndI = dyn_cast<Instruction>(And)) {
      AndI->moveBefore(InnerShift);
      AndI->takeName(InnerShift);
    }
    return And;
  }

  assert(InnerShAmt > OuterShAmt &&
         "Unexpected opposite direction logical shift pair");

  // In general, we would need an 'and' for this transform, but
  // canEvaluateShiftedShift() guarantees that the masked-off bits are not used.
  // lshr (shl X, C1), C2 -->  shl X, C1 - C2
  // shl (lshr X, C1), C2 --> lshr X, C1 - C2
  return NewInnerShift(InnerShAmt - OuterShAmt);
}

/// When canEvaluateShifted() returns true for an expression, this function
/// inserts the new computation that produces the shifted value.
static Value *getShiftedValue(Value *V, unsigned NumBits, bool isLeftShift,
                              InstCombinerImpl &IC, const DataLayout &DL) {
  // We can always evaluate constants shifted.
  if (Constant *C = dyn_cast<Constant>(V)) {
    if (isLeftShift)
      return IC.Builder.CreateShl(C, NumBits);
    else
      return IC.Builder.CreateLShr(C, NumBits);
  }

  Instruction *I = cast<Instruction>(V);
  IC.addToWorklist(I);

  switch (I->getOpcode()) {
  default: llvm_unreachable("Inconsistency with CanEvaluateShifted");
  case Instruction::And:
  case Instruction::Or:
  case Instruction::Xor:
    // Bitwise operators can all arbitrarily be arbitrarily evaluated shifted.
    I->setOperand(
        0, getShiftedValue(I->getOperand(0), NumBits, isLeftShift, IC, DL));
    I->setOperand(
        1, getShiftedValue(I->getOperand(1), NumBits, isLeftShift, IC, DL));
    return I;

  case Instruction::Shl:
  case Instruction::LShr:
    return foldShiftedShift(cast<BinaryOperator>(I), NumBits, isLeftShift,
                            IC.Builder);

  case Instruction::Select:
    I->setOperand(
        1, getShiftedValue(I->getOperand(1), NumBits, isLeftShift, IC, DL));
    I->setOperand(
        2, getShiftedValue(I->getOperand(2), NumBits, isLeftShift, IC, DL));
    return I;
  case Instruction::PHI: {
    // We can change a phi if we can change all operands.  Note that we never
    // get into trouble with cyclic PHIs here because we only consider
    // instructions with a single use.
    PHINode *PN = cast<PHINode>(I);
    for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
      PN->setIncomingValue(i, getShiftedValue(PN->getIncomingValue(i), NumBits,
                                              isLeftShift, IC, DL));
    return PN;
  }
  }
}

// If this is a bitwise operator or add with a constant RHS we might be able
// to pull it through a shift.
static bool canShiftBinOpWithConstantRHS(BinaryOperator &Shift,
                                         BinaryOperator *BO) {
  switch (BO->getOpcode()) {
  default:
    return false; // Do not perform transform!
  case Instruction::Add:
    return Shift.getOpcode() == Instruction::Shl;
  case Instruction::Or:
  case Instruction::And:
    return true;
  case Instruction::Xor:
    // Do not change a 'not' of logical shift because that would create a normal
    // 'xor'. The 'not' is likely better for analysis, SCEV, and codegen.
    return !(Shift.isLogicalShift() && match(BO, m_Not(m_Value())));
  }
}

Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
                                                   BinaryOperator &I) {
  bool isLeftShift = I.getOpcode() == Instruction::Shl;

  const APInt *Op1C;
  if (!match(Op1, m_APInt(Op1C)))
    return nullptr;

  // See if we can propagate this shift into the input, this covers the trivial
  // cast of lshr(shl(x,c1),c2) as well as other more complex cases.
  if (I.getOpcode() != Instruction::AShr &&
      canEvaluateShifted(Op0, Op1C->getZExtValue(), isLeftShift, *this, &I)) {
    LLVM_DEBUG(
        dbgs() << "ICE: GetShiftedValue propagating shift through expression"
                  " to eliminate shift:\n  IN: "
               << *Op0 << "\n  SH: " << I << "\n");

    return replaceInstUsesWith(
        I, getShiftedValue(Op0, Op1C->getZExtValue(), isLeftShift, *this, DL));
  }

  // See if we can simplify any instructions used by the instruction whose sole
  // purpose is to compute bits we don't care about.
  Type *Ty = I.getType();
  unsigned TypeBits = Ty->getScalarSizeInBits();
  assert(!Op1C->uge(TypeBits) &&
         "Shift over the type width should have been removed already");

  if (Instruction *FoldedShift = foldBinOpIntoSelectOrPhi(I))
    return FoldedShift;

  // Fold shift2(trunc(shift1(x,c1)), c2) -> trunc(shift2(shift1(x,c1),c2))
  if (auto *TI = dyn_cast<TruncInst>(Op0)) {
    // If 'shift2' is an ashr, we would have to get the sign bit into a funny
    // place.  Don't try to do this transformation in this case.  Also, we
    // require that the input operand is a shift-by-constant so that we have
    // confidence that the shifts will get folded together.  We could do this
    // xform in more cases, but it is unlikely to be profitable.
    const APInt *TrShiftAmt;
    if (I.isLogicalShift() &&
        match(TI->getOperand(0), m_Shift(m_Value(), m_APInt(TrShiftAmt)))) {
      auto *TrOp = cast<Instruction>(TI->getOperand(0));
      Type *SrcTy = TrOp->getType();

      // Okay, we'll do this xform.  Make the shift of shift.
      Constant *ShAmt = ConstantExpr::getZExt(Op1, SrcTy);
      // (shift2 (shift1 & 0x00FF), c2)
      Value *NSh = Builder.CreateBinOp(I.getOpcode(), TrOp, ShAmt, I.getName());

      // For logical shifts, the truncation has the effect of making the high
      // part of the register be zeros.  Emulate this by inserting an AND to
      // clear the top bits as needed.  This 'and' will usually be zapped by
      // other xforms later if dead.
      unsigned SrcSize = SrcTy->getScalarSizeInBits();
      Constant *MaskV =
          ConstantInt::get(SrcTy, APInt::getLowBitsSet(SrcSize, TypeBits));

      // The mask we constructed says what the trunc would do if occurring
      // between the shifts.  We want to know the effect *after* the second
      // shift.  We know that it is a logical shift by a constant, so adjust the
      // mask as appropriate.
      MaskV = ConstantExpr::get(I.getOpcode(), MaskV, ShAmt);
      // shift1 & 0x00FF
      Value *And = Builder.CreateAnd(NSh, MaskV, TI->getName());
      // Return the value truncated to the interesting size.
      return new TruncInst(And, Ty);
    }
  }

  if (Op0->hasOneUse()) {
    if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
      // Turn ((X >> C) + Y) << C  ->  (X + (Y << C)) & (~0 << C)
      Value *V1;
      const APInt *CC;
      switch (Op0BO->getOpcode()) {
      default: break;
      case Instruction::Add:
      case Instruction::And:
      case Instruction::Or:
      case Instruction::Xor: {
        // These operators commute.
        // Turn (Y + (X >> C)) << C  ->  (X + (Y << C)) & (~0 << C)
        if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() &&
            match(Op0BO->getOperand(1), m_Shr(m_Value(V1),
                  m_Specific(Op1)))) {
          Value *YS =         // (Y << C)
            Builder.CreateShl(Op0BO->getOperand(0), Op1, Op0BO->getName());
          // (X + (Y << C))
          Value *X = Builder.CreateBinOp(Op0BO->getOpcode(), YS, V1,
                                         Op0BO->getOperand(1)->getName());
          unsigned Op1Val = Op1C->getLimitedValue(TypeBits);
          APInt Bits = APInt::getHighBitsSet(TypeBits, TypeBits - Op1Val);
          Constant *Mask = ConstantInt::get(Ty, Bits);
          return BinaryOperator::CreateAnd(X, Mask);
        }

        // Turn (Y + ((X >> C) & CC)) << C  ->  ((X & (CC << C)) + (Y << C))
        Value *Op0BOOp1 = Op0BO->getOperand(1);
        if (isLeftShift && Op0BOOp1->hasOneUse() &&
            match(Op0BOOp1, m_And(m_OneUse(m_Shr(m_Value(V1), m_Specific(Op1))),
                                  m_APInt(CC)))) {
          Value *YS = // (Y << C)
              Builder.CreateShl(Op0BO->getOperand(0), Op1, Op0BO->getName());
          // X & (CC << C)
          Value *XM = Builder.CreateAnd(
              V1, ConstantExpr::getShl(ConstantInt::get(Ty, *CC), Op1),
              V1->getName() + ".mask");
          return BinaryOperator::Create(Op0BO->getOpcode(), YS, XM);
        }
        LLVM_FALLTHROUGH;
      }

      case Instruction::Sub: {
        // Turn ((X >> C) + Y) << C  ->  (X + (Y << C)) & (~0 << C)
        if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
            match(Op0BO->getOperand(0), m_Shr(m_Value(V1),
                  m_Specific(Op1)))) {
          Value *YS =  // (Y << C)
            Builder.CreateShl(Op0BO->getOperand(1), Op1, Op0BO->getName());
          // (X + (Y << C))
          Value *X = Builder.CreateBinOp(Op0BO->getOpcode(), V1, YS,
                                         Op0BO->getOperand(0)->getName());
          unsigned Op1Val = Op1C->getLimitedValue(TypeBits);
          APInt Bits = APInt::getHighBitsSet(TypeBits, TypeBits - Op1Val);
          Constant *Mask = ConstantInt::get(Ty, Bits);
          return BinaryOperator::CreateAnd(X, Mask);
        }

        // Turn (((X >> C)&CC) + Y) << C  ->  (X + (Y << C)) & (CC << C)
        if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() &&
            match(Op0BO->getOperand(0),
                  m_And(m_OneUse(m_Shr(m_Value(V1), m_Specific(Op1))),
                        m_APInt(CC)))) {
          Value *YS = // (Y << C)
              Builder.CreateShl(Op0BO->getOperand(1), Op1, Op0BO->getName());
          // X & (CC << C)
          Value *XM = Builder.CreateAnd(
              V1, ConstantExpr::getShl(ConstantInt::get(Ty, *CC), Op1),
              V1->getName() + ".mask");
          return BinaryOperator::Create(Op0BO->getOpcode(), XM, YS);
        }

        break;
      }
      }

      // If the operand is a bitwise operator with a constant RHS, and the
      // shift is the only use, we can pull it out of the shift.
      const APInt *Op0C;
      if (match(Op0BO->getOperand(1), m_APInt(Op0C))) {
        if (canShiftBinOpWithConstantRHS(I, Op0BO)) {
          Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
                                     cast<Constant>(Op0BO->getOperand(1)), Op1);

          Value *NewShift =
            Builder.CreateBinOp(I.getOpcode(), Op0BO->getOperand(0), Op1);
          NewShift->takeName(Op0BO);

          return BinaryOperator::Create(Op0BO->getOpcode(), NewShift,
                                        NewRHS);
        }
      }

      // If the operand is a subtract with a constant LHS, and the shift
      // is the only use, we can pull it out of the shift.
      // This folds (shl (sub C1, X), C2) -> (sub (C1 << C2), (shl X, C2))
      if (isLeftShift && Op0BO->getOpcode() == Instruction::Sub &&
          match(Op0BO->getOperand(0), m_APInt(Op0C))) {
        Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
                                   cast<Constant>(Op0BO->getOperand(0)), Op1);

        Value *NewShift = Builder.CreateShl(Op0BO->getOperand(1), Op1);
        NewShift->takeName(Op0BO);

        return BinaryOperator::CreateSub(NewRHS, NewShift);
      }
    }

    // If we have a select that conditionally executes some binary operator,
    // see if we can pull it the select and operator through the shift.
    //
    // For example, turning:
    //   shl (select C, (add X, C1), X), C2
    // Into:
    //   Y = shl X, C2
    //   select C, (add Y, C1 << C2), Y
    Value *Cond;
    BinaryOperator *TBO;
    Value *FalseVal;
    if (match(Op0, m_Select(m_Value(Cond), m_OneUse(m_BinOp(TBO)),
                            m_Value(FalseVal)))) {
      const APInt *C;
      if (!isa<Constant>(FalseVal) && TBO->getOperand(0) == FalseVal &&
          match(TBO->getOperand(1), m_APInt(C)) &&
          canShiftBinOpWithConstantRHS(I, TBO)) {
        Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
                                       cast<Constant>(TBO->getOperand(1)), Op1);

        Value *NewShift =
          Builder.CreateBinOp(I.getOpcode(), FalseVal, Op1);
        Value *NewOp = Builder.CreateBinOp(TBO->getOpcode(), NewShift,
                                           NewRHS);
        return SelectInst::Create(Cond, NewOp, NewShift);
      }
    }

    BinaryOperator *FBO;
    Value *TrueVal;
    if (match(Op0, m_Select(m_Value(Cond), m_Value(TrueVal),
                            m_OneUse(m_BinOp(FBO))))) {
      const APInt *C;
      if (!isa<Constant>(TrueVal) && FBO->getOperand(0) == TrueVal &&
          match(FBO->getOperand(1), m_APInt(C)) &&
          canShiftBinOpWithConstantRHS(I, FBO)) {
        Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
                                       cast<Constant>(FBO->getOperand(1)), Op1);

        Value *NewShift =
          Builder.CreateBinOp(I.getOpcode(), TrueVal, Op1);
        Value *NewOp = Builder.CreateBinOp(FBO->getOpcode(), NewShift,
                                           NewRHS);
        return SelectInst::Create(Cond, NewShift, NewOp);
      }
    }
  }

  return nullptr;
}

Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
  const SimplifyQuery Q = SQ.getWithInstruction(&I);

  if (Value *V = SimplifyShlInst(I.getOperand(0), I.getOperand(1),
                                 I.hasNoSignedWrap(), I.hasNoUnsignedWrap(), Q))
    return replaceInstUsesWith(I, V);

  if (Instruction *X = foldVectorBinop(I))
    return X;

  if (Instruction *V = commonShiftTransforms(I))
    return V;

  if (Instruction *V = dropRedundantMaskingOfLeftShiftInput(&I, Q, Builder))
    return V;

  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
  Type *Ty = I.getType();
  unsigned BitWidth = Ty->getScalarSizeInBits();

  const APInt *ShAmtAPInt;
  if (match(Op1, m_APInt(ShAmtAPInt))) {
    unsigned ShAmt = ShAmtAPInt->getZExtValue();

    // shl (zext X), ShAmt --> zext (shl X, ShAmt)
    // This is only valid if X would have zeros shifted out.
    Value *X;
    if (match(Op0, m_OneUse(m_ZExt(m_Value(X))))) {
      unsigned SrcWidth = X->getType()->getScalarSizeInBits();
      if (ShAmt < SrcWidth &&
          MaskedValueIsZero(X, APInt::getHighBitsSet(SrcWidth, ShAmt), 0, &I))
        return new ZExtInst(Builder.CreateShl(X, ShAmt), Ty);
    }

    // (X >> C) << C --> X & (-1 << C)
    if (match(Op0, m_Shr(m_Value(X), m_Specific(Op1)))) {
      APInt Mask(APInt::getHighBitsSet(BitWidth, BitWidth - ShAmt));
      return BinaryOperator::CreateAnd(X, ConstantInt::get(Ty, Mask));
    }

    const APInt *ShOp1;
    if (match(Op0, m_Exact(m_Shr(m_Value(X), m_APInt(ShOp1)))) &&
        ShOp1->ult(BitWidth)) {
      unsigned ShrAmt = ShOp1->getZExtValue();
      if (ShrAmt < ShAmt) {
        // If C1 < C2: (X >>?,exact C1) << C2 --> X << (C2 - C1)
        Constant *ShiftDiff = ConstantInt::get(Ty, ShAmt - ShrAmt);
        auto *NewShl = BinaryOperator::CreateShl(X, ShiftDiff);
        NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
        NewShl->setHasNoSignedWrap(I.hasNoSignedWrap());
        return NewShl;
      }
      if (ShrAmt > ShAmt) {
        // If C1 > C2: (X >>?exact C1) << C2 --> X >>?exact (C1 - C2)
        Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmt);
        auto *NewShr = BinaryOperator::Create(
            cast<BinaryOperator>(Op0)->getOpcode(), X, ShiftDiff);
        NewShr->setIsExact(true);
        return NewShr;
      }
    }

    if (match(Op0, m_OneUse(m_Shr(m_Value(X), m_APInt(ShOp1)))) &&
        ShOp1->ult(BitWidth)) {
      unsigned ShrAmt = ShOp1->getZExtValue();
      if (ShrAmt < ShAmt) {
        // If C1 < C2: (X >>? C1) << C2 --> X << (C2 - C1) & (-1 << C2)
        Constant *ShiftDiff = ConstantInt::get(Ty, ShAmt - ShrAmt);
        auto *NewShl = BinaryOperator::CreateShl(X, ShiftDiff);
        NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
        NewShl->setHasNoSignedWrap(I.hasNoSignedWrap());
        Builder.Insert(NewShl);
        APInt Mask(APInt::getHighBitsSet(BitWidth, BitWidth - ShAmt));
        return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
      }
      if (ShrAmt > ShAmt) {
        // If C1 > C2: (X >>? C1) << C2 --> X >>? (C1 - C2) & (-1 << C2)
        Constant *ShiftDiff = ConstantInt::get(Ty, ShrAmt - ShAmt);
        auto *OldShr = cast<BinaryOperator>(Op0);
        auto *NewShr =
            BinaryOperator::Create(OldShr->getOpcode(), X, ShiftDiff);
        NewShr->setIsExact(OldShr->isExact());
        Builder.Insert(NewShr);
        APInt Mask(APInt::getHighBitsSet(BitWidth, BitWidth - ShAmt));
        return BinaryOperator::CreateAnd(NewShr, ConstantInt::get(Ty, Mask));
      }
    }

    if (match(Op0, m_Shl(m_Value(X), m_APInt(ShOp1))) && ShOp1->ult(BitWidth)) {
      unsigned AmtSum = ShAmt + ShOp1->getZExtValue();
      // Oversized shifts are simplified to zero in InstSimplify.
      if (AmtSum < BitWidth)
        // (X << C1) << C2 --> X << (C1 + C2)
        return BinaryOperator::CreateShl(X, ConstantInt::get(Ty, AmtSum));
    }

    // If the shifted-out value is known-zero, then this is a NUW shift.
    if (!I.hasNoUnsignedWrap() &&
        MaskedValueIsZero(Op0, APInt::getHighBitsSet(BitWidth, ShAmt), 0, &I)) {
      I.setHasNoUnsignedWrap();
      return &I;
    }

    // If the shifted-out value is all signbits, then this is a NSW shift.
    if (!I.hasNoSignedWrap() && ComputeNumSignBits(Op0, 0, &I) > ShAmt) {
      I.setHasNoSignedWrap();
      return &I;
    }
  }

  // Transform  (x >> y) << y  to  x & (-1 << y)
  // Valid for any type of right-shift.
  Value *X;
  if (match(Op0, m_OneUse(m_Shr(m_Value(X), m_Specific(Op1))))) {
    Constant *AllOnes = ConstantInt::getAllOnesValue(Ty);
    Value *Mask = Builder.CreateShl(AllOnes, Op1);
    return BinaryOperator::CreateAnd(Mask, X);
  }

  Constant *C1;
  if (match(Op1, m_Constant(C1))) {
    Constant *C2;
    Value *X;
    // (C2 << X) << C1 --> (C2 << C1) << X
    if (match(Op0, m_OneUse(m_Shl(m_Constant(C2), m_Value(X)))))
      return BinaryOperator::CreateShl(ConstantExpr::getShl(C2, C1), X);

    // (X * C2) << C1 --> X * (C2 << C1)
    if (match(Op0, m_Mul(m_Value(X), m_Constant(C2))))
      return BinaryOperator::CreateMul(X, ConstantExpr::getShl(C2, C1));

    // shl (zext i1 X), C1 --> select (X, 1 << C1, 0)
    if (match(Op0, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {
      auto *NewC = ConstantExpr::getShl(ConstantInt::get(Ty, 1), C1);
      return SelectInst::Create(X, NewC, ConstantInt::getNullValue(Ty));
    }
  }

  // (1 << (C - x)) -> ((1 << C) >> x) if C is bitwidth - 1
  if (match(Op0, m_One()) &&
      match(Op1, m_Sub(m_SpecificInt(BitWidth - 1), m_Value(X))))
    return BinaryOperator::CreateLShr(
        ConstantInt::get(Ty, APInt::getSignMask(BitWidth)), X);

  return nullptr;
}

Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
  if (Value *V = SimplifyLShrInst(I.getOperand(0), I.getOperand(1), I.isExact(),
                                  SQ.getWithInstruction(&I)))
    return replaceInstUsesWith(I, V);

  if (Instruction *X = foldVectorBinop(I))
    return X;

  if (Instruction *R = commonShiftTransforms(I))
    return R;

  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
  Type *Ty = I.getType();
  const APInt *ShAmtAPInt;
  if (match(Op1, m_APInt(ShAmtAPInt))) {
    unsigned ShAmt = ShAmtAPInt->getZExtValue();
    unsigned BitWidth = Ty->getScalarSizeInBits();
    auto *II = dyn_cast<IntrinsicInst>(Op0);
    if (II && isPowerOf2_32(BitWidth) && Log2_32(BitWidth) == ShAmt &&
        (II->getIntrinsicID() == Intrinsic::ctlz ||
         II->getIntrinsicID() == Intrinsic::cttz ||
         II->getIntrinsicID() == Intrinsic::ctpop)) {
      // ctlz.i32(x)>>5  --> zext(x == 0)
      // cttz.i32(x)>>5  --> zext(x == 0)
      // ctpop.i32(x)>>5 --> zext(x == -1)
      bool IsPop = II->getIntrinsicID() == Intrinsic::ctpop;
      Constant *RHS = ConstantInt::getSigned(Ty, IsPop ? -1 : 0);
      Value *Cmp = Builder.CreateICmpEQ(II->getArgOperand(0), RHS);
      return new ZExtInst(Cmp, Ty);
    }

    Value *X;
    const APInt *ShOp1;
    if (match(Op0, m_Shl(m_Value(X), m_APInt(ShOp1))) && ShOp1->ult(BitWidth)) {
      if (ShOp1->ult(ShAmt)) {
        unsigned ShlAmt = ShOp1->getZExtValue();
        Constant *ShiftDiff = ConstantInt::get(Ty, ShAmt - ShlAmt);
        if (cast<BinaryOperator>(Op0)->hasNoUnsignedWrap()) {
          // (X <<nuw C1) >>u C2 --> X >>u (C2 - C1)
          auto *NewLShr = BinaryOperator::CreateLShr(X, ShiftDiff);
          NewLShr->setIsExact(I.isExact());
          return NewLShr;
        }
        // (X << C1) >>u C2  --> (X >>u (C2 - C1)) & (-1 >> C2)
        Value *NewLShr = Builder.CreateLShr(X, ShiftDiff, "", I.isExact());
        APInt Mask(APInt::getLowBitsSet(BitWidth, BitWidth - ShAmt));
        return BinaryOperator::CreateAnd(NewLShr, ConstantInt::get(Ty, Mask));
      }
      if (ShOp1->ugt(ShAmt)) {
        unsigned ShlAmt = ShOp1->getZExtValue();
        Constant *ShiftDiff = ConstantInt::get(Ty, ShlAmt - ShAmt);
        if (cast<BinaryOperator>(Op0)->hasNoUnsignedWrap()) {
          // (X <<nuw C1) >>u C2 --> X <<nuw (C1 - C2)
          auto *NewShl = BinaryOperator::CreateShl(X, ShiftDiff);
          NewShl->setHasNoUnsignedWrap(true);
          return NewShl;
        }
        // (X << C1) >>u C2  --> X << (C1 - C2) & (-1 >> C2)
        Value *NewShl = Builder.CreateShl(X, ShiftDiff);
        APInt Mask(APInt::getLowBitsSet(BitWidth, BitWidth - ShAmt));
        return BinaryOperator::CreateAnd(NewShl, ConstantInt::get(Ty, Mask));
      }
      assert(*ShOp1 == ShAmt);
      // (X << C) >>u C --> X & (-1 >>u C)
      APInt Mask(APInt::getLowBitsSet(BitWidth, BitWidth - ShAmt));
      return BinaryOperator::CreateAnd(X, ConstantInt::get(Ty, Mask));
    }

    if (match(Op0, m_OneUse(m_ZExt(m_Value(X)))) &&
        (!Ty->isIntegerTy() || shouldChangeType(Ty, X->getType()))) {
      assert(ShAmt < X->getType()->getScalarSizeInBits() &&
             "Big shift not simplified to zero?");
      // lshr (zext iM X to iN), C --> zext (lshr X, C) to iN
      Value *NewLShr = Builder.CreateLShr(X, ShAmt);
      return new ZExtInst(NewLShr, Ty);
    }

    if (match(Op0, m_SExt(m_Value(X))) &&
        (!Ty->isIntegerTy() || shouldChangeType(Ty, X->getType()))) {
      // Are we moving the sign bit to the low bit and widening with high zeros?
      unsigned SrcTyBitWidth = X->getType()->getScalarSizeInBits();
      if (ShAmt == BitWidth - 1) {
        // lshr (sext i1 X to iN), N-1 --> zext X to iN
        if (SrcTyBitWidth == 1)
          return new ZExtInst(X, Ty);

        // lshr (sext iM X to iN), N-1 --> zext (lshr X, M-1) to iN
        if (Op0->hasOneUse()) {
          Value *NewLShr = Builder.CreateLShr(X, SrcTyBitWidth - 1);
          return new ZExtInst(NewLShr, Ty);
        }
      }

      // lshr (sext iM X to iN), N-M --> zext (ashr X, min(N-M, M-1)) to iN
      if (ShAmt == BitWidth - SrcTyBitWidth && Op0->hasOneUse()) {
        // The new shift amount can't be more than the narrow source type.
        unsigned NewShAmt = std::min(ShAmt, SrcTyBitWidth - 1);
        Value *AShr = Builder.CreateAShr(X, NewShAmt);
        return new ZExtInst(AShr, Ty);
      }
    }

    // lshr i32 (X -nsw Y), 31 --> zext (X < Y)
    Value *Y;
    if (ShAmt == BitWidth - 1 &&
        match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y)))))
      return new ZExtInst(Builder.CreateICmpSLT(X, Y), Ty);

    if (match(Op0, m_LShr(m_Value(X), m_APInt(ShOp1)))) {
      unsigned AmtSum = ShAmt + ShOp1->getZExtValue();
      // Oversized shifts are simplified to zero in InstSimplify.
      if (AmtSum < BitWidth)
        // (X >>u C1) >>u C2 --> X >>u (C1 + C2)
        return BinaryOperator::CreateLShr(X, ConstantInt::get(Ty, AmtSum));
    }

    // Look for a "splat" mul pattern - it replicates bits across each half of
    // a value, so a right shift is just a mask of the low bits:
    // lshr i32 (mul nuw X, Pow2+1), 16 --> and X, Pow2-1
    // TODO: Generalize to allow more than just half-width shifts?
    const APInt *MulC;
    if (match(Op0, m_NUWMul(m_Value(X), m_APInt(MulC))) &&
        ShAmt * 2 == BitWidth && (*MulC - 1).isPowerOf2() &&
        MulC->logBase2() == ShAmt)
      return BinaryOperator::CreateAnd(X, ConstantInt::get(Ty, *MulC - 2));

    // If the shifted-out value is known-zero, then this is an exact shift.
    if (!I.isExact() &&
        MaskedValueIsZero(Op0, APInt::getLowBitsSet(BitWidth, ShAmt), 0, &I)) {
      I.setIsExact();
      return &I;
    }
  }

  // Transform  (x << y) >> y  to  x & (-1 >> y)
  Value *X;
  if (match(Op0, m_OneUse(m_Shl(m_Value(X), m_Specific(Op1))))) {
    Constant *AllOnes = ConstantInt::getAllOnesValue(Ty);
    Value *Mask = Builder.CreateLShr(AllOnes, Op1);
    return BinaryOperator::CreateAnd(Mask, X);
  }

  return nullptr;
}

Instruction *
InstCombinerImpl::foldVariableSignZeroExtensionOfVariableHighBitExtract(
    BinaryOperator &OldAShr) {
  assert(OldAShr.getOpcode() == Instruction::AShr &&
         "Must be called with arithmetic right-shift instruction only.");

  // Check that constant C is a splat of the element-wise bitwidth of V.
  auto BitWidthSplat = [](Constant *C, Value *V) {
    return match(
        C, m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ,
                              APInt(C->getType()->getScalarSizeInBits(),
                                    V->getType()->getScalarSizeInBits())));
  };

  // It should look like variable-length sign-extension on the outside:
  //   (Val << (bitwidth(Val)-Nbits)) a>> (bitwidth(Val)-Nbits)
  Value *NBits;
  Instruction *MaybeTrunc;
  Constant *C1, *C2;
  if (!match(&OldAShr,
             m_AShr(m_Shl(m_Instruction(MaybeTrunc),
                          m_ZExtOrSelf(m_Sub(m_Constant(C1),
                                             m_ZExtOrSelf(m_Value(NBits))))),
                    m_ZExtOrSelf(m_Sub(m_Constant(C2),
                                       m_ZExtOrSelf(m_Deferred(NBits)))))) ||
      !BitWidthSplat(C1, &OldAShr) || !BitWidthSplat(C2, &OldAShr))
    return nullptr;

  // There may or may not be a truncation after outer two shifts.
  Instruction *HighBitExtract;
  match(MaybeTrunc, m_TruncOrSelf(m_Instruction(HighBitExtract)));
  bool HadTrunc = MaybeTrunc != HighBitExtract;

  // And finally, the innermost part of the pattern must be a right-shift.
  Value *X, *NumLowBitsToSkip;
  if (!match(HighBitExtract, m_Shr(m_Value(X), m_Value(NumLowBitsToSkip))))
    return nullptr;

  // Said right-shift must extract high NBits bits - C0 must be it's bitwidth.
  Constant *C0;
  if (!match(NumLowBitsToSkip,
             m_ZExtOrSelf(
                 m_Sub(m_Constant(C0), m_ZExtOrSelf(m_Specific(NBits))))) ||
      !BitWidthSplat(C0, HighBitExtract))
    return nullptr;

  // Since the NBits is identical for all shifts, if the outermost and
  // innermost shifts are identical, then outermost shifts are redundant.
  // If we had truncation, do keep it though.
  if (HighBitExtract->getOpcode() == OldAShr.getOpcode())
    return replaceInstUsesWith(OldAShr, MaybeTrunc);

  // Else, if there was a truncation, then we need to ensure that one
  // instruction will go away.
  if (HadTrunc && !match(&OldAShr, m_c_BinOp(m_OneUse(m_Value()), m_Value())))
    return nullptr;

  // Finally, bypass two innermost shifts, and perform the outermost shift on
  // the operands of the innermost shift.
  Instruction *NewAShr =
      BinaryOperator::Create(OldAShr.getOpcode(), X, NumLowBitsToSkip);
  NewAShr->copyIRFlags(HighBitExtract); // We can preserve 'exact'-ness.
  if (!HadTrunc)
    return NewAShr;

  Builder.Insert(NewAShr);
  return TruncInst::CreateTruncOrBitCast(NewAShr, OldAShr.getType());
}

Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) {
  if (Value *V = SimplifyAShrInst(I.getOperand(0), I.getOperand(1), I.isExact(),
                                  SQ.getWithInstruction(&I)))
    return replaceInstUsesWith(I, V);

  if (Instruction *X = foldVectorBinop(I))
    return X;

  if (Instruction *R = commonShiftTransforms(I))
    return R;

  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
  Type *Ty = I.getType();
  unsigned BitWidth = Ty->getScalarSizeInBits();
  const APInt *ShAmtAPInt;
  if (match(Op1, m_APInt(ShAmtAPInt)) && ShAmtAPInt->ult(BitWidth)) {
    unsigned ShAmt = ShAmtAPInt->getZExtValue();

    // If the shift amount equals the difference in width of the destination
    // and source scalar types:
    // ashr (shl (zext X), C), C --> sext X
    Value *X;
    if (match(Op0, m_Shl(m_ZExt(m_Value(X)), m_Specific(Op1))) &&
        ShAmt == BitWidth - X->getType()->getScalarSizeInBits())
      return new SExtInst(X, Ty);

    // We can't handle (X << C1) >>s C2. It shifts arbitrary bits in. However,
    // we can handle (X <<nsw C1) >>s C2 since it only shifts in sign bits.
    const APInt *ShOp1;
    if (match(Op0, m_NSWShl(m_Value(X), m_APInt(ShOp1))) &&
        ShOp1->ult(BitWidth)) {
      unsigned ShlAmt = ShOp1->getZExtValue();
      if (ShlAmt < ShAmt) {
        // (X <<nsw C1) >>s C2 --> X >>s (C2 - C1)
        Constant *ShiftDiff = ConstantInt::get(Ty, ShAmt - ShlAmt);
        auto *NewAShr = BinaryOperator::CreateAShr(X, ShiftDiff);
        NewAShr->setIsExact(I.isExact());
        return NewAShr;
      }
      if (ShlAmt > ShAmt) {
        // (X <<nsw C1) >>s C2 --> X <<nsw (C1 - C2)
        Constant *ShiftDiff = ConstantInt::get(Ty, ShlAmt - ShAmt);
        auto *NewShl = BinaryOperator::Create(Instruction::Shl, X, ShiftDiff);
        NewShl->setHasNoSignedWrap(true);
        return NewShl;
      }
    }

    if (match(Op0, m_AShr(m_Value(X), m_APInt(ShOp1))) &&
        ShOp1->ult(BitWidth)) {
      unsigned AmtSum = ShAmt + ShOp1->getZExtValue();
      // Oversized arithmetic shifts replicate the sign bit.
      AmtSum = std::min(AmtSum, BitWidth - 1);
      // (X >>s C1) >>s C2 --> X >>s (C1 + C2)
      return BinaryOperator::CreateAShr(X, ConstantInt::get(Ty, AmtSum));
    }

    if (match(Op0, m_OneUse(m_SExt(m_Value(X)))) &&
        (Ty->isVectorTy() || shouldChangeType(Ty, X->getType()))) {
      // ashr (sext X), C --> sext (ashr X, C')
      Type *SrcTy = X->getType();
      ShAmt = std::min(ShAmt, SrcTy->getScalarSizeInBits() - 1);
      Value *NewSh = Builder.CreateAShr(X, ConstantInt::get(SrcTy, ShAmt));
      return new SExtInst(NewSh, Ty);
    }

    // ashr i32 (X -nsw Y), 31 --> sext (X < Y)
    Value *Y;
    if (ShAmt == BitWidth - 1 &&
        match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y)))))
      return new SExtInst(Builder.CreateICmpSLT(X, Y), Ty);

    // If the shifted-out value is known-zero, then this is an exact shift.
    if (!I.isExact() &&
        MaskedValueIsZero(Op0, APInt::getLowBitsSet(BitWidth, ShAmt), 0, &I)) {
      I.setIsExact();
      return &I;
    }
  }

  if (Instruction *R = foldVariableSignZeroExtensionOfVariableHighBitExtract(I))
    return R;

  // See if we can turn a signed shr into an unsigned shr.
  if (MaskedValueIsZero(Op0, APInt::getSignMask(BitWidth), 0, &I))
    return BinaryOperator::CreateLShr(Op0, Op1);

  // ashr (xor %x, -1), %y  -->  xor (ashr %x, %y), -1
  Value *X;
  if (match(Op0, m_OneUse(m_Not(m_Value(X))))) {
    // Note that we must drop 'exact'-ness of the shift!
    // Note that we can't keep undef's in -1 vector constant!
    auto *NewAShr = Builder.CreateAShr(X, Op1, Op0->getName() + ".not");
    return BinaryOperator::CreateNot(NewAShr);
  }

  return nullptr;
}
