//===- InstCombineAddSub.cpp ------------------------------------*- C++ -*-===//
//
// 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 visit functions for add, fadd, sub, and fsub.
//
//===----------------------------------------------------------------------===//

#include "InstCombineInternal.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include <cassert>
#include <utility>

using namespace llvm;
using namespace PatternMatch;

#define DEBUG_TYPE "instcombine"

namespace {

  /// Class representing coefficient of floating-point addend.
  /// This class needs to be highly efficient, which is especially true for
  /// the constructor. As of I write this comment, the cost of the default
  /// constructor is merely 4-byte-store-zero (Assuming compiler is able to
  /// perform write-merging).
  ///
  class FAddendCoef {
  public:
    // The constructor has to initialize a APFloat, which is unnecessary for
    // most addends which have coefficient either 1 or -1. So, the constructor
    // is expensive. In order to avoid the cost of the constructor, we should
    // reuse some instances whenever possible. The pre-created instances
    // FAddCombine::Add[0-5] embodies this idea.
    FAddendCoef() = default;
    ~FAddendCoef();

    // If possible, don't define operator+/operator- etc because these
    // operators inevitably call FAddendCoef's constructor which is not cheap.
    void operator=(const FAddendCoef &A);
    void operator+=(const FAddendCoef &A);
    void operator*=(const FAddendCoef &S);

    void set(short C) {
      assert(!insaneIntVal(C) && "Insane coefficient");
      IsFp = false; IntVal = C;
    }

    void set(const APFloat& C);

    void negate();

    bool isZero() const { return isInt() ? !IntVal : getFpVal().isZero(); }
    Value *getValue(Type *) const;

    bool isOne() const { return isInt() && IntVal == 1; }
    bool isTwo() const { return isInt() && IntVal == 2; }
    bool isMinusOne() const { return isInt() && IntVal == -1; }
    bool isMinusTwo() const { return isInt() && IntVal == -2; }

  private:
    bool insaneIntVal(int V) { return V > 4 || V < -4; }

    APFloat *getFpValPtr() { return reinterpret_cast<APFloat *>(&FpValBuf); }

    const APFloat *getFpValPtr() const {
      return reinterpret_cast<const APFloat *>(&FpValBuf);
    }

    const APFloat &getFpVal() const {
      assert(IsFp && BufHasFpVal && "Incorrect state");
      return *getFpValPtr();
    }

    APFloat &getFpVal() {
      assert(IsFp && BufHasFpVal && "Incorrect state");
      return *getFpValPtr();
    }

    bool isInt() const { return !IsFp; }

    // If the coefficient is represented by an integer, promote it to a
    // floating point.
    void convertToFpType(const fltSemantics &Sem);

    // Construct an APFloat from a signed integer.
    // TODO: We should get rid of this function when APFloat can be constructed
    //       from an *SIGNED* integer.
    APFloat createAPFloatFromInt(const fltSemantics &Sem, int Val);

    bool IsFp = false;

    // True iff FpValBuf contains an instance of APFloat.
    bool BufHasFpVal = false;

    // The integer coefficient of an individual addend is either 1 or -1,
    // and we try to simplify at most 4 addends from neighboring at most
    // two instructions. So the range of <IntVal> falls in [-4, 4]. APInt
    // is overkill of this end.
    short IntVal = 0;

    AlignedCharArrayUnion<APFloat> FpValBuf;
  };

  /// FAddend is used to represent floating-point addend. An addend is
  /// represented as <C, V>, where the V is a symbolic value, and C is a
  /// constant coefficient. A constant addend is represented as <C, 0>.
  class FAddend {
  public:
    FAddend() = default;

    void operator+=(const FAddend &T) {
      assert((Val == T.Val) && "Symbolic-values disagree");
      Coeff += T.Coeff;
    }

    Value *getSymVal() const { return Val; }
    const FAddendCoef &getCoef() const { return Coeff; }

    bool isConstant() const { return Val == nullptr; }
    bool isZero() const { return Coeff.isZero(); }

    void set(short Coefficient, Value *V) {
      Coeff.set(Coefficient);
      Val = V;
    }
    void set(const APFloat &Coefficient, Value *V) {
      Coeff.set(Coefficient);
      Val = V;
    }
    void set(const ConstantFP *Coefficient, Value *V) {
      Coeff.set(Coefficient->getValueAPF());
      Val = V;
    }

    void negate() { Coeff.negate(); }

    /// Drill down the U-D chain one step to find the definition of V, and
    /// try to break the definition into one or two addends.
    static unsigned drillValueDownOneStep(Value* V, FAddend &A0, FAddend &A1);

    /// Similar to FAddend::drillDownOneStep() except that the value being
    /// splitted is the addend itself.
    unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1) const;

  private:
    void Scale(const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; }

    // This addend has the value of "Coeff * Val".
    Value *Val = nullptr;
    FAddendCoef Coeff;
  };

  /// FAddCombine is the class for optimizing an unsafe fadd/fsub along
  /// with its neighboring at most two instructions.
  ///
  class FAddCombine {
  public:
    FAddCombine(InstCombiner::BuilderTy &B) : Builder(B) {}

    Value *simplify(Instruction *FAdd);

  private:
    using AddendVect = SmallVector<const FAddend *, 4>;

    Value *simplifyFAdd(AddendVect& V, unsigned InstrQuota);

    /// Convert given addend to a Value
    Value *createAddendVal(const FAddend &A, bool& NeedNeg);

    /// Return the number of instructions needed to emit the N-ary addition.
    unsigned calcInstrNumber(const AddendVect& Vect);

    Value *createFSub(Value *Opnd0, Value *Opnd1);
    Value *createFAdd(Value *Opnd0, Value *Opnd1);
    Value *createFMul(Value *Opnd0, Value *Opnd1);
    Value *createFNeg(Value *V);
    Value *createNaryFAdd(const AddendVect& Opnds, unsigned InstrQuota);
    void createInstPostProc(Instruction *NewInst, bool NoNumber = false);

     // Debugging stuff are clustered here.
    #ifndef NDEBUG
      unsigned CreateInstrNum;
      void initCreateInstNum() { CreateInstrNum = 0; }
      void incCreateInstNum() { CreateInstrNum++; }
    #else
      void initCreateInstNum() {}
      void incCreateInstNum() {}
    #endif

    InstCombiner::BuilderTy &Builder;
    Instruction *Instr = nullptr;
  };

} // end anonymous namespace

//===----------------------------------------------------------------------===//
//
// Implementation of
//    {FAddendCoef, FAddend, FAddition, FAddCombine}.
//
//===----------------------------------------------------------------------===//
FAddendCoef::~FAddendCoef() {
  if (BufHasFpVal)
    getFpValPtr()->~APFloat();
}

void FAddendCoef::set(const APFloat& C) {
  APFloat *P = getFpValPtr();

  if (isInt()) {
    // As the buffer is meanless byte stream, we cannot call
    // APFloat::operator=().
    new(P) APFloat(C);
  } else
    *P = C;

  IsFp = BufHasFpVal = true;
}

void FAddendCoef::convertToFpType(const fltSemantics &Sem) {
  if (!isInt())
    return;

  APFloat *P = getFpValPtr();
  if (IntVal > 0)
    new(P) APFloat(Sem, IntVal);
  else {
    new(P) APFloat(Sem, 0 - IntVal);
    P->changeSign();
  }
  IsFp = BufHasFpVal = true;
}

APFloat FAddendCoef::createAPFloatFromInt(const fltSemantics &Sem, int Val) {
  if (Val >= 0)
    return APFloat(Sem, Val);

  APFloat T(Sem, 0 - Val);
  T.changeSign();

  return T;
}

void FAddendCoef::operator=(const FAddendCoef &That) {
  if (That.isInt())
    set(That.IntVal);
  else
    set(That.getFpVal());
}

void FAddendCoef::operator+=(const FAddendCoef &That) {
  RoundingMode RndMode = RoundingMode::NearestTiesToEven;
  if (isInt() == That.isInt()) {
    if (isInt())
      IntVal += That.IntVal;
    else
      getFpVal().add(That.getFpVal(), RndMode);
    return;
  }

  if (isInt()) {
    const APFloat &T = That.getFpVal();
    convertToFpType(T.getSemantics());
    getFpVal().add(T, RndMode);
    return;
  }

  APFloat &T = getFpVal();
  T.add(createAPFloatFromInt(T.getSemantics(), That.IntVal), RndMode);
}

void FAddendCoef::operator*=(const FAddendCoef &That) {
  if (That.isOne())
    return;

  if (That.isMinusOne()) {
    negate();
    return;
  }

  if (isInt() && That.isInt()) {
    int Res = IntVal * (int)That.IntVal;
    assert(!insaneIntVal(Res) && "Insane int value");
    IntVal = Res;
    return;
  }

  const fltSemantics &Semantic =
    isInt() ? That.getFpVal().getSemantics() : getFpVal().getSemantics();

  if (isInt())
    convertToFpType(Semantic);
  APFloat &F0 = getFpVal();

  if (That.isInt())
    F0.multiply(createAPFloatFromInt(Semantic, That.IntVal),
                APFloat::rmNearestTiesToEven);
  else
    F0.multiply(That.getFpVal(), APFloat::rmNearestTiesToEven);
}

void FAddendCoef::negate() {
  if (isInt())
    IntVal = 0 - IntVal;
  else
    getFpVal().changeSign();
}

Value *FAddendCoef::getValue(Type *Ty) const {
  return isInt() ?
    ConstantFP::get(Ty, float(IntVal)) :
    ConstantFP::get(Ty->getContext(), getFpVal());
}

// The definition of <Val>     Addends
// =========================================
//  A + B                     <1, A>, <1,B>
//  A - B                     <1, A>, <1,B>
//  0 - B                     <-1, B>
//  C * A,                    <C, A>
//  A + C                     <1, A> <C, NULL>
//  0 +/- 0                   <0, NULL> (corner case)
//
// Legend: A and B are not constant, C is constant
unsigned FAddend::drillValueDownOneStep
  (Value *Val, FAddend &Addend0, FAddend &Addend1) {
  Instruction *I = nullptr;
  if (!Val || !(I = dyn_cast<Instruction>(Val)))
    return 0;

  unsigned Opcode = I->getOpcode();

  if (Opcode == Instruction::FAdd || Opcode == Instruction::FSub) {
    ConstantFP *C0, *C1;
    Value *Opnd0 = I->getOperand(0);
    Value *Opnd1 = I->getOperand(1);
    if ((C0 = dyn_cast<ConstantFP>(Opnd0)) && C0->isZero())
      Opnd0 = nullptr;

    if ((C1 = dyn_cast<ConstantFP>(Opnd1)) && C1->isZero())
      Opnd1 = nullptr;

    if (Opnd0) {
      if (!C0)
        Addend0.set(1, Opnd0);
      else
        Addend0.set(C0, nullptr);
    }

    if (Opnd1) {
      FAddend &Addend = Opnd0 ? Addend1 : Addend0;
      if (!C1)
        Addend.set(1, Opnd1);
      else
        Addend.set(C1, nullptr);
      if (Opcode == Instruction::FSub)
        Addend.negate();
    }

    if (Opnd0 || Opnd1)
      return Opnd0 && Opnd1 ? 2 : 1;

    // Both operands are zero. Weird!
    Addend0.set(APFloat(C0->getValueAPF().getSemantics()), nullptr);
    return 1;
  }

  if (I->getOpcode() == Instruction::FMul) {
    Value *V0 = I->getOperand(0);
    Value *V1 = I->getOperand(1);
    if (ConstantFP *C = dyn_cast<ConstantFP>(V0)) {
      Addend0.set(C, V1);
      return 1;
    }

    if (ConstantFP *C = dyn_cast<ConstantFP>(V1)) {
      Addend0.set(C, V0);
      return 1;
    }
  }

  return 0;
}

// Try to break *this* addend into two addends. e.g. Suppose this addend is
// <2.3, V>, and V = X + Y, by calling this function, we obtain two addends,
// i.e. <2.3, X> and <2.3, Y>.
unsigned FAddend::drillAddendDownOneStep
  (FAddend &Addend0, FAddend &Addend1) const {
  if (isConstant())
    return 0;

  unsigned BreakNum = FAddend::drillValueDownOneStep(Val, Addend0, Addend1);
  if (!BreakNum || Coeff.isOne())
    return BreakNum;

  Addend0.Scale(Coeff);

  if (BreakNum == 2)
    Addend1.Scale(Coeff);

  return BreakNum;
}

Value *FAddCombine::simplify(Instruction *I) {
  assert(I->hasAllowReassoc() && I->hasNoSignedZeros() &&
         "Expected 'reassoc'+'nsz' instruction");

  // Currently we are not able to handle vector type.
  if (I->getType()->isVectorTy())
    return nullptr;

  assert((I->getOpcode() == Instruction::FAdd ||
          I->getOpcode() == Instruction::FSub) && "Expect add/sub");

  // Save the instruction before calling other member-functions.
  Instr = I;

  FAddend Opnd0, Opnd1, Opnd0_0, Opnd0_1, Opnd1_0, Opnd1_1;

  unsigned OpndNum = FAddend::drillValueDownOneStep(I, Opnd0, Opnd1);

  // Step 1: Expand the 1st addend into Opnd0_0 and Opnd0_1.
  unsigned Opnd0_ExpNum = 0;
  unsigned Opnd1_ExpNum = 0;

  if (!Opnd0.isConstant())
    Opnd0_ExpNum = Opnd0.drillAddendDownOneStep(Opnd0_0, Opnd0_1);

  // Step 2: Expand the 2nd addend into Opnd1_0 and Opnd1_1.
  if (OpndNum == 2 && !Opnd1.isConstant())
    Opnd1_ExpNum = Opnd1.drillAddendDownOneStep(Opnd1_0, Opnd1_1);

  // Step 3: Try to optimize Opnd0_0 + Opnd0_1 + Opnd1_0 + Opnd1_1
  if (Opnd0_ExpNum && Opnd1_ExpNum) {
    AddendVect AllOpnds;
    AllOpnds.push_back(&Opnd0_0);
    AllOpnds.push_back(&Opnd1_0);
    if (Opnd0_ExpNum == 2)
      AllOpnds.push_back(&Opnd0_1);
    if (Opnd1_ExpNum == 2)
      AllOpnds.push_back(&Opnd1_1);

    // Compute instruction quota. We should save at least one instruction.
    unsigned InstQuota = 0;

    Value *V0 = I->getOperand(0);
    Value *V1 = I->getOperand(1);
    InstQuota = ((!isa<Constant>(V0) && V0->hasOneUse()) &&
                 (!isa<Constant>(V1) && V1->hasOneUse())) ? 2 : 1;

    if (Value *R = simplifyFAdd(AllOpnds, InstQuota))
      return R;
  }

  if (OpndNum != 2) {
    // The input instruction is : "I=0.0 +/- V". If the "V" were able to be
    // splitted into two addends, say "V = X - Y", the instruction would have
    // been optimized into "I = Y - X" in the previous steps.
    //
    const FAddendCoef &CE = Opnd0.getCoef();
    return CE.isOne() ? Opnd0.getSymVal() : nullptr;
  }

  // step 4: Try to optimize Opnd0 + Opnd1_0 [+ Opnd1_1]
  if (Opnd1_ExpNum) {
    AddendVect AllOpnds;
    AllOpnds.push_back(&Opnd0);
    AllOpnds.push_back(&Opnd1_0);
    if (Opnd1_ExpNum == 2)
      AllOpnds.push_back(&Opnd1_1);

    if (Value *R = simplifyFAdd(AllOpnds, 1))
      return R;
  }

  // step 5: Try to optimize Opnd1 + Opnd0_0 [+ Opnd0_1]
  if (Opnd0_ExpNum) {
    AddendVect AllOpnds;
    AllOpnds.push_back(&Opnd1);
    AllOpnds.push_back(&Opnd0_0);
    if (Opnd0_ExpNum == 2)
      AllOpnds.push_back(&Opnd0_1);

    if (Value *R = simplifyFAdd(AllOpnds, 1))
      return R;
  }

  return nullptr;
}

Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {
  unsigned AddendNum = Addends.size();
  assert(AddendNum <= 4 && "Too many addends");

  // For saving intermediate results;
  unsigned NextTmpIdx = 0;
  FAddend TmpResult[3];

  // Simplified addends are placed <SimpVect>.
  AddendVect SimpVect;

  // The outer loop works on one symbolic-value at a time. Suppose the input
  // addends are : <a1, x>, <b1, y>, <a2, x>, <c1, z>, <b2, y>, ...
  // The symbolic-values will be processed in this order: x, y, z.
  for (unsigned SymIdx = 0; SymIdx < AddendNum; SymIdx++) {

    const FAddend *ThisAddend = Addends[SymIdx];
    if (!ThisAddend) {
      // This addend was processed before.
      continue;
    }

    Value *Val = ThisAddend->getSymVal();

    // If the resulting expr has constant-addend, this constant-addend is
    // desirable to reside at the top of the resulting expression tree. Placing
    // constant close to super-expr(s) will potentially reveal some
    // optimization opportunities in super-expr(s). Here we do not implement
    // this logic intentionally and rely on SimplifyAssociativeOrCommutative
    // call later.

    unsigned StartIdx = SimpVect.size();
    SimpVect.push_back(ThisAddend);

    // The inner loop collects addends sharing same symbolic-value, and these
    // addends will be later on folded into a single addend. Following above
    // example, if the symbolic value "y" is being processed, the inner loop
    // will collect two addends "<b1,y>" and "<b2,Y>". These two addends will
    // be later on folded into "<b1+b2, y>".
    for (unsigned SameSymIdx = SymIdx + 1;
         SameSymIdx < AddendNum; SameSymIdx++) {
      const FAddend *T = Addends[SameSymIdx];
      if (T && T->getSymVal() == Val) {
        // Set null such that next iteration of the outer loop will not process
        // this addend again.
        Addends[SameSymIdx] = nullptr;
        SimpVect.push_back(T);
      }
    }

    // If multiple addends share same symbolic value, fold them together.
    if (StartIdx + 1 != SimpVect.size()) {
      FAddend &R = TmpResult[NextTmpIdx ++];
      R = *SimpVect[StartIdx];
      for (unsigned Idx = StartIdx + 1; Idx < SimpVect.size(); Idx++)
        R += *SimpVect[Idx];

      // Pop all addends being folded and push the resulting folded addend.
      SimpVect.resize(StartIdx);
      if (!R.isZero()) {
        SimpVect.push_back(&R);
      }
    }
  }

  assert((NextTmpIdx <= std::size(TmpResult) + 1) && "out-of-bound access");

  Value *Result;
  if (!SimpVect.empty())
    Result = createNaryFAdd(SimpVect, InstrQuota);
  else {
    // The addition is folded to 0.0.
    Result = ConstantFP::get(Instr->getType(), 0.0);
  }

  return Result;
}

Value *FAddCombine::createNaryFAdd
  (const AddendVect &Opnds, unsigned InstrQuota) {
  assert(!Opnds.empty() && "Expect at least one addend");

  // Step 1: Check if the # of instructions needed exceeds the quota.

  unsigned InstrNeeded = calcInstrNumber(Opnds);
  if (InstrNeeded > InstrQuota)
    return nullptr;

  initCreateInstNum();

  // step 2: Emit the N-ary addition.
  // Note that at most three instructions are involved in Fadd-InstCombine: the
  // addition in question, and at most two neighboring instructions.
  // The resulting optimized addition should have at least one less instruction
  // than the original addition expression tree. This implies that the resulting
  // N-ary addition has at most two instructions, and we don't need to worry
  // about tree-height when constructing the N-ary addition.

  Value *LastVal = nullptr;
  bool LastValNeedNeg = false;

  // Iterate the addends, creating fadd/fsub using adjacent two addends.
  for (const FAddend *Opnd : Opnds) {
    bool NeedNeg;
    Value *V = createAddendVal(*Opnd, NeedNeg);
    if (!LastVal) {
      LastVal = V;
      LastValNeedNeg = NeedNeg;
      continue;
    }

    if (LastValNeedNeg == NeedNeg) {
      LastVal = createFAdd(LastVal, V);
      continue;
    }

    if (LastValNeedNeg)
      LastVal = createFSub(V, LastVal);
    else
      LastVal = createFSub(LastVal, V);

    LastValNeedNeg = false;
  }

  if (LastValNeedNeg) {
    LastVal = createFNeg(LastVal);
  }

#ifndef NDEBUG
  assert(CreateInstrNum == InstrNeeded &&
         "Inconsistent in instruction numbers");
#endif

  return LastVal;
}

Value *FAddCombine::createFSub(Value *Opnd0, Value *Opnd1) {
  Value *V = Builder.CreateFSub(Opnd0, Opnd1);
  if (Instruction *I = dyn_cast<Instruction>(V))
    createInstPostProc(I);
  return V;
}

Value *FAddCombine::createFNeg(Value *V) {
  Value *NewV = Builder.CreateFNeg(V);
  if (Instruction *I = dyn_cast<Instruction>(NewV))
    createInstPostProc(I, true); // fneg's don't receive instruction numbers.
  return NewV;
}

Value *FAddCombine::createFAdd(Value *Opnd0, Value *Opnd1) {
  Value *V = Builder.CreateFAdd(Opnd0, Opnd1);
  if (Instruction *I = dyn_cast<Instruction>(V))
    createInstPostProc(I);
  return V;
}

Value *FAddCombine::createFMul(Value *Opnd0, Value *Opnd1) {
  Value *V = Builder.CreateFMul(Opnd0, Opnd1);
  if (Instruction *I = dyn_cast<Instruction>(V))
    createInstPostProc(I);
  return V;
}

void FAddCombine::createInstPostProc(Instruction *NewInstr, bool NoNumber) {
  NewInstr->setDebugLoc(Instr->getDebugLoc());

  // Keep track of the number of instruction created.
  if (!NoNumber)
    incCreateInstNum();

  // Propagate fast-math flags
  NewInstr->setFastMathFlags(Instr->getFastMathFlags());
}

// Return the number of instruction needed to emit the N-ary addition.
// NOTE: Keep this function in sync with createAddendVal().
unsigned FAddCombine::calcInstrNumber(const AddendVect &Opnds) {
  unsigned OpndNum = Opnds.size();
  unsigned InstrNeeded = OpndNum - 1;

  // Adjust the number of instructions needed to emit the N-ary add.
  for (const FAddend *Opnd : Opnds) {
    if (Opnd->isConstant())
      continue;

    // The constant check above is really for a few special constant
    // coefficients.
    if (isa<UndefValue>(Opnd->getSymVal()))
      continue;

    const FAddendCoef &CE = Opnd->getCoef();
    // Let the addend be "c * x". If "c == +/-1", the value of the addend
    // is immediately available; otherwise, it needs exactly one instruction
    // to evaluate the value.
    if (!CE.isMinusOne() && !CE.isOne())
      InstrNeeded++;
  }
  return InstrNeeded;
}

// Input Addend        Value           NeedNeg(output)
// ================================================================
// Constant C          C               false
// <+/-1, V>           V               coefficient is -1
// <2/-2, V>          "fadd V, V"      coefficient is -2
// <C, V>             "fmul V, C"      false
//
// NOTE: Keep this function in sync with FAddCombine::calcInstrNumber.
Value *FAddCombine::createAddendVal(const FAddend &Opnd, bool &NeedNeg) {
  const FAddendCoef &Coeff = Opnd.getCoef();

  if (Opnd.isConstant()) {
    NeedNeg = false;
    return Coeff.getValue(Instr->getType());
  }

  Value *OpndVal = Opnd.getSymVal();

  if (Coeff.isMinusOne() || Coeff.isOne()) {
    NeedNeg = Coeff.isMinusOne();
    return OpndVal;
  }

  if (Coeff.isTwo() || Coeff.isMinusTwo()) {
    NeedNeg = Coeff.isMinusTwo();
    return createFAdd(OpndVal, OpndVal);
  }

  NeedNeg = false;
  return createFMul(OpndVal, Coeff.getValue(Instr->getType()));
}

// Checks if any operand is negative and we can convert add to sub.
// This function checks for following negative patterns
//   ADD(XOR(OR(Z, NOT(C)), C)), 1) == NEG(AND(Z, C))
//   ADD(XOR(AND(Z, C), C), 1) == NEG(OR(Z, ~C))
//   XOR(AND(Z, C), (C + 1)) == NEG(OR(Z, ~C)) if C is even
static Value *checkForNegativeOperand(BinaryOperator &I,
                                      InstCombiner::BuilderTy &Builder) {
  Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);

  // This function creates 2 instructions to replace ADD, we need at least one
  // of LHS or RHS to have one use to ensure benefit in transform.
  if (!LHS->hasOneUse() && !RHS->hasOneUse())
    return nullptr;

  Value *X = nullptr, *Y = nullptr, *Z = nullptr;
  const APInt *C1 = nullptr, *C2 = nullptr;

  // if ONE is on other side, swap
  if (match(RHS, m_Add(m_Value(X), m_One())))
    std::swap(LHS, RHS);

  if (match(LHS, m_Add(m_Value(X), m_One()))) {
    // if XOR on other side, swap
    if (match(RHS, m_Xor(m_Value(Y), m_APInt(C1))))
      std::swap(X, RHS);

    if (match(X, m_Xor(m_Value(Y), m_APInt(C1)))) {
      // X = XOR(Y, C1), Y = OR(Z, C2), C2 = NOT(C1) ==> X == NOT(AND(Z, C1))
      // ADD(ADD(X, 1), RHS) == ADD(X, ADD(RHS, 1)) == SUB(RHS, AND(Z, C1))
      if (match(Y, m_Or(m_Value(Z), m_APInt(C2))) && (*C2 == ~(*C1))) {
        Value *NewAnd = Builder.CreateAnd(Z, *C1);
        return Builder.CreateSub(RHS, NewAnd, "sub");
      } else if (match(Y, m_And(m_Value(Z), m_APInt(C2))) && (*C1 == *C2)) {
        // X = XOR(Y, C1), Y = AND(Z, C2), C2 == C1 ==> X == NOT(OR(Z, ~C1))
        // ADD(ADD(X, 1), RHS) == ADD(X, ADD(RHS, 1)) == SUB(RHS, OR(Z, ~C1))
        Value *NewOr = Builder.CreateOr(Z, ~(*C1));
        return Builder.CreateSub(RHS, NewOr, "sub");
      }
    }
  }

  // Restore LHS and RHS
  LHS = I.getOperand(0);
  RHS = I.getOperand(1);

  // if XOR is on other side, swap
  if (match(RHS, m_Xor(m_Value(Y), m_APInt(C1))))
    std::swap(LHS, RHS);

  // C2 is ODD
  // LHS = XOR(Y, C1), Y = AND(Z, C2), C1 == (C2 + 1) => LHS == NEG(OR(Z, ~C2))
  // ADD(LHS, RHS) == SUB(RHS, OR(Z, ~C2))
  if (match(LHS, m_Xor(m_Value(Y), m_APInt(C1))))
    if (C1->countr_zero() == 0)
      if (match(Y, m_And(m_Value(Z), m_APInt(C2))) && *C1 == (*C2 + 1)) {
        Value *NewOr = Builder.CreateOr(Z, ~(*C2));
        return Builder.CreateSub(RHS, NewOr, "sub");
      }
  return nullptr;
}

/// Wrapping flags may allow combining constants separated by an extend.
static Instruction *foldNoWrapAdd(BinaryOperator &Add,
                                  InstCombiner::BuilderTy &Builder) {
  Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1);
  Type *Ty = Add.getType();
  Constant *Op1C;
  if (!match(Op1, m_Constant(Op1C)))
    return nullptr;

  // Try this match first because it results in an add in the narrow type.
  // (zext (X +nuw C2)) + C1 --> zext (X + (C2 + trunc(C1)))
  Value *X;
  const APInt *C1, *C2;
  if (match(Op1, m_APInt(C1)) &&
      match(Op0, m_ZExt(m_NUWAddLike(m_Value(X), m_APInt(C2)))) &&
      C1->isNegative() && C1->sge(-C2->sext(C1->getBitWidth()))) {
    APInt NewC = *C2 + C1->trunc(C2->getBitWidth());
    // If the smaller add will fold to zero, we don't need to check one use.
    if (NewC.isZero())
      return new ZExtInst(X, Ty);
    // Otherwise only do this if the existing zero extend will be removed.
    if (Op0->hasOneUse())
      return new ZExtInst(
          Builder.CreateNUWAdd(X, ConstantInt::get(X->getType(), NewC)), Ty);
  }

  // More general combining of constants in the wide type.
  // (sext (X +nsw NarrowC)) + C --> (sext X) + (sext(NarrowC) + C)
  // or (zext nneg (X +nsw NarrowC)) + C --> (sext X) + (sext(NarrowC) + C)
  Constant *NarrowC;
  if (match(Op0, m_OneUse(m_SExtLike(
                     m_NSWAddLike(m_Value(X), m_Constant(NarrowC)))))) {
    Value *WideC = Builder.CreateSExt(NarrowC, Ty);
    Value *NewC = Builder.CreateAdd(WideC, Op1C);
    Value *WideX = Builder.CreateSExt(X, Ty);
    return BinaryOperator::CreateAdd(WideX, NewC);
  }
  // (zext (X +nuw NarrowC)) + C --> (zext X) + (zext(NarrowC) + C)
  if (match(Op0,
            m_OneUse(m_ZExt(m_NUWAddLike(m_Value(X), m_Constant(NarrowC)))))) {
    Value *WideC = Builder.CreateZExt(NarrowC, Ty);
    Value *NewC = Builder.CreateAdd(WideC, Op1C);
    Value *WideX = Builder.CreateZExt(X, Ty);
    return BinaryOperator::CreateAdd(WideX, NewC);
  }
  return nullptr;
}

Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
  Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1);
  Type *Ty = Add.getType();
  Constant *Op1C;
  if (!match(Op1, m_ImmConstant(Op1C)))
    return nullptr;

  if (Instruction *NV = foldBinOpIntoSelectOrPhi(Add))
    return NV;

  if (Instruction *FoldedLogic = foldBinOpSelectBinOp(Add))
    return FoldedLogic;

  Value *X;
  Constant *Op00C;

  // add (sub C1, X), C2 --> sub (add C1, C2), X
  if (match(Op0, m_Sub(m_Constant(Op00C), m_Value(X))))
    return BinaryOperator::CreateSub(ConstantExpr::getAdd(Op00C, Op1C), X);

  Value *Y;

  // add (sub X, Y), -1 --> add (not Y), X
  if (match(Op0, m_OneUse(m_Sub(m_Value(X), m_Value(Y)))) &&
      match(Op1, m_AllOnes()))
    return BinaryOperator::CreateAdd(Builder.CreateNot(Y), X);

  // zext(bool) + C -> bool ? C + 1 : C
  if (match(Op0, m_ZExt(m_Value(X))) &&
      X->getType()->getScalarSizeInBits() == 1)
    return createSelectInstWithUnknownProfile(X, InstCombiner::AddOne(Op1C),
                                              Op1);
  // sext(bool) + C -> bool ? C - 1 : C
  if (match(Op0, m_SExt(m_Value(X))) &&
      X->getType()->getScalarSizeInBits() == 1)
    return createSelectInstWithUnknownProfile(X, InstCombiner::SubOne(Op1C),
                                              Op1);

  // ~X + C --> (C-1) - X
  if (match(Op0, m_Not(m_Value(X)))) {
    // ~X + C has NSW and (C-1) won't oveflow => (C-1)-X can have NSW
    auto *COne = ConstantInt::get(Op1C->getType(), 1);
    bool WillNotSOV = willNotOverflowSignedSub(Op1C, COne, Add);
    BinaryOperator *Res =
        BinaryOperator::CreateSub(ConstantExpr::getSub(Op1C, COne), X);
    Res->setHasNoSignedWrap(Add.hasNoSignedWrap() && WillNotSOV);
    return Res;
  }

  // (iN X s>> (N - 1)) + 1 --> zext (X > -1)
  const APInt *C;
  unsigned BitWidth = Ty->getScalarSizeInBits();
  if (match(Op0, m_OneUse(m_AShr(m_Value(X),
                                 m_SpecificIntAllowPoison(BitWidth - 1)))) &&
      match(Op1, m_One()))
    return new ZExtInst(Builder.CreateIsNotNeg(X, "isnotneg"), Ty);

  if (!match(Op1, m_APInt(C)))
    return nullptr;

  // (X | Op01C) + Op1C --> X + (Op01C + Op1C) iff the `or` is actually an `add`
  Constant *Op01C;
  if (match(Op0, m_DisjointOr(m_Value(X), m_ImmConstant(Op01C)))) {
    BinaryOperator *NewAdd =
        BinaryOperator::CreateAdd(X, ConstantExpr::getAdd(Op01C, Op1C));
    NewAdd->setHasNoSignedWrap(Add.hasNoSignedWrap() &&
                               willNotOverflowSignedAdd(Op01C, Op1C, Add));
    NewAdd->setHasNoUnsignedWrap(Add.hasNoUnsignedWrap());
    return NewAdd;
  }

  // (X | C2) + C --> (X | C2) ^ C2 iff (C2 == -C)
  const APInt *C2;
  if (match(Op0, m_Or(m_Value(), m_APInt(C2))) && *C2 == -*C)
    return BinaryOperator::CreateXor(Op0, ConstantInt::get(Add.getType(), *C2));

  if (C->isSignMask()) {
    // If wrapping is not allowed, then the addition must set the sign bit:
    // X + (signmask) --> X | signmask
    if (Add.hasNoSignedWrap() || Add.hasNoUnsignedWrap())
      return BinaryOperator::CreateDisjointOr(Op0, Op1);

    // If wrapping is allowed, then the addition flips the sign bit of LHS:
    // X + (signmask) --> X ^ signmask
    return BinaryOperator::CreateXor(Op0, Op1);
  }

  // Is this add the last step in a convoluted sext?
  // add(zext(xor i16 X, -32768), -32768) --> sext X
  if (match(Op0, m_ZExt(m_Xor(m_Value(X), m_APInt(C2)))) &&
      C2->isMinSignedValue() && C2->sext(Ty->getScalarSizeInBits()) == *C)
    return CastInst::Create(Instruction::SExt, X, Ty);

  if (match(Op0, m_Xor(m_Value(X), m_APInt(C2)))) {
    // (X ^ signmask) + C --> (X + (signmask ^ C))
    if (C2->isSignMask())
      return BinaryOperator::CreateAdd(X, ConstantInt::get(Ty, *C2 ^ *C));

    // If X has no bits set other than an xor mask,
    // xor is equivalent to sub with no borrow between bits:
    // add (xor X, C2), C --> sub (C2 + C), X
    KnownBits LHSKnown = computeKnownBits(X, &Add);
    if ((*C2 | LHSKnown.Zero).isAllOnes())
      return BinaryOperator::CreateSub(ConstantInt::get(Ty, *C2 + *C), X);

    // Look for a math+logic pattern that corresponds to sext-in-register of a
    // value with cleared high bits. Convert that into a pair of shifts:
    // add (xor X, 0x80), 0xF..F80 --> (X << ShAmtC) >>s ShAmtC
    // add (xor X, 0xF..F80), 0x80 --> (X << ShAmtC) >>s ShAmtC
    if (Op0->hasOneUse() && *C2 == -(*C)) {
      unsigned BitWidth = Ty->getScalarSizeInBits();
      unsigned ShAmt = 0;
      if (C->isPowerOf2())
        ShAmt = BitWidth - C->logBase2() - 1;
      else if (C2->isPowerOf2())
        ShAmt = BitWidth - C2->logBase2() - 1;
      if (ShAmt &&
          MaskedValueIsZero(X, APInt::getHighBitsSet(BitWidth, ShAmt), &Add)) {
        Constant *ShAmtC = ConstantInt::get(Ty, ShAmt);
        Value *NewShl = Builder.CreateShl(X, ShAmtC, "sext");
        return BinaryOperator::CreateAShr(NewShl, ShAmtC);
      }
    }
  }

  if (C->isOne() && Op0->hasOneUse()) {
    // add (sext i1 X), 1 --> zext (not X)
    // TODO: The smallest IR representation is (select X, 0, 1), and that would
    // not require the one-use check. But we need to remove a transform in
    // visitSelect and make sure that IR value tracking for select is equal or
    // better than for these ops.
    if (match(Op0, m_SExt(m_Value(X))) &&
        X->getType()->getScalarSizeInBits() == 1)
      return new ZExtInst(Builder.CreateNot(X), Ty);

    // Shifts and add used to flip and mask off the low bit:
    // add (ashr (shl i32 X, 31), 31), 1 --> and (not X), 1
    const APInt *C3;
    if (match(Op0, m_AShr(m_Shl(m_Value(X), m_APInt(C2)), m_APInt(C3))) &&
        C2 == C3 && *C2 == Ty->getScalarSizeInBits() - 1) {
      Value *NotX = Builder.CreateNot(X);
      return BinaryOperator::CreateAnd(NotX, ConstantInt::get(Ty, 1));
    }
  }

  // umax(X, C) + -C --> usub.sat(X, C)
  if (match(Op0, m_OneUse(m_UMax(m_Value(X), m_SpecificInt(-*C)))))
    return replaceInstUsesWith(
        Add, Builder.CreateBinaryIntrinsic(
                 Intrinsic::usub_sat, X, ConstantInt::get(Add.getType(), -*C)));
  // uadd.sat(X, C) + -C --> umin(X, ~C)
  // The saturating add gives X + C or UMAX, so subtracting C leaves X or
  // UMAX - C. Note UMAX - C == ~C.
  {
    APInt SatC = -*C;
    if (match(Op0, m_OneUse(m_Intrinsic<Intrinsic::uadd_sat>(
                       m_Value(X), m_SpecificInt(SatC)))))
      return replaceInstUsesWith(
          Add, Builder.CreateBinaryIntrinsic(Intrinsic::umin, X,
                                             ConstantInt::get(Ty, ~SatC)));
  }
  // Fold (add (zext (add X, -C)), C) -> (zext X) if X u>= C.
  // Truncate C to the narrow type to avoid mismatched width comparisons.
  {
    const APInt *InnerC;
    if (match(Op0, m_ZExt(m_Add(m_Value(X), m_APIntAllowPoison(InnerC))))) {
      unsigned NarrowBW = InnerC->getBitWidth();
      if (C->isIntN(NarrowBW)) {
        APInt NarrowC = C->trunc(NarrowBW);
        const SimplifyQuery Q = SQ.getWithInstruction(&Add);
        if (*InnerC == -NarrowC &&
            (NarrowC.isOne()
                 ? llvm::isKnownNonZero(X, Q)
                 : computeKnownBits(X, &Add).getMinValue().uge(NarrowC)))
          return new ZExtInst(X, Ty);
      }
    }
  }

  return nullptr;
}

// match variations of a^2 + 2*a*b + b^2
//
// to reuse the code between the FP and Int versions, the instruction OpCodes
//  and constant types have been turned into template parameters.
//
// Mul2Rhs: The constant to perform the multiplicative equivalent of X*2 with;
//  should be `m_SpecificFP(2.0)` for FP and `m_SpecificInt(1)` for Int
//  (we're matching `X<<1` instead of `X*2` for Int)
template <bool FP, typename Mul2Rhs>
static bool matchesSquareSum(BinaryOperator &I, Mul2Rhs M2Rhs, Value *&A,
                             Value *&B) {
  constexpr unsigned MulOp = FP ? Instruction::FMul : Instruction::Mul;
  constexpr unsigned AddOp = FP ? Instruction::FAdd : Instruction::Add;
  constexpr unsigned Mul2Op = FP ? Instruction::FMul : Instruction::Shl;

  // (a * a) + (((a * 2) + b) * b)
  if (match(&I, m_c_BinOp(
                    AddOp, m_OneUse(m_BinOp(MulOp, m_Value(A), m_Deferred(A))),
                    m_OneUse(m_c_BinOp(
                        MulOp,
                        m_c_BinOp(AddOp, m_BinOp(Mul2Op, m_Deferred(A), M2Rhs),
                                  m_Value(B)),
                        m_Deferred(B))))))
    return true;

  // ((a * b) * 2)  or ((a * 2) * b)
  // +
  // (a * a + b * b) or (b * b + a * a)
  return match(
      &I, m_c_BinOp(
              AddOp,
              m_CombineOr(
                  m_OneUse(m_BinOp(
                      Mul2Op, m_BinOp(MulOp, m_Value(A), m_Value(B)), M2Rhs)),
                  m_OneUse(m_c_BinOp(MulOp, m_BinOp(Mul2Op, m_Value(A), M2Rhs),
                                     m_Value(B)))),
              m_OneUse(
                  m_c_BinOp(AddOp, m_BinOp(MulOp, m_Deferred(A), m_Deferred(A)),
                            m_BinOp(MulOp, m_Deferred(B), m_Deferred(B))))));
}

// Fold integer variations of a^2 + 2*a*b + b^2 -> (a + b)^2
Instruction *InstCombinerImpl::foldSquareSumInt(BinaryOperator &I) {
  Value *A, *B;
  if (matchesSquareSum</*FP*/ false>(I, m_SpecificInt(1), A, B)) {
    Value *AB = Builder.CreateAdd(A, B);
    return BinaryOperator::CreateMul(AB, AB);
  }
  return nullptr;
}

// Fold floating point variations of a^2 + 2*a*b + b^2 -> (a + b)^2
// Requires `nsz` and `reassoc`.
Instruction *InstCombinerImpl::foldSquareSumFP(BinaryOperator &I) {
  assert(I.hasAllowReassoc() && I.hasNoSignedZeros() && "Assumption mismatch");
  Value *A, *B;
  if (matchesSquareSum</*FP*/ true>(I, m_SpecificFP(2.0), A, B)) {
    Value *AB = Builder.CreateFAddFMF(A, B, &I);
    return BinaryOperator::CreateFMulFMF(AB, AB, &I);
  }
  return nullptr;
}

// Matches multiplication expression Op * C where C is a constant. Returns the
// constant value in C and the other operand in Op. Returns true if such a
// match is found.
static bool MatchMul(Value *E, Value *&Op, APInt &C) {
  const APInt *AI;
  if (match(E, m_Mul(m_Value(Op), m_APInt(AI)))) {
    C = *AI;
    return true;
  }
  if (match(E, m_Shl(m_Value(Op), m_APInt(AI)))) {
    C = APInt(AI->getBitWidth(), 1);
    C <<= *AI;
    return true;
  }
  return false;
}

// Matches remainder expression Op % C where C is a constant. Returns the
// constant value in C and the other operand in Op. Returns the signedness of
// the remainder operation in IsSigned. Returns true if such a match is
// found.
static bool MatchRem(Value *E, Value *&Op, APInt &C, bool &IsSigned) {
  const APInt *AI;
  IsSigned = false;
  if (match(E, m_SRem(m_Value(Op), m_APInt(AI)))) {
    IsSigned = true;
    C = *AI;
    return true;
  }
  if (match(E, m_URem(m_Value(Op), m_APInt(AI)))) {
    C = *AI;
    return true;
  }
  if (match(E, m_And(m_Value(Op), m_APInt(AI))) && (*AI + 1).isPowerOf2()) {
    C = *AI + 1;
    return true;
  }
  return false;
}

// Matches division expression Op / C with the given signedness as indicated
// by IsSigned, where C is a constant. Returns the constant value in C and the
// other operand in Op. Returns true if such a match is found.
static bool MatchDiv(Value *E, Value *&Op, APInt &C, bool IsSigned) {
  const APInt *AI;
  if (IsSigned && match(E, m_SDiv(m_Value(Op), m_APInt(AI)))) {
    C = *AI;
    return true;
  }
  if (!IsSigned) {
    if (match(E, m_UDiv(m_Value(Op), m_APInt(AI)))) {
      C = *AI;
      return true;
    }
    if (match(E, m_LShr(m_Value(Op), m_APInt(AI)))) {
      C = APInt(AI->getBitWidth(), 1);
      C <<= *AI;
      return true;
    }
  }
  return false;
}

// Returns whether C0 * C1 with the given signedness overflows.
static bool MulWillOverflow(APInt &C0, APInt &C1, bool IsSigned) {
  bool overflow;
  if (IsSigned)
    (void)C0.smul_ov(C1, overflow);
  else
    (void)C0.umul_ov(C1, overflow);
  return overflow;
}

// Simplifies X % C0 + (( X / C0 ) % C1) * C0 to X % (C0 * C1), where (C0 * C1)
// does not overflow.
// Simplifies (X / C0) * C1 + (X % C0) * C2 to
// (X / C0) * (C1 - C2 * C0) + X * C2
Value *InstCombinerImpl::SimplifyAddWithRemainder(BinaryOperator &I) {
  Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
  Value *X, *MulOpV;
  APInt C0, MulOpC;
  bool IsSigned;
  // Match I = X % C0 + MulOpV * C0
  if (((MatchRem(LHS, X, C0, IsSigned) && MatchMul(RHS, MulOpV, MulOpC)) ||
       (MatchRem(RHS, X, C0, IsSigned) && MatchMul(LHS, MulOpV, MulOpC))) &&
      C0 == MulOpC) {
    Value *RemOpV;
    APInt C1;
    bool Rem2IsSigned;
    // Match MulOpC = RemOpV % C1
    if (MatchRem(MulOpV, RemOpV, C1, Rem2IsSigned) &&
        IsSigned == Rem2IsSigned) {
      Value *DivOpV;
      APInt DivOpC;
      // Match RemOpV = X / C0
      if (MatchDiv(RemOpV, DivOpV, DivOpC, IsSigned) && X == DivOpV &&
          C0 == DivOpC && !MulWillOverflow(C0, C1, IsSigned)) {
        Value *NewDivisor = ConstantInt::get(X->getType(), C0 * C1);
        return IsSigned ? Builder.CreateSRem(X, NewDivisor, "srem")
                        : Builder.CreateURem(X, NewDivisor, "urem");
      }
    }
  }

  // Match I = (X / C0) * C1 + (X % C0) * C2.
  auto FoldDivRem = [&](Value *DivSide, Value *RemSide) -> Value * {
    Value *Div, *Rem;
    APInt C1, C2;
    if (!DivSide->hasOneUse() || !MatchMul(DivSide, Div, C1))
      Div = DivSide, C1 = APInt(I.getType()->getScalarSizeInBits(), 1);
    if (!RemSide->hasOneUse() || !MatchMul(RemSide, Rem, C2))
      Rem = RemSide, C2 = APInt(I.getType()->getScalarSizeInBits(), 1);
    Value *DivOpV;
    APInt DivOpC;
    if (MatchRem(Rem, X, C0, IsSigned) &&
        MatchDiv(Div, DivOpV, DivOpC, IsSigned) && X == DivOpV &&
        C0 == DivOpC &&
        // Avoid unprofitable replacement of and with mul.
        !(C1.isOne() && !IsSigned && DivOpC.isPowerOf2() && DivOpC != 2)) {
      APInt NewC = C1 - C2 * C0;
      if (!NewC.isZero() && !Rem->hasOneUse())
        return nullptr;
      if (!isGuaranteedNotToBeUndef(X, &AC, &I, &DT))
        return nullptr;
      Value *MulXC2 = Builder.CreateMul(X, ConstantInt::get(X->getType(), C2));
      if (NewC.isZero())
        return MulXC2;
      return Builder.CreateAdd(
          Builder.CreateMul(Div, ConstantInt::get(X->getType(), NewC)), MulXC2);
    }
    return nullptr;
  };
  if (Value *V = FoldDivRem(LHS, RHS))
    return V;
  if (Value *V = FoldDivRem(RHS, LHS))
    return V;

  return nullptr;
}

/// Fold
///   (1 << NBits) - 1
/// Into:
///   ~(-(1 << NBits))
/// Because a 'not' is better for bit-tracking analysis and other transforms
/// than an 'add'. The new shl is always nsw, and is nuw if old `and` was.
static Instruction *canonicalizeLowbitMask(BinaryOperator &I,
                                           InstCombiner::BuilderTy &Builder) {
  Value *NBits;
  if (!match(&I, m_Add(m_OneUse(m_Shl(m_One(), m_Value(NBits))), m_AllOnes())))
    return nullptr;

  Constant *MinusOne = Constant::getAllOnesValue(NBits->getType());
  Value *NotMask = Builder.CreateShl(MinusOne, NBits, "notmask");
  // Be wary of constant folding.
  if (auto *BOp = dyn_cast<BinaryOperator>(NotMask)) {
    // Always NSW. But NUW propagates from `add`.
    BOp->setHasNoSignedWrap();
    BOp->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
  }

  return BinaryOperator::CreateNot(NotMask, I.getName());
}

static Instruction *foldToUnsignedSaturatedAdd(BinaryOperator &I) {
  assert(I.getOpcode() == Instruction::Add && "Expecting add instruction");
  Type *Ty = I.getType();
  auto getUAddSat = [&]() {
    return Intrinsic::getOrInsertDeclaration(I.getModule(), Intrinsic::uadd_sat,
                                             Ty);
  };

  // add (umin X, ~Y), Y --> uaddsat X, Y
  Value *X, *Y;
  if (match(&I, m_c_Add(m_c_UMin(m_Value(X), m_Not(m_Value(Y))),
                        m_Deferred(Y))))
    return CallInst::Create(getUAddSat(), { X, Y });

  // add (umin X, ~C), C --> uaddsat X, C
  const APInt *C, *NotC;
  if (match(&I, m_Add(m_UMin(m_Value(X), m_APInt(NotC)), m_APInt(C))) &&
      *C == ~*NotC)
    return CallInst::Create(getUAddSat(), { X, ConstantInt::get(Ty, *C) });

  return nullptr;
}

// Transform:
//  (add A, (shl (neg B), Y))
//      -> (sub A, (shl B, Y))
static Instruction *combineAddSubWithShlAddSub(InstCombiner::BuilderTy &Builder,
                                               const BinaryOperator &I) {
  Value *A, *B, *Cnt;
  if (match(&I,
            m_c_Add(m_OneUse(m_Shl(m_OneUse(m_Neg(m_Value(B))), m_Value(Cnt))),
                    m_Value(A)))) {
    Value *NewShl = Builder.CreateShl(B, Cnt);
    return BinaryOperator::CreateSub(A, NewShl);
  }
  return nullptr;
}

/// Try to reduce signed division by power-of-2 to an arithmetic shift right.
static Instruction *foldAddToAshr(BinaryOperator &Add) {
  // Division must be by power-of-2, but not the minimum signed value.
  Value *X;
  const APInt *DivC;
  if (!match(Add.getOperand(0), m_SDiv(m_Value(X), m_Power2(DivC))) ||
      DivC->isNegative())
    return nullptr;

  // Rounding is done by adding -1 if the dividend (X) is negative and has any
  // low bits set. It recognizes two canonical patterns:
  // 1. For an 'ugt' cmp with the signed minimum value (SMIN), the
  //    pattern is: sext (icmp ugt (X & (DivC - 1)), SMIN).
  // 2. For an 'eq' cmp, the pattern's: sext (icmp eq X & (SMIN + 1), SMIN + 1).
  // Note that, by the time we end up here, if possible, ugt has been
  // canonicalized into eq.
  const APInt *MaskC, *MaskCCmp;
  CmpPredicate Pred;
  if (!match(Add.getOperand(1),
             m_SExt(m_ICmp(Pred, m_And(m_Specific(X), m_APInt(MaskC)),
                           m_APInt(MaskCCmp)))))
    return nullptr;

  if ((Pred != ICmpInst::ICMP_UGT || !MaskCCmp->isSignMask()) &&
      (Pred != ICmpInst::ICMP_EQ || *MaskCCmp != *MaskC))
    return nullptr;

  APInt SMin = APInt::getSignedMinValue(Add.getType()->getScalarSizeInBits());
  bool IsMaskValid = Pred == ICmpInst::ICMP_UGT
                         ? (*MaskC == (SMin | (*DivC - 1)))
                         : (*DivC == 2 && *MaskC == SMin + 1);
  if (!IsMaskValid)
    return nullptr;

  // (X / DivC) + sext ((X & (SMin | (DivC - 1)) >u SMin) --> X >>s log2(DivC)
  return BinaryOperator::CreateAShr(
      X, ConstantInt::get(Add.getType(), DivC->exactLogBase2()));
}

Instruction *InstCombinerImpl::foldAddLikeCommutative(Value *LHS, Value *RHS,
                                                      bool NSW, bool NUW) {
  Value *A, *B, *C;
  if (match(LHS, m_Sub(m_Value(A), m_Value(B))) &&
      match(RHS, m_Sub(m_Value(C), m_Specific(A)))) {
    Instruction *R = BinaryOperator::CreateSub(C, B);
    bool NSWOut = NSW && match(LHS, m_NSWSub(m_Value(), m_Value())) &&
                  match(RHS, m_NSWSub(m_Value(), m_Value()));

    bool NUWOut = match(LHS, m_NUWSub(m_Value(), m_Value())) &&
                  match(RHS, m_NUWSub(m_Value(), m_Value()));
    R->setHasNoSignedWrap(NSWOut);
    R->setHasNoUnsignedWrap(NUWOut);
    return R;
  }

  // ((X s/ C1) << C2) + X => X s% -C1 where -C1 is 1 << C2
  const APInt *C1, *C2;
  if (match(LHS, m_Shl(m_SDiv(m_Specific(RHS), m_APInt(C1)), m_APInt(C2)))) {
    APInt One(C2->getBitWidth(), 1);
    APInt MinusC1 = -(*C1);
    if (MinusC1 == (One << *C2)) {
      Constant *NewRHS = ConstantInt::get(RHS->getType(), MinusC1);
      return BinaryOperator::CreateSRem(RHS, NewRHS);
    }
  }

  // (A + C) + (B & ~C) == A + (B | C)
  if (match(LHS, m_c_Add(m_Value(A), m_APInt(C1))) &&
      match(RHS, m_c_And(m_Value(B), m_SpecificInt(~*C1)))) {
    // Replacing one add with {or, add}. Avoid growth if both sides are shared.
    if (!LHS->hasOneUse() && !RHS->hasOneUse())
      return nullptr;

    bool NSWOut = NSW && match(LHS, m_NSWAdd(m_Value(), m_Value()));
    bool NUWOut = NUW && match(LHS, m_NUWAdd(m_Value(), m_Value()));
    Value *NewOr =
        Builder.CreateOr(B, Constant::getIntegerValue(LHS->getType(), *C1));
    Instruction *NewAdd = BinaryOperator::CreateAdd(A, NewOr);
    NewAdd->setHasNoSignedWrap(NSWOut);
    NewAdd->setHasNoUnsignedWrap(NUWOut);
    return NewAdd;
  }

  return nullptr;
}

Instruction *InstCombinerImpl::
    canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
        BinaryOperator &I) {
  assert((I.getOpcode() == Instruction::Add ||
          I.getOpcode() == Instruction::Or ||
          I.getOpcode() == Instruction::Sub) &&
         "Expecting add/or/sub instruction");

  // We have a subtraction/addition between a (potentially truncated) *logical*
  // right-shift of X and a "select".
  Value *X, *Select;
  Instruction *LowBitsToSkip, *Extract;
  if (!match(&I, m_c_BinOp(m_TruncOrSelf(m_Instruction(
                               Extract, m_LShr(m_Value(X),
                                               m_Instruction(LowBitsToSkip)))),
                           m_Value(Select))))
    return nullptr;

  // `add`/`or` is commutative; but for `sub`, "select" *must* be on RHS.
  if (I.getOpcode() == Instruction::Sub && I.getOperand(1) != Select)
    return nullptr;

  Type *XTy = X->getType();
  bool HadTrunc = I.getType() != XTy;

  // If there was a truncation of extracted value, then we'll need to produce
  // one extra instruction, so we need to ensure one instruction will go away.
  if (HadTrunc && !match(&I, m_c_BinOp(m_OneUse(m_Value()), m_Value())))
    return nullptr;

  // Extraction should extract high NBits bits, with shift amount calculated as:
  //   low bits to skip = shift bitwidth - high bits to extract
  // The shift amount itself may be extended, and we need to look past zero-ext
  // when matching NBits, that will matter for matching later.
  Value *NBits;
  if (!match(LowBitsToSkip,
             m_ZExtOrSelf(m_Sub(m_SpecificInt(XTy->getScalarSizeInBits()),
                                m_ZExtOrSelf(m_Value(NBits))))))
    return nullptr;

  // Sign-extending value can be zero-extended if we `sub`tract it,
  // or sign-extended otherwise.
  auto SkipExtInMagic = [&I](Value *&V) {
    if (I.getOpcode() == Instruction::Sub)
      match(V, m_ZExtOrSelf(m_Value(V)));
    else
      match(V, m_SExtOrSelf(m_Value(V)));
  };

  // Now, finally validate the sign-extending magic.
  // `select` itself may be appropriately extended, look past that.
  SkipExtInMagic(Select);

  CmpPredicate Pred;
  const APInt *Thr;
  Value *SignExtendingValue, *Zero;
  bool ShouldSignext;
  // It must be a select between two values we will later establish to be a
  // sign-extending value and a zero constant. The condition guarding the
  // sign-extension must be based on a sign bit of the same X we had in `lshr`.
  if (!match(Select, m_Select(m_ICmp(Pred, m_Specific(X), m_APInt(Thr)),
                              m_Value(SignExtendingValue), m_Value(Zero))) ||
      !isSignBitCheck(Pred, *Thr, ShouldSignext))
    return nullptr;

  // icmp-select pair is commutative.
  if (!ShouldSignext)
    std::swap(SignExtendingValue, Zero);

  // If we should not perform sign-extension then we must add/or/subtract zero.
  if (!match(Zero, m_Zero()))
    return nullptr;
  // Otherwise, it should be some constant, left-shifted by the same NBits we
  // had in `lshr`. Said left-shift can also be appropriately extended.
  // Again, we must look past zero-ext when looking for NBits.
  SkipExtInMagic(SignExtendingValue);
  Constant *SignExtendingValueBaseConstant;
  if (!match(SignExtendingValue,
             m_Shl(m_Constant(SignExtendingValueBaseConstant),
                   m_ZExtOrSelf(m_Specific(NBits)))))
    return nullptr;
  // If we `sub`, then the constant should be one, else it should be all-ones.
  if (I.getOpcode() == Instruction::Sub
          ? !match(SignExtendingValueBaseConstant, m_One())
          : !match(SignExtendingValueBaseConstant, m_AllOnes()))
    return nullptr;

  auto *NewAShr = BinaryOperator::CreateAShr(X, LowBitsToSkip,
                                             Extract->getName() + ".sext");
  NewAShr->copyIRFlags(Extract); // Preserve `exact`-ness.
  if (!HadTrunc)
    return NewAShr;

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

/// This is a specialization of a more general transform from
/// foldUsingDistributiveLaws. If that code can be made to work optimally
/// for multi-use cases or propagating nsw/nuw, then we would not need this.
static Instruction *factorizeMathWithShlOps(BinaryOperator &I,
                                            InstCombiner::BuilderTy &Builder) {
  // TODO: Also handle mul by doubling the shift amount?
  assert((I.getOpcode() == Instruction::Add ||
          I.getOpcode() == Instruction::Sub) &&
         "Expected add/sub");
  auto *Op0 = dyn_cast<BinaryOperator>(I.getOperand(0));
  auto *Op1 = dyn_cast<BinaryOperator>(I.getOperand(1));
  if (!Op0 || !Op1 || !(Op0->hasOneUse() || Op1->hasOneUse()))
    return nullptr;

  Value *X, *Y, *ShAmt;
  if (!match(Op0, m_Shl(m_Value(X), m_Value(ShAmt))) ||
      !match(Op1, m_Shl(m_Value(Y), m_Specific(ShAmt))))
    return nullptr;

  // No-wrap propagates only when all ops have no-wrap.
  bool HasNSW = I.hasNoSignedWrap() && Op0->hasNoSignedWrap() &&
                Op1->hasNoSignedWrap();
  bool HasNUW = I.hasNoUnsignedWrap() && Op0->hasNoUnsignedWrap() &&
                Op1->hasNoUnsignedWrap();

  // add/sub (X << ShAmt), (Y << ShAmt) --> (add/sub X, Y) << ShAmt
  Value *NewMath = Builder.CreateBinOp(I.getOpcode(), X, Y);
  if (auto *NewI = dyn_cast<BinaryOperator>(NewMath)) {
    NewI->setHasNoSignedWrap(HasNSW);
    NewI->setHasNoUnsignedWrap(HasNUW);
  }
  auto *NewShl = BinaryOperator::CreateShl(NewMath, ShAmt);
  NewShl->setHasNoSignedWrap(HasNSW);
  NewShl->setHasNoUnsignedWrap(HasNUW);
  return NewShl;
}

/// Reduce a sequence of masked half-width multiplies to a single multiply.
/// ((XLow * YHigh) + (YLow * XHigh)) << HalfBits) + (XLow * YLow) --> X * Y
static Instruction *foldBoxMultiply(BinaryOperator &I) {
  unsigned BitWidth = I.getType()->getScalarSizeInBits();
  // Skip the odd bitwidth types.
  if ((BitWidth & 0x1))
    return nullptr;

  unsigned HalfBits = BitWidth >> 1;
  APInt HalfMask = APInt::getMaxValue(HalfBits);

  // ResLo = (CrossSum << HalfBits) + (YLo * XLo)
  Value *XLo, *YLo;
  Value *CrossSum;
  // Require one-use on the multiply to avoid increasing the number of
  // multiplications.
  if (!match(&I, m_c_Add(m_Shl(m_Value(CrossSum), m_SpecificInt(HalfBits)),
                         m_OneUse(m_Mul(m_Value(YLo), m_Value(XLo))))))
    return nullptr;

  // XLo = X & HalfMask
  // YLo = Y & HalfMask
  // TODO: Refactor with SimplifyDemandedBits or KnownBits known leading zeros
  // to enhance robustness
  Value *X, *Y;
  if (!match(XLo, m_And(m_Value(X), m_SpecificInt(HalfMask))) ||
      !match(YLo, m_And(m_Value(Y), m_SpecificInt(HalfMask))))
    return nullptr;

  // CrossSum = (X' * (Y >> Halfbits)) + (Y' * (X >> HalfBits))
  // X' can be either X or XLo in the pattern (and the same for Y')
  if (match(CrossSum,
            m_c_Add(m_c_Mul(m_LShr(m_Specific(Y), m_SpecificInt(HalfBits)),
                            m_CombineOr(m_Specific(X), m_Specific(XLo))),
                    m_c_Mul(m_LShr(m_Specific(X), m_SpecificInt(HalfBits)),
                            m_CombineOr(m_Specific(Y), m_Specific(YLo))))))
    return BinaryOperator::CreateMul(X, Y);

  return nullptr;
}

/// Return true if X + (Y-1) is provably non-wrapping in X's type
static bool checkDivCeilNUW(Value *X, Value *Y, const SimplifyQuery &SQ) {
  ConstantRange CRX = computeConstantRange(X, /*ForSigned=*/false, SQ);
  ConstantRange CRY = computeConstantRange(Y, /*ForSigned=*/false, SQ);
  APInt MinY = CRY.getUnsignedMin();
  APInt MaxX = CRX.getUnsignedMax();
  APInt MaxY = CRY.getUnsignedMax();

  return !MinY.isZero() && !MaxX.ugt(-MaxY);
}

/// Fold the div_ceil idiom in both forms:
///   add(udiv(X, Y), zext(icmp ne(urem(X, Y), 0)))
///     -> udiv(add nuw(X, Y - 1), Y)
///   add(zext(udiv(X, Y)), zext(icmp ne(urem(X, Y), 0)))
///     -> zext(udiv(add nuw(X, Y - 1), Y))
/// The zext form applies when udiv/urem operate in a narrower type than the
/// add.
Instruction *InstCombinerImpl::foldDivCeil(BinaryOperator &I) {
  Value *X, *Y;

  auto UDivPat = m_OneUse(m_UDiv(m_Value(X), m_Value(Y)));
  auto URemPat = m_OneUse(m_URem(m_Deferred(X), m_Deferred(Y)));
  auto ICmpPat = m_OneUse(m_SpecificICmp(ICmpInst::ICMP_NE, URemPat, m_Zero()));
  auto DivPat = m_OneUse(m_ZExtOrSelf(UDivPat));
  auto ZExtCmpPat = m_OneUse(m_ZExt(ICmpPat));

  if (!match(&I, m_c_Add(DivPat, ZExtCmpPat)) || !checkDivCeilNUW(X, Y, SQ))
    return nullptr;

  Value *YMinusOne =
      Builder.CreateAdd(Y, ConstantInt::getAllOnesValue(Y->getType()));
  Value *NUWAdd = Builder.CreateNUWAdd(X, YMinusOne);
  if (X->getType() != I.getType()) {
    Value *Div = Builder.CreateUDiv(NUWAdd, Y);
    return new ZExtInst(Div, I.getType());
  }
  return BinaryOperator::CreateUDiv(NUWAdd, Y);
}

Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
  if (Value *V = simplifyAddInst(I.getOperand(0), I.getOperand(1),
                                 I.hasNoSignedWrap(), I.hasNoUnsignedWrap(),
                                 SQ.getWithInstruction(&I)))
    return replaceInstUsesWith(I, V);

  if (SimplifyAssociativeOrCommutative(I))
    return &I;

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

  if (Instruction *Phi = foldBinopWithPhiOperands(I))
    return Phi;

  // (A*B)+(A*C) -> A*(B+C) etc
  if (Value *V = foldUsingDistributiveLaws(I))
    return replaceInstUsesWith(I, V);

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

  if (Instruction *R = factorizeMathWithShlOps(I, Builder))
    return R;

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

  if (Instruction *X = foldNoWrapAdd(I, Builder))
    return X;

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

  if (Instruction *R = combineAddSubWithShlAddSub(Builder, I))
    return R;

  Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
  if (Instruction *R = foldAddLikeCommutative(LHS, RHS, I.hasNoSignedWrap(),
                                              I.hasNoUnsignedWrap()))
    return R;
  if (Instruction *R = foldAddLikeCommutative(RHS, LHS, I.hasNoSignedWrap(),
                                              I.hasNoUnsignedWrap()))
    return R;
  Type *Ty = I.getType();
  if (Ty->isIntOrIntVectorTy(1))
    return BinaryOperator::CreateXor(LHS, RHS);

  // X + X --> X << 1
  if (LHS == RHS) {
    auto *Shl = BinaryOperator::CreateShl(LHS, ConstantInt::get(Ty, 1));
    Shl->setHasNoSignedWrap(I.hasNoSignedWrap());
    Shl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap());
    return Shl;
  }

  Value *A, *B;
  if (match(LHS, m_Neg(m_Value(A)))) {
    // -A + -B --> -(A + B)
    if (match(RHS, m_Neg(m_Value(B))))
      return BinaryOperator::CreateNeg(Builder.CreateAdd(A, B));

    // -A + B --> B - A
    auto *Sub = BinaryOperator::CreateSub(RHS, A);
    auto *OB0 = cast<OverflowingBinaryOperator>(LHS);
    Sub->setHasNoSignedWrap(I.hasNoSignedWrap() && OB0->hasNoSignedWrap());

    return Sub;
  }

  // A + -B  -->  A - B
  if (match(RHS, m_Neg(m_Value(B)))) {
    auto *Sub = BinaryOperator::CreateSub(LHS, B);
    auto *OBO = cast<OverflowingBinaryOperator>(RHS);
    Sub->setHasNoSignedWrap(I.hasNoSignedWrap() && OBO->hasNoSignedWrap());
    return Sub;
  }

  if (Value *V = checkForNegativeOperand(I, Builder))
    return replaceInstUsesWith(I, V);

  // (A + 1) + ~B --> A - B
  // ~B + (A + 1) --> A - B
  // (~B + A) + 1 --> A - B
  // (A + ~B) + 1 --> A - B
  // This relies on the ~B == -1-B identity.
  if (match(&I, m_c_BinOp(m_Add(m_Value(A), m_One()), m_Not(m_Value(B)))) ||
      match(&I, m_BinOp(m_c_Add(m_Not(m_Value(B)), m_Value(A)), m_One())))
    return BinaryOperator::CreateSub(A, B);

  {
    // (A + C) + ~B --> A - B + (C-1)
    // ~B + (A + C) --> A - B + (C-1)
    // (~B + A) + C --> A - B + (C-1)
    // (A + ~B) + C --> A - B + (C-1)
    // With constant C, subtraction of one is free, so we replace three ops
    // (two adds and a bitwise-not) with two (sub and add).
    const APInt *C;
    if (match(&I, m_c_BinOp(m_OneUse(m_Add(m_Value(A), m_APIntAllowPoison(C))),
                            m_Not(m_Value(B)))) ||
        match(&I, m_BinOp(m_OneUse(m_c_Add(m_Not(m_Value(B)), m_Value(A))),
                          m_APIntAllowPoison(C)))) {
      Value *Sub = Builder.CreateSub(A, B);
      return BinaryOperator::CreateAdd(Sub, ConstantInt::get(Ty, *C - 1));
    }
  }

  // (A + RHS) + RHS --> A + (RHS << 1)
  if (match(LHS, m_OneUse(m_c_Add(m_Value(A), m_Specific(RHS)))))
    return BinaryOperator::CreateAdd(A, Builder.CreateShl(RHS, 1, "reass.add"));

  // LHS + (A + LHS) --> A + (LHS << 1)
  if (match(RHS, m_OneUse(m_c_Add(m_Value(A), m_Specific(LHS)))))
    return BinaryOperator::CreateAdd(A, Builder.CreateShl(LHS, 1, "reass.add"));

  {
    // (A + C1) + (C2 - B) --> (A - B) + (C1 + C2)
    Constant *C1, *C2;
    if (match(&I, m_c_Add(m_Add(m_Value(A), m_ImmConstant(C1)),
                          m_Sub(m_ImmConstant(C2), m_Value(B)))) &&
        (LHS->hasOneUse() || RHS->hasOneUse())) {
      Value *Sub = Builder.CreateSub(A, B);
      return BinaryOperator::CreateAdd(Sub, ConstantExpr::getAdd(C1, C2));
    }

    // Canonicalize a constant sub operand as an add operand for better folding:
    // (C1 - A) + B --> (B - A) + C1
    if (match(&I, m_c_Add(m_OneUse(m_Sub(m_ImmConstant(C1), m_Value(A))),
                          m_Value(B)))) {
      Value *Sub = Builder.CreateSub(B, A, "reass.sub");
      return BinaryOperator::CreateAdd(Sub, C1);
    }
  }

  // X % C0 + (( X / C0 ) % C1) * C0 => X % (C0 * C1)
  if (Value *V = SimplifyAddWithRemainder(I)) return replaceInstUsesWith(I, V);

  const APInt *C1;
  // (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit
  if (match(&I, m_c_Add(m_And(m_Value(A), m_APInt(C1)), m_Deferred(A))) &&
      C1->isPowerOf2() && (ComputeNumSignBits(A) > C1->countl_zero())) {
    Constant *NewMask = ConstantInt::get(RHS->getType(), *C1 - 1);
    return BinaryOperator::CreateAnd(A, NewMask);
  }

  // ZExt (B - A) + ZExt(A) --> ZExt(B)
  if ((match(RHS, m_ZExt(m_Value(A))) &&
       match(LHS, m_ZExt(m_NUWSub(m_Value(B), m_Specific(A))))) ||
      (match(LHS, m_ZExt(m_Value(A))) &&
       match(RHS, m_ZExt(m_NUWSub(m_Value(B), m_Specific(A))))))
    return new ZExtInst(B, LHS->getType());

  // zext(A) + sext(A) --> 0 if A is i1
  if (match(&I, m_c_BinOp(m_ZExt(m_Value(A)), m_SExt(m_Deferred(A)))) &&
      A->getType()->isIntOrIntVectorTy(1))
    return replaceInstUsesWith(I, Constant::getNullValue(I.getType()));

  // sext(A < B) + zext(A > B) => ucmp/scmp(A, B)
  CmpPredicate LTPred, GTPred;
  if (match(&I,
            m_c_Add(m_SExt(m_c_ICmp(LTPred, m_Value(A), m_Value(B))),
                    m_ZExt(m_c_ICmp(GTPred, m_Deferred(A), m_Deferred(B))))) &&
      A->getType()->isIntOrIntVectorTy()) {
    if (ICmpInst::isGT(LTPred)) {
      std::swap(LTPred, GTPred);
      std::swap(A, B);
    }

    if (ICmpInst::isLT(LTPred) && ICmpInst::isGT(GTPred) &&
        ICmpInst::isSigned(LTPred) == ICmpInst::isSigned(GTPred))
      return replaceInstUsesWith(
          I, Builder.CreateIntrinsic(
                 Ty,
                 ICmpInst::isSigned(LTPred) ? Intrinsic::scmp : Intrinsic::ucmp,
                 {A, B}));
  }

  // A+B --> A|B iff A and B have no bits set in common.
  WithCache<const Value *> LHSCache(LHS), RHSCache(RHS);
  switch (
      getNoCommonBitsSetResult(LHSCache, RHSCache, SQ.getWithInstruction(&I))) {
  case NoCommonBitsSetResult::Known:
    return BinaryOperator::CreateDisjointOr(LHS, RHS);
  case NoCommonBitsSetResult::OnlyIfUndefIgnored:
    return BinaryOperator::CreateOr(LHS, RHS);
  case NoCommonBitsSetResult::Unknown:
    break;
  }

  if (Instruction *Ext = narrowMathIfNoOverflow(I))
    return Ext;

  // (add (xor A, B) (and A, B)) --> (or A, B)
  // (add (and A, B) (xor A, B)) --> (or A, B)
  if (match(&I, m_c_BinOp(m_Xor(m_Value(A), m_Value(B)),
                          m_c_And(m_Deferred(A), m_Deferred(B)))))
    return BinaryOperator::CreateOr(A, B);

  // (add (or A, B) (and A, B)) --> (add A, B)
  // (add (and A, B) (or A, B)) --> (add A, B)
  if (match(&I, m_c_BinOp(m_Or(m_Value(A), m_Value(B)),
                          m_c_And(m_Deferred(A), m_Deferred(B))))) {
    // Replacing operands in-place to preserve nuw/nsw flags.
    replaceOperand(I, 0, A);
    replaceOperand(I, 1, B);
    return &I;
  }

  // (add A (or A, -A)) --> (and (add A, -1) A)
  // (add A (or -A, A)) --> (and (add A, -1) A)
  // (add (or A, -A) A) --> (and (add A, -1) A)
  // (add (or -A, A) A) --> (and (add A, -1) A)
  if (match(&I, m_c_BinOp(m_Value(A), m_OneUse(m_c_Or(m_Neg(m_Deferred(A)),
                                                      m_Deferred(A)))))) {
    Value *Add =
        Builder.CreateAdd(A, Constant::getAllOnesValue(A->getType()), "",
                          I.hasNoUnsignedWrap(), I.hasNoSignedWrap());
    return BinaryOperator::CreateAnd(Add, A);
  }

  // Align-up idiom:
  // X + ((-X) & (C - 1)) --> (X + C - 1) & -C
  // ((X - 1) | (C - 1)) + 1 -> (X + C - 1) & -C
  // For a power-of-two C. Note -C == ~(C - 1), so the mask is simply the
  // inverted low-bit mask.
  {
    const APInt *LowMask;
    if (match(&I,
              m_c_Add(m_OneUse(m_And(m_Neg(m_Value(A)), m_LowBitMask(LowMask))),
                      m_Deferred(A))) ||
        match(&I, m_Add(m_OneUse(m_Or(m_Add(m_Value(A), m_AllOnes()),
                                      m_LowBitMask(LowMask))),
                        m_One()))

    ) {
      Value *NewAdd = Builder.CreateAdd(A, ConstantInt::get(Ty, *LowMask));
      return BinaryOperator::CreateAnd(NewAdd, ConstantInt::get(Ty, ~*LowMask));
    }
  }

  // Canonicalize ((A & -A) - 1) --> ((A - 1) & ~A)
  // Forms all commutable operations, and simplifies ctpop -> cttz folds.
  if (match(&I,
            m_Add(m_OneUse(m_c_And(m_Value(A), m_OneUse(m_Neg(m_Deferred(A))))),
                  m_AllOnes()))) {
    Constant *AllOnes = ConstantInt::getAllOnesValue(RHS->getType());
    Value *Dec = Builder.CreateAdd(A, AllOnes);
    Value *Not = Builder.CreateXor(A, AllOnes);
    return BinaryOperator::CreateAnd(Dec, Not);
  }

  // Disguised reassociation/factorization:
  // ~(A * C1) + A
  // ((A * -C1) - 1) + A
  // ((A * -C1) + A) - 1
  // (A * (1 - C1)) - 1
  if (match(&I,
            m_c_Add(m_OneUse(m_Not(m_OneUse(m_Mul(m_Value(A), m_APInt(C1))))),
                    m_Deferred(A)))) {
    Type *Ty = I.getType();
    Constant *NewMulC = ConstantInt::get(Ty, 1 - *C1);
    Value *NewMul = Builder.CreateMul(A, NewMulC);
    return BinaryOperator::CreateAdd(NewMul, ConstantInt::getAllOnesValue(Ty));
  }

  // (A * -2**C) + B --> B - (A << C)
  const APInt *NegPow2C;
  if (match(&I, m_c_Add(m_OneUse(m_Mul(m_Value(A), m_NegatedPower2(NegPow2C))),
                        m_Value(B)))) {
    Constant *ShiftAmtC = ConstantInt::get(Ty, NegPow2C->countr_zero());
    Value *Shl = Builder.CreateShl(A, ShiftAmtC);
    return BinaryOperator::CreateSub(B, Shl);
  }

  // Canonicalize signum variant that ends in add:
  // (A s>> (BW - 1)) + (zext (A s> 0)) --> (A s>> (BW - 1)) | (zext (A != 0))
  uint64_t BitWidth = Ty->getScalarSizeInBits();
  if (match(LHS, m_AShr(m_Value(A), m_SpecificIntAllowPoison(BitWidth - 1))) &&
      match(RHS, m_OneUse(m_ZExt(m_OneUse(m_SpecificICmp(
                     CmpInst::ICMP_SGT, m_Specific(A), m_ZeroInt())))))) {
    Value *NotZero = Builder.CreateIsNotNull(A, "isnotnull");
    Value *Zext = Builder.CreateZExt(NotZero, Ty, "isnotnull.zext");
    return BinaryOperator::CreateOr(LHS, Zext);
  }

  {
    Value *Cond, *Ext;
    Constant *C;
    // (add X, (sext/zext (icmp eq X, C)))
    //    -> (select (icmp eq X, C), (add C, (sext/zext 1)), X)
    auto CondMatcher =
        m_Value(Cond, m_SpecificICmp(ICmpInst::ICMP_EQ, m_Deferred(A),
                                     m_ImmConstant(C)));

    if (match(&I,
              m_c_Add(m_Value(A), m_Value(Ext, m_ZExtOrSExt(CondMatcher)))) &&
        Ext->hasOneUse()) {
      Value *Add = isa<ZExtInst>(Ext) ? InstCombiner::AddOne(C)
                                      : InstCombiner::SubOne(C);
      return replaceInstUsesWith(I, Builder.CreateSelect(Cond, Add, A));
    }
  }

  // (add (add A, 1), (sext (icmp ne A, 0))) => call umax(A, 1)
  if (match(LHS, m_Add(m_Value(A), m_One())) &&
      match(RHS, m_OneUse(m_SExt(m_OneUse(m_SpecificICmp(
                     ICmpInst::ICMP_NE, m_Specific(A), m_ZeroInt())))))) {
    Value *OneConst = ConstantInt::get(A->getType(), 1);
    Value *UMax = Builder.CreateBinaryIntrinsic(Intrinsic::umax, A, OneConst);
    return replaceInstUsesWith(I, UMax);
  }

  if (Instruction *Ashr = foldAddToAshr(I))
    return Ashr;

  // Ceiling division by power-of-2:
  // (X >> log2(N)) + zext(X & (N-1) != 0) --> (X + (N-1)) >> log2(N)
  // This is valid when adding (N-1) to X doesn't overflow.
  {
    Value *X;
    const APInt *ShiftAmt, *Mask;
    CmpPredicate Pred;

    // Match: (X >> C) + zext((X & Mask) != 0)
    // or:    zext((X & Mask) != 0) + (X >> C)
    if (match(&I,
              m_c_Add(m_ZExt(m_SpecificICmp(
                          ICmpInst::ICMP_NE,
                          m_And(m_Value(X), m_LowBitMask(Mask)), m_ZeroInt())),
                      m_OneUse(m_ZExtOrSelf(m_OneUse(
                          m_LShr(m_Deferred(X), m_APInt(ShiftAmt))))))) &&
        Mask->popcount() == *ShiftAmt) {

      // Check if X + Mask doesn't overflow
      unsigned Xbits = X->getType()->getScalarSizeInBits();
      unsigned Ibits = Ty->getScalarSizeInBits();
      bool NeedZext = Ibits > Xbits;
      Constant *MaskC = ConstantInt::get(Ty, Mask->zext(Ibits));
      if (NeedZext || willNotOverflowUnsignedAdd(X, MaskC, I)) {
        if (NeedZext)
          X = Builder.CreateZExt(X, Ty);
        // (X + Mask) >> ShiftAmt
        Value *Add = Builder.CreateNUWAdd(X, MaskC);
        return BinaryOperator::CreateLShr(
            Add, ConstantInt::get(Ty, ShiftAmt->zext(Ibits)));
      }
    }
  }

  // (~X) + (~Y) --> -2 - (X + Y)
  {
    // To ensure we can save instructions we need to ensure that we consume both
    // LHS/RHS (i.e they have a `not`).
    bool ConsumesLHS, ConsumesRHS;
    if (isFreeToInvert(LHS, LHS->hasOneUse(), ConsumesLHS) && ConsumesLHS &&
        isFreeToInvert(RHS, RHS->hasOneUse(), ConsumesRHS) && ConsumesRHS) {
      Value *NotLHS = getFreelyInverted(LHS, LHS->hasOneUse(), &Builder);
      Value *NotRHS = getFreelyInverted(RHS, RHS->hasOneUse(), &Builder);
      assert(NotLHS != nullptr && NotRHS != nullptr &&
             "isFreeToInvert desynced with getFreelyInverted");
      Value *LHSPlusRHS = Builder.CreateAdd(NotLHS, NotRHS);
      return BinaryOperator::CreateSub(
          ConstantInt::getSigned(RHS->getType(), -2), LHSPlusRHS);
    }
  }

  if (Instruction *R = tryFoldInstWithCtpopWithNot(&I))
    return R;

  // TODO(jingyue): Consider willNotOverflowSignedAdd and
  // willNotOverflowUnsignedAdd to reduce the number of invocations of
  // computeKnownBits.
  bool Changed = false;
  if (!I.hasNoSignedWrap() && willNotOverflowSignedAdd(LHSCache, RHSCache, I)) {
    Changed = true;
    I.setHasNoSignedWrap(true);
  }
  if (!I.hasNoUnsignedWrap() &&
      willNotOverflowUnsignedAdd(LHSCache, RHSCache, I)) {
    Changed = true;
    I.setHasNoUnsignedWrap(true);
  }

  if (Instruction *V = canonicalizeLowbitMask(I, Builder))
    return V;

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

  if (Instruction *SatAdd = foldToUnsignedSaturatedAdd(I))
    return SatAdd;

  // usub.sat(A, B) + B => umax(A, B)
  if (match(&I, m_c_BinOp(
          m_OneUse(m_Intrinsic<Intrinsic::usub_sat>(m_Value(A), m_Value(B))),
          m_Deferred(B)))) {
    return replaceInstUsesWith(I,
        Builder.CreateIntrinsic(Intrinsic::umax, {I.getType()}, {A, B}));
  }

  // ctpop(A) + ctpop(B) => ctpop(A | B) if A and B have no bits set in common.
  if (match(LHS, m_OneUse(m_Ctpop(m_Value(A)))) &&
      match(RHS, m_OneUse(m_Ctpop(m_Value(B)))) &&
      haveNoCommonBitsSet(A, B, SQ.getWithInstruction(&I)))
    return replaceInstUsesWith(
        I, Builder.CreateIntrinsic(Intrinsic::ctpop, {I.getType()},
                                   {Builder.CreateDisjointOr(A, B)}));

  // Fold the log2_ceil idiom:
  // zext(ctpop(A) >u/!= 1) + (ctlz(A, true) ^ (BW - 1))
  // -->
  // BW - ctlz(A - 1, false)
  const APInt *XorC;
  CmpPredicate Pred;
  if (match(&I, m_c_Add(m_ZExt(m_ICmp(Pred, m_Ctpop(m_Value(A)), m_One())),
                        m_OneUse(m_ZExtOrSelf(m_OneUse(
                            m_Xor(m_OneUse(m_TruncOrSelf(m_OneUse(
                                      m_Ctlz(m_Deferred(A), m_One())))),
                                  m_APInt(XorC))))))) &&
      (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_NE) &&
      *XorC == A->getType()->getScalarSizeInBits() - 1) {
    Value *Sub = Builder.CreateAdd(A, Constant::getAllOnesValue(A->getType()));
    Value *Ctlz = Builder.CreateIntrinsic(Intrinsic::ctlz, {A->getType()},
                                          {Sub, Builder.getFalse()});
    Value *Ret = Builder.CreateSub(
        ConstantInt::get(A->getType(), A->getType()->getScalarSizeInBits()),
        Ctlz, "", /*HasNUW=*/true, /*HasNSW=*/true);
    return replaceInstUsesWith(I, Builder.CreateZExtOrTrunc(Ret, I.getType()));
  }

  if (Instruction *Res = foldSquareSumInt(I))
    return Res;

  if (Instruction *Res = foldBinOpOfDisplacedShifts(I))
    return Res;

  if (Instruction *Res = foldBinOpOfSelectAndCastOfSelectCondition(I))
    return Res;

  if (Instruction *Res = foldDivCeil(I))
    return Res;

  // Re-enqueue users of the induction variable of add recurrence if we infer
  // new nuw/nsw flags.
  if (Changed) {
    PHINode *PHI;
    Value *Start, *Step;
    if (matchSimpleRecurrence(&I, PHI, Start, Step))
      Worklist.pushUsersToWorkList(*PHI);
  }

  return Changed ? &I : nullptr;
}

/// Eliminate an op from a linear interpolation (lerp) pattern.
static Instruction *factorizeLerp(BinaryOperator &I,
                                  InstCombiner::BuilderTy &Builder) {
  Value *X, *Y, *Z;
  if (!match(&I, m_c_FAdd(m_OneUse(m_c_FMul(m_Value(Y),
                                            m_OneUse(m_FSub(m_FPOne(),
                                                            m_Value(Z))))),
                          m_OneUse(m_c_FMul(m_Value(X), m_Deferred(Z))))))
    return nullptr;

  // (Y * (1.0 - Z)) + (X * Z) --> Y + Z * (X - Y) [8 commuted variants]
  Value *XY = Builder.CreateFSubFMF(X, Y, &I);
  Value *MulZ = Builder.CreateFMulFMF(Z, XY, &I);
  return BinaryOperator::CreateFAddFMF(Y, MulZ, &I);
}

/// Factor a common operand out of fadd/fsub of fmul/fdiv.
static Instruction *factorizeFAddFSub(BinaryOperator &I,
                                      InstCombiner::BuilderTy &Builder) {
  assert((I.getOpcode() == Instruction::FAdd ||
          I.getOpcode() == Instruction::FSub) && "Expecting fadd/fsub");
  assert(I.hasAllowReassoc() && I.hasNoSignedZeros() &&
         "FP factorization requires FMF");

  if (Instruction *Lerp = factorizeLerp(I, Builder))
    return Lerp;

  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
  if (!Op0->hasOneUse() || !Op1->hasOneUse())
    return nullptr;

  Value *X, *Y, *Z;
  bool IsFMul;
  if ((match(Op0, m_FMul(m_Value(X), m_Value(Z))) &&
       match(Op1, m_c_FMul(m_Value(Y), m_Specific(Z)))) ||
      (match(Op0, m_FMul(m_Value(Z), m_Value(X))) &&
       match(Op1, m_c_FMul(m_Value(Y), m_Specific(Z)))))
    IsFMul = true;
  else if (match(Op0, m_FDiv(m_Value(X), m_Value(Z))) &&
           match(Op1, m_FDiv(m_Value(Y), m_Specific(Z))))
    IsFMul = false;
  else
    return nullptr;

  // (X * Z) + (Y * Z) --> (X + Y) * Z
  // (X * Z) - (Y * Z) --> (X - Y) * Z
  // (X / Z) + (Y / Z) --> (X + Y) / Z
  // (X / Z) - (Y / Z) --> (X - Y) / Z
  bool IsFAdd = I.getOpcode() == Instruction::FAdd;
  Value *XY = IsFAdd ? Builder.CreateFAddFMF(X, Y, &I)
                     : Builder.CreateFSubFMF(X, Y, &I);

  // Bail out if we just created a denormal constant.
  // TODO: This is copied from a previous implementation. Is it necessary?
  const APFloat *C;
  if (match(XY, m_APFloat(C)) && !C->isNormal())
    return nullptr;

  return IsFMul ? BinaryOperator::CreateFMulFMF(XY, Z, &I)
                : BinaryOperator::CreateFDivFMF(XY, Z, &I);
}

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

  if (SimplifyAssociativeOrCommutative(I))
    return &I;

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

  if (Instruction *Phi = foldBinopWithPhiOperands(I))
    return Phi;

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

  // B = fadd A, 0.0
  // Z = Op B
  // can be transformed into
  // Z = Op A
  // Where Op is such that we can ignore sign of 0 in fadd
  Value *A;
  if (match(&I, m_OneUse(m_FAdd(m_Value(A), m_AnyZeroFP()))) &&
      canIgnoreSignBitOfZero(*I.use_begin()))
    return replaceInstUsesWith(I, A);

  // (-X) + Y --> Y - X
  Value *X, *Y;
  if (match(&I, m_c_FAdd(m_FNeg(m_Value(X)), m_Value(Y))))
    return BinaryOperator::CreateFSubFMF(Y, X, &I);

  // Similar to above, but look through fmul/fdiv for the negated term.
  // (-X * Y) + Z --> Z - (X * Y) [4 commuted variants]
  Value *Z;
  if (match(&I, m_c_FAdd(m_OneUse(m_c_FMul(m_FNeg(m_Value(X)), m_Value(Y))),
                         m_Value(Z)))) {
    Value *XY = Builder.CreateFMulFMF(X, Y, &I);
    return BinaryOperator::CreateFSubFMF(Z, XY, &I);
  }
  // (-X / Y) + Z --> Z - (X / Y) [2 commuted variants]
  // (X / -Y) + Z --> Z - (X / Y) [2 commuted variants]
  if (match(&I, m_c_FAdd(m_OneUse(m_FDiv(m_FNeg(m_Value(X)), m_Value(Y))),
                         m_Value(Z))) ||
      match(&I, m_c_FAdd(m_OneUse(m_FDiv(m_Value(X), m_FNeg(m_Value(Y)))),
                         m_Value(Z)))) {
    Value *XY = Builder.CreateFDivFMF(X, Y, &I);
    return BinaryOperator::CreateFSubFMF(Z, XY, &I);
  }

  // Check for (fadd double (sitofp x), y), see if we can merge this into an
  // integer add followed by a promotion.
  if (Instruction *R = foldFBinOpOfIntCasts(I))
    return R;

  Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
  // Handle specials cases for FAdd with selects feeding the operation
  if (Value *V = SimplifySelectsFeedingBinaryOp(I, LHS, RHS))
    return replaceInstUsesWith(I, V);

  if (I.hasAllowReassoc() && I.hasNoSignedZeros()) {
    if (Instruction *F = factorizeFAddFSub(I, Builder))
      return F;

    if (Instruction *F = foldSquareSumFP(I))
      return F;

    // Try to fold fadd into start value of reduction intrinsic.
    if (match(&I, m_c_FAdd(m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_fadd>(
                               m_AnyZeroFP(), m_Value(X))),
                           m_Value(Y)))) {
      // fadd (rdx 0.0, X), Y --> rdx Y, X
      return replaceInstUsesWith(
          I, Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
                                     {X->getType()}, {Y, X}, &I));
    }
    const APFloat *StartC, *C;
    if (match(LHS, m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_fadd>(
                       m_APFloat(StartC), m_Value(X)))) &&
        match(RHS, m_APFloat(C))) {
      // fadd (rdx StartC, X), C --> rdx (C + StartC), X
      Constant *NewStartC = ConstantFP::get(I.getType(), *C + *StartC);
      return replaceInstUsesWith(
          I, Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
                                     {X->getType()}, {NewStartC, X}, &I));
    }

    // (X * MulC) + X --> X * (MulC + 1.0)
    Constant *MulC;
    if (match(&I, m_c_FAdd(m_FMul(m_Value(X), m_ImmConstant(MulC)),
                           m_Deferred(X)))) {
      if (Constant *NewMulC = ConstantFoldBinaryOpOperands(
              Instruction::FAdd, MulC, ConstantFP::get(I.getType(), 1.0), DL))
        return BinaryOperator::CreateFMulFMF(X, NewMulC, &I);
    }

    // (-X - Y) + (X + Z) --> Z - Y
    if (match(&I, m_c_FAdd(m_FSub(m_FNeg(m_Value(X)), m_Value(Y)),
                           m_c_FAdd(m_Deferred(X), m_Value(Z)))))
      return BinaryOperator::CreateFSubFMF(Z, Y, &I);

    if (Value *V = FAddCombine(Builder).simplify(&I))
      return replaceInstUsesWith(I, V);
  }

  // minumum(X, Y) + maximum(X, Y) => X + Y.
  if (match(&I,
            m_c_FAdd(m_Intrinsic<Intrinsic::maximum>(m_Value(X), m_Value(Y)),
                     m_c_Intrinsic<Intrinsic::minimum>(m_Deferred(X),
                                                       m_Deferred(Y))))) {
    BinaryOperator *Result = BinaryOperator::CreateFAddFMF(X, Y, &I);
    // We cannot preserve ninf if nnan flag is not set.
    // If X is NaN and Y is Inf then in original program we had NaN + NaN,
    // while in optimized version NaN + Inf and this is a poison with ninf flag.
    if (!Result->hasNoNaNs())
      Result->setHasNoInfs(false);
    return Result;
  }

  return nullptr;
}

CommonPointerBase CommonPointerBase::compute(Value *LHS, Value *RHS) {
  CommonPointerBase Base;

  if (LHS->getType() != RHS->getType())
    return Base;

  // Collect all base pointers of LHS.
  SmallPtrSet<Value *, 16> Ptrs;
  Value *Ptr = LHS;
  while (true) {
    Ptrs.insert(Ptr);
    if (auto *GEP = dyn_cast<GEPOperator>(Ptr))
      Ptr = GEP->getPointerOperand();
    else
      break;
  }

  // Find common base and collect RHS GEPs.
  bool First = true;
  while (true) {
    if (Ptrs.contains(RHS)) {
      Base.Ptr = RHS;
      break;
    }

    if (auto *GEP = dyn_cast<GEPOperator>(RHS)) {
      Base.RHSGEPs.push_back(GEP);
      if (First) {
        First = false;
        Base.RHSNW = GEP->getNoWrapFlags();
      } else {
        Base.RHSNW = Base.RHSNW.intersectForOffsetAdd(GEP->getNoWrapFlags());
      }
      RHS = GEP->getPointerOperand();
    } else {
      // No common base.
      return Base;
    }
  }

  // Collect LHS GEPs.
  First = true;
  while (true) {
    if (LHS == Base.Ptr)
      break;

    auto *GEP = cast<GEPOperator>(LHS);
    Base.LHSGEPs.push_back(GEP);
    if (First) {
      First = false;
      Base.LHSNW = GEP->getNoWrapFlags();
    } else {
      Base.LHSNW = Base.LHSNW.intersectForOffsetAdd(GEP->getNoWrapFlags());
    }
    LHS = GEP->getPointerOperand();
  }

  return Base;
}

bool CommonPointerBase::isExpensive() const {
  unsigned NumGEPs = 0;
  auto ProcessGEPs = [&NumGEPs](ArrayRef<GEPOperator *> GEPs) {
    bool SeenMultiUse = false;
    for (GEPOperator *GEP : GEPs) {
      // Only count multi-use GEPs, excluding the first one. For the first one,
      // we will directly reuse the offset. For one-use GEPs, their offset will
      // be folded into a multi-use GEP.
      if (!GEP->hasOneUse()) {
        if (SeenMultiUse)
          ++NumGEPs;
        SeenMultiUse = true;
      }
    }
  };
  ProcessGEPs(LHSGEPs);
  ProcessGEPs(RHSGEPs);
  return NumGEPs > 2;
}

/// Optimize pointer differences into the same array into a size.  Consider:
///  &A[10] - &A[0]: we should compile this to "10".  LHS/RHS are the pointer
/// operands to the ptrtoint instructions for the LHS/RHS of the subtract.
Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
                                                   Type *Ty, bool IsNUW) {
  CommonPointerBase Base = CommonPointerBase::compute(LHS, RHS);
  if (!Base.Ptr || Base.isExpensive())
    return nullptr;

  // To avoid duplicating the offset arithmetic, rewrite the GEP to use the
  // computed offset.
  // TODO: We should probably do this even if there is only one GEP.
  bool RewriteGEPs = !Base.LHSGEPs.empty() && !Base.RHSGEPs.empty();

  Type *IdxTy = DL.getIndexType(LHS->getType());
  Value *Result = EmitGEPOffsets(Base.LHSGEPs, Base.LHSNW, IdxTy, RewriteGEPs);
  Value *Offset2 = EmitGEPOffsets(Base.RHSGEPs, Base.RHSNW, IdxTy, RewriteGEPs);

  // If this is a single inbounds GEP and the original sub was nuw,
  // then the final multiplication is also nuw.
  if (auto *I = dyn_cast<OverflowingBinaryOperator>(Result))
    if (IsNUW && match(Offset2, m_Zero()) && Base.LHSNW.isInBounds() &&
        (I->use_empty() || I->hasOneUse()) && I->hasNoSignedWrap() &&
        !I->hasNoUnsignedWrap() &&
        ((I->getOpcode() == Instruction::Mul &&
          match(I->getOperand(1), m_NonNegative())) ||
         I->getOpcode() == Instruction::Shl))
      cast<Instruction>(I)->setHasNoUnsignedWrap();

  // If we have a 2nd GEP of the same base pointer, subtract the offsets.
  // If both GEPs are inbounds, then the subtract does not have signed overflow.
  // If both GEPs are nuw and the original sub is nuw, the new sub is also nuw.
  if (!match(Offset2, m_Zero())) {
    Result =
        Builder.CreateSub(Result, Offset2, "gepdiff",
                          IsNUW && Base.LHSNW.hasNoUnsignedWrap() &&
                              Base.RHSNW.hasNoUnsignedWrap(),
                          Base.LHSNW.isInBounds() && Base.RHSNW.isInBounds());
  }

  return Builder.CreateIntCast(Result, Ty, true);
}

static Instruction *foldSubOfMinMax(BinaryOperator &I,
                                    InstCombiner::BuilderTy &Builder) {
  Value *Op0 = I.getOperand(0);
  Value *Op1 = I.getOperand(1);
  Type *Ty = I.getType();
  auto *MinMax = dyn_cast<MinMaxIntrinsic>(Op1);
  if (!MinMax)
    return nullptr;

  // sub(add(X,Y), s/umin(X,Y)) --> s/umax(X,Y)
  // sub(add(X,Y), s/umax(X,Y)) --> s/umin(X,Y)
  Value *X = MinMax->getLHS();
  Value *Y = MinMax->getRHS();
  if (match(Op0, m_c_Add(m_Specific(X), m_Specific(Y))) &&
      (Op0->hasOneUse() || Op1->hasOneUse())) {
    Intrinsic::ID InvID = getInverseMinMaxIntrinsic(MinMax->getIntrinsicID());
    Function *F = Intrinsic::getOrInsertDeclaration(I.getModule(), InvID, Ty);
    return CallInst::Create(F, {X, Y});
  }

  // sub(add(X,Y),umin(Y,Z)) --> add(X,usub.sat(Y,Z))
  // sub(add(X,Z),umin(Y,Z)) --> add(X,usub.sat(Z,Y))
  Value *Z;
  if (match(Op1, m_OneUse(m_UMin(m_Value(Y), m_Value(Z))))) {
    if (match(Op0, m_OneUse(m_c_Add(m_Specific(Y), m_Value(X))))) {
      Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, Ty, {Y, Z});
      return BinaryOperator::CreateAdd(X, USub);
    }
    if (match(Op0, m_OneUse(m_c_Add(m_Specific(Z), m_Value(X))))) {
      Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, Ty, {Z, Y});
      return BinaryOperator::CreateAdd(X, USub);
    }
  }

  // sub Op0, smin((sub nsw Op0, Z), 0) --> smax Op0, Z
  // sub Op0, smax((sub nsw Op0, Z), 0) --> smin Op0, Z
  if (MinMax->isSigned() && match(Y, m_ZeroInt()) &&
      match(X, m_NSWSub(m_Specific(Op0), m_Value(Z)))) {
    Intrinsic::ID InvID = getInverseMinMaxIntrinsic(MinMax->getIntrinsicID());
    Function *F = Intrinsic::getOrInsertDeclaration(I.getModule(), InvID, Ty);
    return CallInst::Create(F, {Op0, Z});
  }

  return nullptr;
}

Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
  if (Value *V = simplifySubInst(I.getOperand(0), I.getOperand(1),
                                 I.hasNoSignedWrap(), I.hasNoUnsignedWrap(),
                                 SQ.getWithInstruction(&I)))
    return replaceInstUsesWith(I, V);

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

  if (Instruction *Phi = foldBinopWithPhiOperands(I))
    return Phi;

  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);

  // If this is a 'B = x-(-A)', change to B = x+A.
  // We deal with this without involving Negator to preserve NSW flag.
  if (Value *V = dyn_castNegVal(Op1)) {
    BinaryOperator *Res = BinaryOperator::CreateAdd(Op0, V);

    if (const auto *BO = dyn_cast<BinaryOperator>(Op1)) {
      assert(BO->getOpcode() == Instruction::Sub &&
             "Expected a subtraction operator!");
      if (BO->hasNoSignedWrap() && I.hasNoSignedWrap())
        Res->setHasNoSignedWrap(true);
    } else {
      if (cast<Constant>(Op1)->isNotMinSignedValue() && I.hasNoSignedWrap())
        Res->setHasNoSignedWrap(true);
    }

    return Res;
  }

  // Try this before Negator to preserve NSW flag.
  if (Instruction *R = factorizeMathWithShlOps(I, Builder))
    return R;

  Constant *C;
  if (match(Op0, m_ImmConstant(C))) {
    Value *X;
    Constant *C2;

    // C-(X+C2) --> (C-C2)-X
    if (match(Op1, m_AddLike(m_Value(X), m_ImmConstant(C2)))) {
      // C-C2 never overflow, and C-(X+C2), (X+C2) has NSW/NUW
      // => (C-C2)-X can have NSW/NUW
      bool WillNotSOV = willNotOverflowSignedSub(C, C2, I);
      BinaryOperator *Res =
          BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X);

      // or disjoint is equivalent to add nuw nsw.
      bool Op1NSW = true;
      bool Op1NUW = true;

      if (auto *OBO1 = dyn_cast<OverflowingBinaryOperator>(Op1)) {
        Op1NSW = OBO1->hasNoSignedWrap();
        Op1NUW = OBO1->hasNoUnsignedWrap();
      }

      Res->setHasNoSignedWrap(I.hasNoSignedWrap() && Op1NSW && WillNotSOV);
      Res->setHasNoUnsignedWrap(I.hasNoUnsignedWrap() && Op1NUW);
      return Res;
    }
  }

  auto TryToNarrowDeduceFlags = [this, &I, &Op0, &Op1]() -> Instruction * {
    if (Instruction *Ext = narrowMathIfNoOverflow(I))
      return Ext;

    bool Changed = false;
    if (!I.hasNoSignedWrap() && willNotOverflowSignedSub(Op0, Op1, I)) {
      Changed = true;
      I.setHasNoSignedWrap(true);
    }
    if (!I.hasNoUnsignedWrap() && willNotOverflowUnsignedSub(Op0, Op1, I)) {
      Changed = true;
      I.setHasNoUnsignedWrap(true);
    }

    return Changed ? &I : nullptr;
  };

  // First, let's try to interpret `sub a, b` as `add a, (sub 0, b)`,
  // and let's try to sink `(sub 0, b)` into `b` itself. But only if this isn't
  // a pure negation used by a select that looks like abs/nabs.
  bool IsNegation = match(Op0, m_ZeroInt());
  if (!IsNegation || none_of(I.users(), match_fn(m_c_Select(m_Specific(Op1),
                                                            m_Specific(&I))))) {
    if (Value *NegOp1 = Negator::Negate(IsNegation, /* IsNSW */ IsNegation &&
                                                        I.hasNoSignedWrap(),
                                        Op1, *this))
      return BinaryOperator::CreateAdd(NegOp1, Op0);
  }
  if (IsNegation)
    return TryToNarrowDeduceFlags(); // Should have been handled in Negator!

  // (A*B)-(A*C) -> A*(B-C) etc
  if (Value *V = foldUsingDistributiveLaws(I))
    return replaceInstUsesWith(I, V);

  if (I.getType()->isIntOrIntVectorTy(1))
    return BinaryOperator::CreateXor(Op0, Op1);

  // Replace (-1 - A) with (~A).
  if (match(Op0, m_AllOnes()))
    return BinaryOperator::CreateNot(Op1);

  // (X + -1) - Y --> ~Y + X
  Value *X, *Y;
  if (match(Op0, m_OneUse(m_Add(m_Value(X), m_AllOnes()))))
    return BinaryOperator::CreateAdd(Builder.CreateNot(Op1), X);

  // if (C1 & C2) == C2 then (X & C1) - (X & C2) -> X & (C1 ^ C2)
  Constant *C1, *C2;
  if (match(Op0, m_And(m_Value(X), m_ImmConstant(C1))) &&
      match(Op1, m_And(m_Specific(X), m_ImmConstant(C2)))) {
    Value *AndC = ConstantFoldBinaryInstruction(Instruction::And, C1, C2);
    if (C2->isElementWiseEqual(AndC))
      return BinaryOperator::CreateAnd(
          X, ConstantFoldBinaryInstruction(Instruction::Xor, C1, C2));
  }

  // Reassociate sub/add sequences to create more add instructions and
  // reduce dependency chains:
  // ((X - Y) + Z) - Op1 --> (X + Z) - (Y + Op1)
  Value *Z;
  if (match(Op0, m_OneUse(m_c_Add(m_OneUse(m_Sub(m_Value(X), m_Value(Y))),
                                  m_Value(Z))))) {
    Value *XZ = Builder.CreateAdd(X, Z);
    Value *YW = Builder.CreateAdd(Y, Op1);
    return BinaryOperator::CreateSub(XZ, YW);
  }

  // ((X - Y) - Op1)  -->  X - (Y + Op1)
  if (match(Op0, m_OneUse(m_Sub(m_Value(X), m_Value(Y))))) {
    OverflowingBinaryOperator *LHSSub = cast<OverflowingBinaryOperator>(Op0);
    bool HasNUW = I.hasNoUnsignedWrap() && LHSSub->hasNoUnsignedWrap();
    bool HasNSW = HasNUW && I.hasNoSignedWrap() && LHSSub->hasNoSignedWrap();
    Value *Add = Builder.CreateAdd(Y, Op1, "", /*HasNUW=*/HasNUW,
                                   /*HasNSW=*/HasNSW);
    BinaryOperator *Sub = BinaryOperator::CreateSub(X, Add);
    Sub->setHasNoUnsignedWrap(HasNUW);
    Sub->setHasNoSignedWrap(HasNSW);
    return Sub;
  }

  // (X + C0) - (Y + C1) --> (X - Y) + (C0 - C1)
  {
    Constant *CX, *CY;
    if (match(Op0, m_OneUse(m_Add(m_Value(X), m_ImmConstant(CX)))) &&
        match(Op1, m_OneUse(m_Add(m_Value(Y), m_ImmConstant(CY))))) {
      Value *OpsSub = Builder.CreateSub(X, Y);
      Constant *ConstsSub = ConstantExpr::getSub(CX, CY);
      return BinaryOperator::CreateAdd(OpsSub, ConstsSub);
    }
  }

  // (X + Z) - (Y + Z) --> (X - Y)
  {
    Value *W, *Z;
    if (match(Op0, m_AddLike(m_Value(W), m_Value(X))) &&
        match(Op1, m_AddLike(m_Value(Y), m_Value(Z)))) {
      Instruction *R = nullptr;
      if (W == Y)
        R = BinaryOperator::CreateSub(X, Z);
      else if (W == Z)
        R = BinaryOperator::CreateSub(X, Y);
      else if (X == Y)
        R = BinaryOperator::CreateSub(W, Z);
      else if (X == Z)
        R = BinaryOperator::CreateSub(W, Y);
      if (R) {
        bool NSW = I.hasNoSignedWrap() &&
                   match(Op0, m_NSWAddLike(m_Value(), m_Value())) &&
                   match(Op1, m_NSWAddLike(m_Value(), m_Value()));

        bool NUW = I.hasNoUnsignedWrap() &&
                   match(Op1, m_NUWAddLike(m_Value(), m_Value()));
        R->setHasNoSignedWrap(NSW);
        R->setHasNoUnsignedWrap(NUW);
        return R;
      }
    }
  }

  // (~X) - (~Y) --> Y - X
  {
    // Need to ensure we can consume at least one of the `not` instructions,
    // otherwise this can inf loop.
    bool ConsumesOp0, ConsumesOp1;
    if (isFreeToInvert(Op0, Op0->hasOneUse(), ConsumesOp0) &&
        isFreeToInvert(Op1, Op1->hasOneUse(), ConsumesOp1) &&
        (ConsumesOp0 || ConsumesOp1)) {
      Value *NotOp0 = getFreelyInverted(Op0, Op0->hasOneUse(), &Builder);
      Value *NotOp1 = getFreelyInverted(Op1, Op1->hasOneUse(), &Builder);
      assert(NotOp0 != nullptr && NotOp1 != nullptr &&
             "isFreeToInvert desynced with getFreelyInverted");
      return BinaryOperator::CreateSub(NotOp1, NotOp0);
    }
  }

  auto m_AddRdx = [](Value *&Vec) {
    return m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_add>(m_Value(Vec)));
  };
  Value *V0, *V1;
  if (match(Op0, m_AddRdx(V0)) && match(Op1, m_AddRdx(V1)) &&
      V0->getType() == V1->getType()) {
    // Difference of sums is sum of differences:
    // add_rdx(V0) - add_rdx(V1) --> add_rdx(V0 - V1)
    Value *Sub = Builder.CreateSub(V0, V1);
    Value *Rdx = Builder.CreateIntrinsic(Intrinsic::vector_reduce_add,
                                         {Sub->getType()}, {Sub});
    return replaceInstUsesWith(I, Rdx);
  }

  if (Constant *C = dyn_cast<Constant>(Op0)) {
    Value *X;
    if (match(Op1, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1))
      // C - (zext bool) --> bool ? C - 1 : C
      return SelectInst::Create(X, InstCombiner::SubOne(C), C);
    if (match(Op1, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1))
      // C - (sext bool) --> bool ? C + 1 : C
      return SelectInst::Create(X, InstCombiner::AddOne(C), C);

    // C - ~X == X + (1+C)
    if (match(Op1, m_Not(m_Value(X))))
      return BinaryOperator::CreateAdd(X, InstCombiner::AddOne(C));

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

    // Try to fold constant sub into PHI values.
    if (PHINode *PN = dyn_cast<PHINode>(Op1))
      if (Instruction *R = foldOpIntoPhi(I, PN))
        return R;

    Constant *C2;

    // C-(C2-X) --> X+(C-C2)
    if (match(Op1, m_Sub(m_ImmConstant(C2), m_Value(X))))
      return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2));
  }

  const APInt *Op0C;
  if (match(Op0, m_APInt(Op0C))) {
    if (Op0C->isMask()) {
      // Turn this into a xor if LHS is 2^n-1 and the remaining bits are known
      // zero. We don't use information from dominating conditions so this
      // transform is easier to reverse if necessary.
      KnownBits RHSKnown = llvm::computeKnownBits(
          Op1, SQ.getWithInstruction(&I).getWithoutDomCondCache());
      if ((*Op0C | RHSKnown.Zero).isAllOnes())
        return BinaryOperator::CreateXor(Op1, Op0);
    }

    // C - ((C3 -nuw X) & C2) --> (C - (C2 & C3)) + (X & C2) when:
    // (C3 - ((C2 & C3) - 1)) is pow2
    // ((C2 + C3) & ((C2 & C3) - 1)) == ((C2 & C3) - 1)
    // C2 is negative pow2 || sub nuw
    const APInt *C2, *C3;
    BinaryOperator *InnerSub;
    if (match(Op1, m_OneUse(m_And(m_BinOp(InnerSub), m_APInt(C2)))) &&
        match(InnerSub, m_Sub(m_APInt(C3), m_Value(X))) &&
        (InnerSub->hasNoUnsignedWrap() || C2->isNegatedPowerOf2())) {
      APInt C2AndC3 = *C2 & *C3;
      APInt C2AndC3Minus1 = C2AndC3 - 1;
      APInt C2AddC3 = *C2 + *C3;
      if ((*C3 - C2AndC3Minus1).isPowerOf2() &&
          C2AndC3Minus1.isSubsetOf(C2AddC3)) {
        Value *And = Builder.CreateAnd(X, ConstantInt::get(I.getType(), *C2));
        return BinaryOperator::CreateAdd(
            And, ConstantInt::get(I.getType(), *Op0C - C2AndC3));
      }
    }
  }

  {
    Value *Y;
    // X-(X+Y) == -Y    X-(Y+X) == -Y
    if (match(Op1, m_c_Add(m_Specific(Op0), m_Value(Y))))
      return BinaryOperator::CreateNeg(Y);

    // (X-Y)-X == -Y
    if (match(Op0, m_Sub(m_Specific(Op1), m_Value(Y))))
      return BinaryOperator::CreateNeg(Y);
  }

  // (sub (or A, B) (and A, B)) --> (xor A, B)
  {
    Value *A, *B;
    if (match(Op1, m_And(m_Value(A), m_Value(B))) &&
        match(Op0, m_c_Or(m_Specific(A), m_Specific(B))))
      return BinaryOperator::CreateXor(A, B);
  }

  // (sub (add A, B) (or A, B)) --> (and A, B)
  {
    Value *A, *B;
    if (match(Op0, m_Add(m_Value(A), m_Value(B))) &&
        match(Op1, m_c_Or(m_Specific(A), m_Specific(B))))
      return BinaryOperator::CreateAnd(A, B);
  }

  // (sub (add A, B) (and A, B)) --> (or A, B)
  {
    Value *A, *B;
    if (match(Op0, m_Add(m_Value(A), m_Value(B))) &&
        match(Op1, m_c_And(m_Specific(A), m_Specific(B))))
      return BinaryOperator::CreateOr(A, B);
  }

  // (sub (and A, B) (or A, B)) --> neg (xor A, B)
  {
    Value *A, *B;
    if (match(Op0, m_And(m_Value(A), m_Value(B))) &&
        match(Op1, m_c_Or(m_Specific(A), m_Specific(B))) &&
        (Op0->hasOneUse() || Op1->hasOneUse()))
      return BinaryOperator::CreateNeg(Builder.CreateXor(A, B));
  }

  // (sub (or A, B), (xor A, B)) --> (and A, B)
  {
    Value *A, *B;
    if (match(Op1, m_Xor(m_Value(A), m_Value(B))) &&
        match(Op0, m_c_Or(m_Specific(A), m_Specific(B))))
      return BinaryOperator::CreateAnd(A, B);
  }

  // (sub (xor A, B) (or A, B)) --> neg (and A, B)
  {
    Value *A, *B;
    if (match(Op0, m_Xor(m_Value(A), m_Value(B))) &&
        match(Op1, m_c_Or(m_Specific(A), m_Specific(B))) &&
        (Op0->hasOneUse() || Op1->hasOneUse()))
      return BinaryOperator::CreateNeg(Builder.CreateAnd(A, B));
  }

  {
    Value *Y;
    // ((X | Y) - X) --> (~X & Y)
    if (match(Op0, m_OneUse(m_c_Or(m_Value(Y), m_Specific(Op1)))))
      return BinaryOperator::CreateAnd(
          Y, Builder.CreateNot(Op1, Op1->getName() + ".not"));
  }

  {
    // (sub (and Op1, (neg X)), Op1) --> neg (and Op1, (add X, -1))
    Value *X;
    if (match(Op0, m_OneUse(m_c_And(m_Specific(Op1),
                                    m_OneUse(m_Neg(m_Value(X))))))) {
      return BinaryOperator::CreateNeg(Builder.CreateAnd(
          Op1, Builder.CreateAdd(X, Constant::getAllOnesValue(I.getType()))));
    }
  }

  {
    // (sub (and Op1, C), Op1) --> neg (and Op1, ~C)
    Constant *C;
    if (match(Op0, m_OneUse(m_And(m_Specific(Op1), m_Constant(C))))) {
      return BinaryOperator::CreateNeg(
          Builder.CreateAnd(Op1, Builder.CreateNot(C)));
    }
  }

  {
    // (sub (xor X, (sext C)), (sext C)) => (select C, (neg X), X)
    // (sub (sext C), (xor X, (sext C))) => (select C, X, (neg X))
    Value *C, *X;
    auto m_SubXorCmp = [&C, &X](Value *LHS, Value *RHS) {
      return match(LHS, m_OneUse(m_c_Xor(m_Value(X), m_Specific(RHS)))) &&
             match(RHS, m_SExt(m_Value(C))) &&
             (C->getType()->getScalarSizeInBits() == 1);
    };
    if (m_SubXorCmp(Op0, Op1))
      return createSelectInstWithUnknownProfile(C, Builder.CreateNeg(X), X);
    if (m_SubXorCmp(Op1, Op0))
      return createSelectInstWithUnknownProfile(C, X, Builder.CreateNeg(X));
  }

  if (Instruction *R = tryFoldInstWithCtpopWithNot(&I))
    return R;

  if (Instruction *R = foldSubOfMinMax(I, Builder))
    return R;

  {
    // If we have a subtraction between some value and a select between
    // said value and something else, sink subtraction into select hands, i.e.:
    //   sub (select %Cond, %TrueVal, %FalseVal), %Op1
    //     ->
    //   select %Cond, (sub %TrueVal, %Op1), (sub %FalseVal, %Op1)
    //  or
    //   sub %Op0, (select %Cond, %TrueVal, %FalseVal)
    //     ->
    //   select %Cond, (sub %Op0, %TrueVal), (sub %Op0, %FalseVal)
    // This will result in select between new subtraction and 0.
    auto SinkSubIntoSelect =
        [Ty = I.getType()](Value *Select, Value *OtherHandOfSub,
                           auto SubBuilder) -> Instruction * {
      Value *Cond, *TrueVal, *FalseVal;
      if (!match(Select, m_OneUse(m_Select(m_Value(Cond), m_Value(TrueVal),
                                           m_Value(FalseVal)))))
        return nullptr;
      if (OtherHandOfSub != TrueVal && OtherHandOfSub != FalseVal)
        return nullptr;
      // While it is really tempting to just create two subtractions and let
      // InstCombine fold one of those to 0, it isn't possible to do so
      // because of worklist visitation order. So ugly it is.
      bool OtherHandOfSubIsTrueVal = OtherHandOfSub == TrueVal;
      Value *NewSub = SubBuilder(OtherHandOfSubIsTrueVal ? FalseVal : TrueVal);
      Constant *Zero = Constant::getNullValue(Ty);
      SelectInst *NewSel =
          SelectInst::Create(Cond, OtherHandOfSubIsTrueVal ? Zero : NewSub,
                             OtherHandOfSubIsTrueVal ? NewSub : Zero);
      // Preserve prof metadata if any.
      NewSel->copyMetadata(cast<Instruction>(*Select));
      return NewSel;
    };
    if (Instruction *NewSel = SinkSubIntoSelect(
            /*Select=*/Op0, /*OtherHandOfSub=*/Op1,
            [Builder = &Builder, Op1](Value *OtherHandOfSelect) {
              return Builder->CreateSub(OtherHandOfSelect,
                                        /*OtherHandOfSub=*/Op1);
            }))
      return NewSel;
    if (Instruction *NewSel = SinkSubIntoSelect(
            /*Select=*/Op1, /*OtherHandOfSub=*/Op0,
            [Builder = &Builder, Op0](Value *OtherHandOfSelect) {
              return Builder->CreateSub(/*OtherHandOfSub=*/Op0,
                                        OtherHandOfSelect);
            }))
      return NewSel;
  }

  // (X - (X & Y))   -->   (X & ~Y)
  if (match(Op1, m_c_And(m_Specific(Op0), m_Value(Y))) &&
      (Op1->hasOneUse() || isa<Constant>(Y)))
    return BinaryOperator::CreateAnd(
        Op0, Builder.CreateNot(Y, Y->getName() + ".not"));

  // ~X - Min/Max(~X, Y) -> ~Min/Max(X, ~Y) - X
  // ~X - Min/Max(Y, ~X) -> ~Min/Max(X, ~Y) - X
  // Min/Max(~X, Y) - ~X -> X - ~Min/Max(X, ~Y)
  // Min/Max(Y, ~X) - ~X -> X - ~Min/Max(X, ~Y)
  // As long as Y is freely invertible, this will be neutral or a win.
  // Note: We don't generate the inverse max/min, just create the 'not' of
  // it and let other folds do the rest.
  if (match(Op0, m_Not(m_Value(X))) &&
      match(Op1, m_c_MaxOrMin(m_Specific(Op0), m_Value(Y))) &&
      !Op0->hasNUsesOrMore(3) && isFreeToInvert(Y, Y->hasOneUse())) {
    Value *Not = Builder.CreateNot(Op1);
    return BinaryOperator::CreateSub(Not, X);
  }
  if (match(Op1, m_Not(m_Value(X))) &&
      match(Op0, m_c_MaxOrMin(m_Specific(Op1), m_Value(Y))) &&
      !Op1->hasNUsesOrMore(3) && isFreeToInvert(Y, Y->hasOneUse())) {
    Value *Not = Builder.CreateNot(Op0);
    return BinaryOperator::CreateSub(X, Not);
  }

  // min(X+1, Y) - min(X, Y) --> zext X < Y
  // Replacing a sub and at least one min with an icmp
  // and a zext is a potential improvement.
  if (match(Op0, m_c_SMin(m_NSWAddLike(m_Value(X), m_One()), m_Value(Y))) &&
      match(Op1, m_c_SMin(m_Specific(X), m_Specific(Y))) &&
      I.getType()->getScalarSizeInBits() != 1 &&
      (Op0->hasOneUse() || Op1->hasOneUse())) {
    Value *Cond = Builder.CreateICmpSLT(X, Y);
    return new ZExtInst(Cond, I.getType());
  }
  if (match(Op0, m_c_UMin(m_NUWAddLike(m_Value(X), m_One()), m_Value(Y))) &&
      match(Op1, m_c_UMin(m_Specific(X), m_Specific(Y))) &&
      I.getType()->getScalarSizeInBits() != 1 &&
      (Op0->hasOneUse() || Op1->hasOneUse())) {
    Value *Cond = Builder.CreateICmpULT(X, Y);
    return new ZExtInst(Cond, I.getType());
  }

  // Optimize pointer differences into the same array into a size.  Consider:
  //  &A[10] - &A[0]: we should compile this to "10".
  Value *LHSOp, *RHSOp;
  if (match(Op0, m_PtrToIntOrAddr(m_Value(LHSOp))) &&
      match(Op1, m_PtrToIntOrAddr(m_Value(RHSOp))))
    if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType(),
                                               I.hasNoUnsignedWrap()))
      return replaceInstUsesWith(I, Res);

  // trunc(p)-trunc(q) -> trunc(p-q)
  if (match(Op0, m_Trunc(m_PtrToIntOrAddr(m_Value(LHSOp)))) &&
      match(Op1, m_Trunc(m_PtrToIntOrAddr(m_Value(RHSOp)))))
    if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType(),
                                               /* IsNUW */ false))
      return replaceInstUsesWith(I, Res);

  auto MatchSubOfZExtOfPtrToIntOrAddr = [&]() {
    if (match(Op0, m_ZExt(m_PtrToIntSameSize(DL, m_Value(LHSOp)))) &&
        match(Op1, m_ZExt(m_PtrToIntSameSize(DL, m_Value(RHSOp)))))
      return true;
    if (match(Op0, m_ZExt(m_PtrToAddr(m_Value(LHSOp)))) &&
        match(Op1, m_ZExt(m_PtrToAddr(m_Value(RHSOp)))))
      return true;
    // Special case for non-canonical ptrtoint in constant expression,
    // where the zext has been folded into the ptrtoint.
    if (match(Op0, m_ZExt(m_PtrToIntSameSize(DL, m_Value(LHSOp)))) &&
        match(Op1, m_PtrToInt(m_Value(RHSOp))))
      return true;
    return false;
  };
  if (MatchSubOfZExtOfPtrToIntOrAddr()) {
    if (auto *GEP = dyn_cast<GEPOperator>(LHSOp)) {
      if (GEP->getPointerOperand() == RHSOp) {
        if (GEP->hasNoUnsignedWrap() || GEP->hasNoUnsignedSignedWrap()) {
          Value *Offset = EmitGEPOffset(GEP);
          Value *Res = GEP->hasNoUnsignedWrap()
                           ? Builder.CreateZExt(
                                 Offset, I.getType(), "",
                                 /*IsNonNeg=*/GEP->hasNoUnsignedSignedWrap())
                           : Builder.CreateSExt(Offset, I.getType());
          return replaceInstUsesWith(I, Res);
        }
      }
    }
  }

  // Canonicalize a shifty way to code absolute value to the common pattern.
  // There are 2 potential commuted variants.
  // We're relying on the fact that we only do this transform when the shift has
  // exactly 2 uses and the xor has exactly 1 use (otherwise, we might increase
  // instructions).
  Value *A;
  const APInt *ShAmt;
  Type *Ty = I.getType();
  unsigned BitWidth = Ty->getScalarSizeInBits();
  if (match(Op1, m_AShr(m_Value(A), m_APInt(ShAmt))) &&
      Op1->hasNUses(2) && *ShAmt == BitWidth - 1 &&
      match(Op0, m_OneUse(m_c_Xor(m_Specific(A), m_Specific(Op1))))) {
    // B = ashr i32 A, 31 ; smear the sign bit
    // sub (xor A, B), B  ; flip bits if negative and subtract -1 (add 1)
    // --> (A < 0) ? -A : A
    Value *IsNeg = Builder.CreateIsNeg(A);
    // Copy the nsw flags from the sub to the negate.
    Value *NegA = I.hasNoUnsignedWrap()
                      ? Constant::getNullValue(A->getType())
                      : Builder.CreateNeg(A, "", I.hasNoSignedWrap());
    return SelectInst::Create(IsNeg, NegA, A);
  }

  // If we are subtracting a low-bit masked subset of some value from an add
  // of that same value with no low bits changed, that is clearing some low bits
  // of the sum:
  // sub (X + AddC), (X & AndC) --> and (X + AddC), ~AndC
  const APInt *AddC, *AndC;
  if (match(Op0, m_Add(m_Value(X), m_APInt(AddC))) &&
      match(Op1, m_And(m_Specific(X), m_APInt(AndC)))) {
    unsigned Cttz = AddC->countr_zero();
    APInt HighMask(APInt::getHighBitsSet(BitWidth, BitWidth - Cttz));
    if ((HighMask & *AndC).isZero())
      return BinaryOperator::CreateAnd(Op0, ConstantInt::get(Ty, ~(*AndC)));
  }

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

  // X - usub.sat(X, Y) => umin(X, Y)
  if (match(Op1, m_OneUse(m_Intrinsic<Intrinsic::usub_sat>(m_Specific(Op0),
                                                           m_Value(Y)))))
    return replaceInstUsesWith(
        I, Builder.CreateIntrinsic(Intrinsic::umin, {I.getType()}, {Op0, Y}));

  // umax(X, Op1) - Op1 --> usub.sat(X, Op1)
  // TODO: The one-use restriction is not strictly necessary, but it may
  //       require improving other pattern matching and/or codegen.
  if (match(Op0, m_OneUse(m_c_UMax(m_Value(X), m_Specific(Op1)))))
    return replaceInstUsesWith(
        I, Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {X, Op1}));

  // Op0 - umin(X, Op0) --> usub.sat(Op0, X)
  if (match(Op1, m_OneUse(m_c_UMin(m_Value(X), m_Specific(Op0)))))
    return replaceInstUsesWith(
        I, Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {Op0, X}));

  // Op0 - umax(X, Op0) --> 0 - usub.sat(X, Op0)
  if (match(Op1, m_OneUse(m_c_UMax(m_Value(X), m_Specific(Op0))))) {
    Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {X, Op0});
    return BinaryOperator::CreateNeg(USub);
  }

  // umin(X, Op1) - Op1 --> 0 - usub.sat(Op1, X)
  if (match(Op0, m_OneUse(m_c_UMin(m_Value(X), m_Specific(Op1))))) {
    Value *USub = Builder.CreateIntrinsic(Intrinsic::usub_sat, {Ty}, {Op1, X});
    return BinaryOperator::CreateNeg(USub);
  }

  // C - ctpop(X) => ctpop(~X) if C is bitwidth
  if (match(Op0, m_SpecificInt(BitWidth)) &&
      match(Op1, m_OneUse(m_Ctpop(m_Value(X)))))
    return replaceInstUsesWith(
        I, Builder.CreateIntrinsic(Intrinsic::ctpop, {I.getType()},
                                   {Builder.CreateNot(X)}));

  // Reduce multiplies for difference-of-squares by factoring:
  // (X * X) - (Y * Y) --> (X + Y) * (X - Y)
  if (match(Op0, m_OneUse(m_Mul(m_Value(X), m_Deferred(X)))) &&
      match(Op1, m_OneUse(m_Mul(m_Value(Y), m_Deferred(Y))))) {
    auto *OBO0 = cast<OverflowingBinaryOperator>(Op0);
    auto *OBO1 = cast<OverflowingBinaryOperator>(Op1);
    bool PropagateNSW = I.hasNoSignedWrap() && OBO0->hasNoSignedWrap() &&
                        OBO1->hasNoSignedWrap() && BitWidth > 2;
    bool PropagateNUW = I.hasNoUnsignedWrap() && OBO0->hasNoUnsignedWrap() &&
                        OBO1->hasNoUnsignedWrap() && BitWidth > 1;
    Value *Add = Builder.CreateAdd(X, Y, "add", PropagateNUW, PropagateNSW);
    Value *Sub = Builder.CreateSub(X, Y, "sub", PropagateNUW, PropagateNSW);
    Value *Mul = Builder.CreateMul(Add, Sub, "", PropagateNUW, PropagateNSW);
    return replaceInstUsesWith(I, Mul);
  }

  // max(X,Y) nsw/nuw - min(X,Y) --> abs(X nsw - Y)
  if (match(Op0, m_OneUse(m_c_SMax(m_Value(X), m_Value(Y)))) &&
      match(Op1, m_OneUse(m_c_SMin(m_Specific(X), m_Specific(Y))))) {
    if (I.hasNoUnsignedWrap() || I.hasNoSignedWrap()) {
      Value *Sub =
          Builder.CreateSub(X, Y, "sub", /*HasNUW=*/false, /*HasNSW=*/true);
      Value *Call =
          Builder.CreateBinaryIntrinsic(Intrinsic::abs, Sub, Builder.getTrue());
      return replaceInstUsesWith(I, Call);
    }
  }

  if (Instruction *Res = foldBinOpOfSelectAndCastOfSelectCondition(I))
    return Res;

  // (sub (sext (add nsw (X, Y)), sext (X))) --> (sext (Y))
  if (match(Op1, m_SExtLike(m_Value(X))) &&
      match(Op0, m_SExtLike(m_c_NSWAdd(m_Specific(X), m_Value(Y))))) {
    Value *SExtY = Builder.CreateSExt(Y, I.getType());
    return replaceInstUsesWith(I, SExtY);
  }

  // (sub[ nsw] (sext (add nsw (X, Y)), sext (add nsw (X, Z)))) -->
  // --> (sub[ nsw] (sext (Y), sext (Z)))
  {
    Value *Z, *Add0, *Add1;
    if (match(Op0, m_SExtLike(m_Value(Add0))) &&
        match(Op1, m_SExtLike(m_Value(Add1))) &&
        ((match(Add0, m_NSWAdd(m_Value(X), m_Value(Y))) &&
          match(Add1, m_c_NSWAdd(m_Specific(X), m_Value(Z)))) ||
         (match(Add0, m_NSWAdd(m_Value(Y), m_Value(X))) &&
          match(Add1, m_c_NSWAdd(m_Specific(X), m_Value(Z)))))) {
      unsigned NumOfNewInstrs = 0;
      // Non-constant Y, Z require new SExt.
      NumOfNewInstrs += !isa<Constant>(Y) ? 1 : 0;
      NumOfNewInstrs += !isa<Constant>(Z) ? 1 : 0;
      // Check if we can trade some of the old instructions for the new ones.
      unsigned NumOfDeadInstrs = 0;
      if (Op0->hasOneUse()) {
        // If Op0 (sext) has multiple uses, then we keep it
        // and the add that it uses, otherwise, we can remove
        // the sext and probably the add (depending on the number of its uses).
        ++NumOfDeadInstrs;
        NumOfDeadInstrs += Add0->hasOneUse() ? 1 : 0;
      }
      if (Op1->hasOneUse()) {
        ++NumOfDeadInstrs;
        NumOfDeadInstrs += Add1->hasOneUse() ? 1 : 0;
      }
      if (NumOfDeadInstrs >= NumOfNewInstrs) {
        Value *SExtY = Builder.CreateSExt(Y, I.getType());
        Value *SExtZ = Builder.CreateSExt(Z, I.getType());
        Value *Sub = Builder.CreateSub(SExtY, SExtZ, "",
                                       /*HasNUW=*/false,
                                       /*HasNSW=*/I.hasNoSignedWrap());
        return replaceInstUsesWith(I, Sub);
      }
    }
  }

  return TryToNarrowDeduceFlags();
}

/// This eliminates floating-point negation in either 'fneg(X)' or
/// 'fsub(-0.0, X)' form by combining into a constant operand.
static Instruction *foldFNegIntoConstant(Instruction &I, const DataLayout &DL) {
  // This is limited with one-use because fneg is assumed better for
  // reassociation and cheaper in codegen than fmul/fdiv.
  // TODO: Should the m_OneUse restriction be removed?
  Instruction *FNegOp;
  if (!match(&I, m_FNeg(m_OneUse(m_Instruction(FNegOp)))))
    return nullptr;

  Value *X;
  Constant *C;

  // Fold negation into constant operand.
  // -(X * C) --> X * (-C)
  if (match(FNegOp, m_FMul(m_Value(X), m_Constant(C))))
    if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL)) {
      FastMathFlags FNegF = I.getFastMathFlags();
      FastMathFlags OpF = FNegOp->getFastMathFlags();
      FastMathFlags FMF = FastMathFlags::unionValue(FNegF, OpF) |
                          FastMathFlags::intersectRewrite(FNegF, OpF);
      FMF.setNoInfs(FNegF.noInfs() && OpF.noInfs());
      return BinaryOperator::CreateFMulFMF(X, NegC, FMF);
    }
  // -(X / C) --> X / (-C)
  if (match(FNegOp, m_FDiv(m_Value(X), m_Constant(C)))) {
    if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL)) {
      Instruction *FDiv = BinaryOperator::CreateFDivFMF(X, NegC, &I);

      // Intersect 'nsz' and 'ninf' because those special value exceptions may
      // not apply to the fdiv. Everything else propagates from the fneg.
      FastMathFlags FMF = I.getFastMathFlags();
      FastMathFlags OpFMF = FNegOp->getFastMathFlags();
      FDiv->setHasNoSignedZeros(FMF.noSignedZeros() && OpFMF.noSignedZeros());
      FDiv->setHasNoInfs(FMF.noInfs() && OpFMF.noInfs());
      FDiv->copyMetadata(*FNegOp);
      return FDiv;
    }
  }
  // -(C / X) --> (-C) / X
  if (match(FNegOp, m_FDiv(m_Constant(C), m_Value(X))))
    if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL)) {
      Instruction *FDiv = BinaryOperator::CreateFDivFMF(NegC, X, &I);

      // Intersect 'nsz' and 'ninf' because those special value exceptions may
      // not apply to the fdiv. Everything else propagates from the fneg.
      // TODO: We could propagate nsz/ninf from fdiv alone?
      FastMathFlags FMF = I.getFastMathFlags();
      FastMathFlags OpFMF = FNegOp->getFastMathFlags();
      FDiv->setHasNoSignedZeros(FMF.noSignedZeros() && OpFMF.noSignedZeros());
      FDiv->setHasNoInfs(FMF.noInfs() && OpFMF.noInfs());
      FDiv->copyMetadata(*FNegOp);
      return FDiv;
    }
  // With NSZ [ counter-example with -0.0: -(-0.0 + 0.0) != 0.0 + -0.0 ]:
  // -(X + C) --> -X + -C --> -C - X
  if (I.hasNoSignedZeros() && match(FNegOp, m_FAdd(m_Value(X), m_Constant(C))))
    if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))
      return BinaryOperator::CreateFSubFMF(NegC, X, &I);

  return nullptr;
}

Instruction *InstCombinerImpl::hoistFNegAboveFMulFDiv(Value *FNegOp,
                                                      Instruction &FMFSource) {
  Value *X, *Y;
  if (match(FNegOp, m_FMul(m_Value(X), m_Value(Y)))) {
    // Push into RHS which is more likely to simplify (const or another fneg).
    // FIXME: It would be better to invert the transform.
    return cast<Instruction>(Builder.CreateFMulFMF(
        X, Builder.CreateFNegFMF(Y, &FMFSource), &FMFSource));
  }

  if (match(FNegOp, m_FDiv(m_Value(X), m_Value(Y)))) {
    auto *FDiv = cast<Instruction>(Builder.CreateFDivFMF(
        Builder.CreateFNegFMF(X, &FMFSource), Y, &FMFSource));
    FDiv->copyMetadata(*cast<Instruction>(FNegOp));
    return FDiv;
  }

  if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(FNegOp)) {
    // Make sure to preserve flags and metadata on the call.
    if (II->getIntrinsicID() == Intrinsic::ldexp) {
      FastMathFlags FMF = FMFSource.getFastMathFlags() | II->getFastMathFlags();
      CallInst *New =
          Builder.CreateCall(II->getCalledFunction(),
                             {Builder.CreateFNegFMF(II->getArgOperand(0), FMF),
                              II->getArgOperand(1)});
      New->setFastMathFlags(FMF);
      New->copyMetadata(*II);
      return New;
    }
  }

  return nullptr;
}

Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {
  Value *Op = I.getOperand(0);

  if (Value *V = simplifyFNegInst(Op, I.getFastMathFlags(),
                                  getSimplifyQuery().getWithInstruction(&I)))
    return replaceInstUsesWith(I, V);

  if (Instruction *X = foldFNegIntoConstant(I, DL))
    return X;

  Value *X, *Y;

  // If we can ignore the sign of zeros: -(X - Y) --> (Y - X)
  if (I.hasNoSignedZeros() &&
      match(Op, m_OneUse(m_FSub(m_Value(X), m_Value(Y)))))
    return BinaryOperator::CreateFSubFMF(Y, X, &I);

  Value *OneUse;
  if (!match(Op, m_OneUse(m_Value(OneUse))))
    return nullptr;

  if (Instruction *R = hoistFNegAboveFMulFDiv(OneUse, I))
    return replaceInstUsesWith(I, R);

  // Try to eliminate fneg if at least 1 arm of the select is negated.
  Value *Cond;
  if (match(OneUse, m_Select(m_Value(Cond), m_Value(X), m_Value(Y)))) {
    // Unlike most transforms, this one is not safe to propagate nsz unless
    // it is present on the original select. We union the flags from the select
    // and fneg and then remove nsz if needed.
    auto propagateSelectFMF = [&](SelectInst *S, bool CommonOperand) {
      S->copyFastMathFlags(&I);
      if (auto *OldSel = dyn_cast<SelectInst>(Op)) {
        FastMathFlags FMF = I.getFastMathFlags() | OldSel->getFastMathFlags();
        S->setFastMathFlags(FMF);
        if (!OldSel->hasNoSignedZeros() && !CommonOperand &&
            !isGuaranteedNotToBeUndefOrPoison(OldSel->getCondition()))
          S->setHasNoSignedZeros(false);
      }
    };
    // -(Cond ? -P : Y) --> Cond ? P : -Y
    Value *P;
    if (match(X, m_FNeg(m_Value(P)))) {
      Value *NegY = Builder.CreateFNegFMF(Y, &I, Y->getName() + ".neg");
      SelectInst *NewSel = SelectInst::Create(Cond, P, NegY);
      propagateSelectFMF(NewSel, P == Y);
      return NewSel;
    }
    // -(Cond ? X : -P) --> Cond ? -X : P
    if (match(Y, m_FNeg(m_Value(P)))) {
      Value *NegX = Builder.CreateFNegFMF(X, &I, X->getName() + ".neg");
      SelectInst *NewSel = SelectInst::Create(Cond, NegX, P);
      propagateSelectFMF(NewSel, P == X);
      return NewSel;
    }

    // -(Cond ? X : C) --> Cond ? -X : -C
    // -(Cond ? C : Y) --> Cond ? -C : -Y
    if (match(X, m_ImmConstant()) || match(Y, m_ImmConstant())) {
      Value *NegX = Builder.CreateFNegFMF(X, &I, X->getName() + ".neg");
      Value *NegY = Builder.CreateFNegFMF(Y, &I, Y->getName() + ".neg");
      SelectInst *NewSel = SelectInst::Create(Cond, NegX, NegY);
      propagateSelectFMF(NewSel, /*CommonOperand=*/true);
      return NewSel;
    }
  }

  // fneg (copysign x, y) -> copysign x, (fneg y)
  if (match(OneUse, m_CopySign(m_Value(X), m_Value(Y)))) {
    // The source copysign has an additional value input, so we can't propagate
    // flags the copysign doesn't also have.
    FastMathFlags FMF = I.getFastMathFlags();
    FMF &= cast<FPMathOperator>(OneUse)->getFastMathFlags();
    Value *NegY = Builder.CreateFNegFMF(Y, FMF);
    Value *NewCopySign = Builder.CreateCopySign(X, NegY, FMF);
    return replaceInstUsesWith(I, NewCopySign);
  }

  // fneg (shuffle x, Mask) --> shuffle (fneg x), Mask
  ArrayRef<int> Mask;
  if (match(OneUse, m_Shuffle(m_Value(X), m_Poison(), m_Mask(Mask))))
    return new ShuffleVectorInst(Builder.CreateFNegFMF(X, &I), Mask);

  // fneg (reverse x) --> reverse (fneg x)
  if (match(OneUse, m_VecReverse(m_Value(X)))) {
    Value *Reverse = Builder.CreateVectorReverse(Builder.CreateFNegFMF(X, &I));
    return replaceInstUsesWith(I, Reverse);
  }

  return nullptr;
}

Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) {
  if (Value *V = simplifyFSubInst(I.getOperand(0), I.getOperand(1),
                                  I.getFastMathFlags(),
                                  getSimplifyQuery().getWithInstruction(&I)))
    return replaceInstUsesWith(I, V);

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

  if (Instruction *Phi = foldBinopWithPhiOperands(I))
    return Phi;

  // Subtraction from -0.0 is the canonical form of fneg.
  // fsub -0.0, X ==> fneg X
  // fsub nsz 0.0, X ==> fneg nsz X
  //
  // FIXME This matcher does not respect FTZ or DAZ yet:
  // fsub -0.0, Denorm ==> +-0
  // fneg Denorm ==> -Denorm
  Value *Op;
  if (match(&I, m_FNeg(m_Value(Op))))
    return UnaryOperator::CreateFNegFMF(Op, &I);

  if (Instruction *X = foldFNegIntoConstant(I, DL))
    return X;

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

  Value *X, *Y;
  Constant *C;

  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
  // If Op0 is not -0.0 or we can ignore -0.0: Z - (X - Y) --> Z + (Y - X)
  // Canonicalize to fadd to make analysis easier.
  // This can also help codegen because fadd is commutative.
  // Note that if this fsub was really an fneg, the fadd with -0.0 will get
  // killed later. We still limit that particular transform with 'hasOneUse'
  // because an fneg is assumed better/cheaper than a generic fsub.
  if (I.hasNoSignedZeros() ||
      cannotBeNegativeZero(Op0, getSimplifyQuery().getWithInstruction(&I))) {
    if (match(Op1, m_OneUse(m_FSub(m_Value(X), m_Value(Y))))) {
      Value *NewSub = Builder.CreateFSubFMF(Y, X, &I);
      return BinaryOperator::CreateFAddFMF(Op0, NewSub, &I);
    }
  }

  // (-X) - Op1 --> -(X + Op1)
  if (I.hasNoSignedZeros() && !isa<ConstantExpr>(Op0) &&
      match(Op0, m_OneUse(m_FNeg(m_Value(X))))) {
    Value *FAdd = Builder.CreateFAddFMF(X, Op1, &I);
    return UnaryOperator::CreateFNegFMF(FAdd, &I);
  }

  if (isa<Constant>(Op0))
    if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
      if (Instruction *NV = FoldOpIntoSelect(I, SI))
        return NV;

  // X - C --> X + (-C)
  // But don't transform constant expressions because there's an inverse fold
  // for X + (-Y) --> X - Y.
  if (match(Op1, m_ImmConstant(C)))
    if (Constant *NegC = ConstantFoldUnaryOpOperand(Instruction::FNeg, C, DL))
      return BinaryOperator::CreateFAddFMF(Op0, NegC, &I);

  // X - (-Y) --> X + Y
  if (match(Op1, m_FNeg(m_Value(Y))))
    return BinaryOperator::CreateFAddFMF(Op0, Y, &I);

  // Similar to above, but look through a cast of the negated value:
  // X - (fptrunc(-Y)) --> X + fptrunc(Y)
  Type *Ty = I.getType();
  if (match(Op1, m_OneUse(m_FPTrunc(m_FNeg(m_Value(Y))))))
    return BinaryOperator::CreateFAddFMF(Op0, Builder.CreateFPTrunc(Y, Ty), &I);

  // X - (fpext(-Y)) --> X + fpext(Y)
  if (match(Op1, m_OneUse(m_FPExt(m_FNeg(m_Value(Y))))))
    return BinaryOperator::CreateFAddFMF(Op0, Builder.CreateFPExt(Y, Ty), &I);

  // Similar to above, but look through fmul/fdiv of the negated value:
  // Op0 - (-X * Y) --> Op0 + (X * Y)
  // Op0 - (Y * -X) --> Op0 + (X * Y)
  if (match(Op1, m_OneUse(m_c_FMul(m_FNeg(m_Value(X)), m_Value(Y))))) {
    Value *FMul = Builder.CreateFMulFMF(X, Y, &I);
    return BinaryOperator::CreateFAddFMF(Op0, FMul, &I);
  }
  // Op0 - (-X / Y) --> Op0 + (X / Y)
  // Op0 - (X / -Y) --> Op0 + (X / Y)
  if (match(Op1, m_OneUse(m_FDiv(m_FNeg(m_Value(X)), m_Value(Y)))) ||
      match(Op1, m_OneUse(m_FDiv(m_Value(X), m_FNeg(m_Value(Y)))))) {
    Value *FDiv = Builder.CreateFDivFMF(X, Y, &I);
    return BinaryOperator::CreateFAddFMF(Op0, FDiv, &I);
  }

  // Handle special cases for FSub with selects feeding the operation
  if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1))
    return replaceInstUsesWith(I, V);

  if (I.hasAllowReassoc() && I.hasNoSignedZeros()) {
    // (Y - X) - Y --> -X
    if (match(Op0, m_FSub(m_Specific(Op1), m_Value(X))))
      return UnaryOperator::CreateFNegFMF(X, &I);

    // Y - (X + Y) --> -X
    // Y - (Y + X) --> -X
    if (match(Op1, m_c_FAdd(m_Specific(Op0), m_Value(X))))
      return UnaryOperator::CreateFNegFMF(X, &I);

    // (X * C) - X --> X * (C - 1.0)
    if (match(Op0, m_FMul(m_Specific(Op1), m_Constant(C)))) {
      if (Constant *CSubOne = ConstantFoldBinaryOpOperands(
              Instruction::FSub, C, ConstantFP::get(Ty, 1.0), DL))
        return BinaryOperator::CreateFMulFMF(Op1, CSubOne, &I);
    }
    // X - (X * C) --> X * (1.0 - C)
    if (match(Op1, m_FMul(m_Specific(Op0), m_Constant(C)))) {
      if (Constant *OneSubC = ConstantFoldBinaryOpOperands(
              Instruction::FSub, ConstantFP::get(Ty, 1.0), C, DL))
        return BinaryOperator::CreateFMulFMF(Op0, OneSubC, &I);
    }

    // Reassociate fsub/fadd sequences to create more fadd instructions and
    // reduce dependency chains:
    // ((X - Y) + Z) - Op1 --> (X + Z) - (Y + Op1)
    Value *Z;
    if (match(Op0, m_OneUse(m_c_FAdd(m_OneUse(m_FSub(m_Value(X), m_Value(Y))),
                                     m_Value(Z))))) {
      Value *XZ = Builder.CreateFAddFMF(X, Z, &I);
      Value *YW = Builder.CreateFAddFMF(Y, Op1, &I);
      return BinaryOperator::CreateFSubFMF(XZ, YW, &I);
    }

    auto m_FaddRdx = [](Value *&Sum, Value *&Vec) {
      return m_OneUse(m_Intrinsic<Intrinsic::vector_reduce_fadd>(m_Value(Sum),
                                                                 m_Value(Vec)));
    };
    Value *A0, *A1, *V0, *V1;
    if (match(Op0, m_FaddRdx(A0, V0)) && match(Op1, m_FaddRdx(A1, V1)) &&
        V0->getType() == V1->getType()) {
      // Difference of sums is sum of differences:
      // add_rdx(A0, V0) - add_rdx(A1, V1) --> add_rdx(A0, V0 - V1) - A1
      Value *Sub = Builder.CreateFSubFMF(V0, V1, &I);
      Value *Rdx = Builder.CreateIntrinsic(Intrinsic::vector_reduce_fadd,
                                           {Sub->getType()}, {A0, Sub}, &I);
      return BinaryOperator::CreateFSubFMF(Rdx, A1, &I);
    }

    if (Instruction *F = factorizeFAddFSub(I, Builder))
      return F;

    // TODO: This performs reassociative folds for FP ops. Some fraction of the
    // functionality has been subsumed by simple pattern matching here and in
    // InstSimplify. We should let a dedicated reassociation pass handle more
    // complex pattern matching and remove this from InstCombine.
    if (Value *V = FAddCombine(Builder).simplify(&I))
      return replaceInstUsesWith(I, V);

    // (X - Y) - Op1 --> X - (Y + Op1)
    if (match(Op0, m_OneUse(m_FSub(m_Value(X), m_Value(Y))))) {
      Value *FAdd = Builder.CreateFAddFMF(Y, Op1, &I);
      return BinaryOperator::CreateFSubFMF(X, FAdd, &I);
    }
  }

  return nullptr;
}
