diff options
Diffstat (limited to 'contrib/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp')
| -rw-r--r-- | contrib/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 320 | 
1 files changed, 160 insertions, 160 deletions
diff --git a/contrib/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/contrib/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 809471cfd74f..688897644848 100644 --- a/contrib/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/contrib/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -12,12 +12,26 @@  //===----------------------------------------------------------------------===//  #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/IR/DataLayout.h" -#include "llvm/IR/GetElementPtrTypeIterator.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 <cassert> +#include <utility>  using namespace llvm;  using namespace PatternMatch; @@ -39,10 +53,15 @@ namespace {      // 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() : IsFp(false), BufHasFpVal(false), IntVal(0) {} +    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; @@ -55,12 +74,6 @@ namespace {      bool isZero() const { return isInt() ? !IntVal : getFpVal().isZero(); }      Value *getValue(Type *) const; -    // 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); -      bool isOne() const { return isInt() && IntVal == 1; }      bool isTwo() const { return isInt() && IntVal == 2; }      bool isMinusOne() const { return isInt() && IntVal == -1; } @@ -68,10 +81,12 @@ namespace {    private:      bool insaneIntVal(int V) { return V > 4 || V < -4; } +      APFloat *getFpValPtr() -      { return reinterpret_cast<APFloat*>(&FpValBuf.buffer[0]); } +      { return reinterpret_cast<APFloat *>(&FpValBuf.buffer[0]); } +      const APFloat *getFpValPtr() const -      { return reinterpret_cast<const APFloat*>(&FpValBuf.buffer[0]); } +      { return reinterpret_cast<const APFloat *>(&FpValBuf.buffer[0]); }      const APFloat &getFpVal() const {        assert(IsFp && BufHasFpVal && "Incorret state"); @@ -94,17 +109,16 @@ namespace {      //       from an *SIGNED* integer.      APFloat createAPFloatFromInt(const fltSemantics &Sem, int Val); -  private: -    bool IsFp; +    bool IsFp = false;      // True iff FpValBuf contains an instance of APFloat. -    bool BufHasFpVal; +    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; +    short IntVal = 0;      AlignedCharArrayUnion<APFloat> FpValBuf;    }; @@ -112,10 +126,14 @@ namespace {    /// 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() : Val(nullptr) {} +    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; } @@ -146,16 +164,11 @@ namespace {      /// splitted is the addend itself.      unsigned drillAddendDownOneStep(FAddend &Addend0, FAddend &Addend1) const; -    void operator+=(const FAddend &T) { -      assert((Val == T.Val) && "Symbolic-values disagree"); -      Coeff += T.Coeff; -    } -    private:      void Scale(const FAddendCoef& ScaleAmt) { Coeff *= ScaleAmt; }      // This addend has the value of "Coeff * Val". -    Value *Val; +    Value *Val = nullptr;      FAddendCoef Coeff;    }; @@ -164,11 +177,12 @@ namespace {    ///    class FAddCombine {    public: -    FAddCombine(InstCombiner::BuilderTy &B) : Builder(B), Instr(nullptr) {} +    FAddCombine(InstCombiner::BuilderTy &B) : Builder(B) {} +      Value *simplify(Instruction *FAdd);    private: -    typedef SmallVector<const FAddend*, 4> AddendVect; +    using AddendVect = SmallVector<const FAddend *, 4>;      Value *simplifyFAdd(AddendVect& V, unsigned InstrQuota); @@ -179,6 +193,7 @@ namespace {      /// 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); @@ -187,9 +202,6 @@ namespace {      Value *createNaryFAdd(const AddendVect& Opnds, unsigned InstrQuota);      void createInstPostProc(Instruction *NewInst, bool NoNumber = false); -    InstCombiner::BuilderTy &Builder; -    Instruction *Instr; -       // Debugging stuff are clustered here.      #ifndef NDEBUG        unsigned CreateInstrNum; @@ -199,9 +211,12 @@ namespace {        void initCreateInstNum() {}        void incCreateInstNum() {}      #endif + +    InstCombiner::BuilderTy &Builder; +    Instruction *Instr = nullptr;    }; -} // anonymous namespace +} // end anonymous namespace  //===----------------------------------------------------------------------===//  // @@ -332,7 +347,6 @@ Value *FAddendCoef::getValue(Type *Ty) const {  //  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; @@ -396,7 +410,6 @@ unsigned FAddend::drillValueDownOneStep  // 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()) @@ -421,7 +434,6 @@ unsigned FAddend::drillAddendDownOneStep  // -------------------------------------------------------  //   (x * y) +/- (x * z)               x * (y +/- z)  //   (y / x) +/- (z / x)               (y +/- z) / x -//  Value *FAddCombine::performFactorization(Instruction *I) {    assert((I->getOpcode() == Instruction::FAdd ||            I->getOpcode() == Instruction::FSub) && "Expect add/sub"); @@ -447,7 +459,6 @@ Value *FAddCombine::performFactorization(Instruction *I) {    //  ----------------------------------------------    // (x*y) +/- (x*z)        x        y         z    // (y/x) +/- (z/x)        x        y         z -  //    Value *Factor = nullptr;    Value *AddSub0 = nullptr, *AddSub1 = nullptr; @@ -471,7 +482,7 @@ Value *FAddCombine::performFactorization(Instruction *I) {      return nullptr;    FastMathFlags Flags; -  Flags.setUnsafeAlgebra(); +  Flags.setFast();    if (I0) Flags &= I->getFastMathFlags();    if (I1) Flags &= I->getFastMathFlags(); @@ -500,7 +511,7 @@ Value *FAddCombine::performFactorization(Instruction *I) {  }  Value *FAddCombine::simplify(Instruction *I) { -  assert(I->hasUnsafeAlgebra() && "Should be in unsafe mode"); +  assert(I->isFast() && "Expected 'fast' instruction");    // Currently we are not able to handle vector type.    if (I->getType()->isVectorTy()) @@ -599,7 +610,6 @@ Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {    // desirable to reside at the top of the resulting expression tree. Placing    // constant close to supper-expr(s) will potentially reveal some optimization    // opportunities in super-expr(s). -  //    const FAddend *ConstAdd = nullptr;    // Simplified addends are placed <SimpVect>. @@ -608,7 +618,6 @@ Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {    // 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]; @@ -626,7 +635,6 @@ Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {      // 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]; @@ -681,7 +689,7 @@ Value *FAddCombine::createNaryFAdd    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; @@ -726,10 +734,10 @@ Value *FAddCombine::createNaryFAdd      LastVal = createFNeg(LastVal);    } -  #ifndef NDEBUG -    assert(CreateInstrNum == InstrNeeded && -           "Inconsistent in instruction numbers"); -  #endif +#ifndef NDEBUG +  assert(CreateInstrNum == InstrNeeded && +         "Inconsistent in instruction numbers"); +#endif    return LastVal;  } @@ -950,9 +958,25 @@ static Value *checkForNegativeOperand(BinaryOperator &I,    return nullptr;  } -static Instruction *foldAddWithConstant(BinaryOperator &Add, -                                        InstCombiner::BuilderTy &Builder) { +Instruction *InstCombiner::foldAddWithConstant(BinaryOperator &Add) {    Value *Op0 = Add.getOperand(0), *Op1 = Add.getOperand(1); +  Constant *Op1C; +  if (!match(Op1, m_Constant(Op1C))) +    return nullptr; + +  if (Instruction *NV = foldOpWithConstantIntoOperand(Add)) +    return NV; + +  Value *X; +  // zext(bool) + C -> bool ? C + 1 : C +  if (match(Op0, m_ZExt(m_Value(X))) && +      X->getType()->getScalarSizeInBits() == 1) +    return SelectInst::Create(X, AddOne(Op1C), Op1); + +  // ~X + C --> (C-1) - X +  if (match(Op0, m_Not(m_Value(X)))) +    return BinaryOperator::CreateSub(SubOne(Op1C), X); +    const APInt *C;    if (!match(Op1, m_APInt(C)))      return nullptr; @@ -968,21 +992,17 @@ static Instruction *foldAddWithConstant(BinaryOperator &Add,      return BinaryOperator::CreateXor(Op0, Op1);    } -  Value *X; -  const APInt *C2; -  Type *Ty = Add.getType(); -    // Is this add the last step in a convoluted sext?    // add(zext(xor i16 X, -32768), -32768) --> sext X +  Type *Ty = Add.getType(); +  const APInt *C2;    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);    // (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C)) -  // FIXME: This should check hasOneUse to not increase the instruction count? -  if (C->isNegative() && -      match(Op0, m_ZExt(m_NUWAdd(m_Value(X), m_APInt(C2)))) && -      C->sge(-C2->sext(C->getBitWidth()))) { +  if (match(Op0, m_OneUse(m_ZExt(m_NUWAdd(m_Value(X), m_APInt(C2))))) && +      C->isNegative() && C->sge(-C2->sext(C->getBitWidth()))) {      Constant *NewC =          ConstantInt::get(X->getType(), *C2 + C->trunc(C2->getBitWidth()));      return new ZExtInst(Builder.CreateNUWAdd(X, NewC), Ty); @@ -1013,34 +1033,29 @@ static Instruction *foldAddWithConstant(BinaryOperator &Add,  Instruction *InstCombiner::visitAdd(BinaryOperator &I) {    bool Changed = SimplifyAssociativeOrCommutative(I); -  Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); -    if (Value *V = SimplifyVectorOp(I))      return replaceInstUsesWith(I, V); +  Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);    if (Value *V =            SimplifyAddInst(LHS, RHS, I.hasNoSignedWrap(), I.hasNoUnsignedWrap(),                            SQ.getWithInstruction(&I)))      return replaceInstUsesWith(I, V); -   // (A*B)+(A*C) -> A*(B+C) etc +  // (A*B)+(A*C) -> A*(B+C) etc    if (Value *V = SimplifyUsingDistributiveLaws(I))      return replaceInstUsesWith(I, V); -  if (Instruction *X = foldAddWithConstant(I, Builder)) +  if (Instruction *X = foldAddWithConstant(I))      return X;    // FIXME: This should be moved into the above helper function to allow these -  // transforms for splat vectors. +  // transforms for general constant or constant splat vectors. +  Type *Ty = I.getType();    if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) { -    // zext(bool) + C -> bool ? C + 1 : C -    if (ZExtInst *ZI = dyn_cast<ZExtInst>(LHS)) -      if (ZI->getSrcTy()->isIntegerTy(1)) -        return SelectInst::Create(ZI->getOperand(0), AddOne(CI), CI); -      Value *XorLHS = nullptr; ConstantInt *XorRHS = nullptr;      if (match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) { -      uint32_t TySizeBits = I.getType()->getScalarSizeInBits(); +      unsigned TySizeBits = Ty->getScalarSizeInBits();        const APInt &RHSVal = CI->getValue();        unsigned ExtendAmt = 0;        // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext. @@ -1059,7 +1074,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {        }        if (ExtendAmt) { -        Constant *ShAmt = ConstantInt::get(I.getType(), ExtendAmt); +        Constant *ShAmt = ConstantInt::get(Ty, ExtendAmt);          Value *NewShl = Builder.CreateShl(XorLHS, ShAmt, "sext");          return BinaryOperator::CreateAShr(NewShl, ShAmt);        } @@ -1080,38 +1095,30 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {      }    } -  if (isa<Constant>(RHS)) -    if (Instruction *NV = foldOpWithConstantIntoOperand(I)) -      return NV; - -  if (I.getType()->isIntOrIntVectorTy(1)) +  if (Ty->isIntOrIntVectorTy(1))      return BinaryOperator::CreateXor(LHS, RHS);    // X + X --> X << 1    if (LHS == RHS) { -    BinaryOperator *New = -      BinaryOperator::CreateShl(LHS, ConstantInt::get(I.getType(), 1)); -    New->setHasNoSignedWrap(I.hasNoSignedWrap()); -    New->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); -    return New; +    auto *Shl = BinaryOperator::CreateShl(LHS, ConstantInt::get(Ty, 1)); +    Shl->setHasNoSignedWrap(I.hasNoSignedWrap()); +    Shl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); +    return Shl;    } -  // -A + B  -->  B - A -  // -A + -B  -->  -(A + B) -  if (Value *LHSV = dyn_castNegVal(LHS)) { -    if (!isa<Constant>(RHS)) -      if (Value *RHSV = dyn_castNegVal(RHS)) { -        Value *NewAdd = Builder.CreateAdd(LHSV, RHSV, "sum"); -        return BinaryOperator::CreateNeg(NewAdd); -      } +  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)); -    return BinaryOperator::CreateSub(RHS, LHSV); +    // -A + B --> B - A +    return BinaryOperator::CreateSub(RHS, A);    }    // A + -B  -->  A - B -  if (!isa<Constant>(RHS)) -    if (Value *V = dyn_castNegVal(RHS)) -      return BinaryOperator::CreateSub(LHS, V); +  if (match(RHS, m_Neg(m_Value(B)))) +    return BinaryOperator::CreateSub(LHS, B);    if (Value *V = checkForNegativeOperand(I, Builder))      return replaceInstUsesWith(I, V); @@ -1120,12 +1127,6 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {    if (haveNoCommonBitsSet(LHS, RHS, DL, &AC, &I, &DT))      return BinaryOperator::CreateOr(LHS, RHS); -  if (Constant *CRHS = dyn_cast<Constant>(RHS)) { -    Value *X; -    if (match(LHS, m_Not(m_Value(X)))) // ~X + C --> (C-1) - X -      return BinaryOperator::CreateSub(SubOne(CRHS), X); -  } -    // FIXME: We already did a check for ConstantInt RHS above this.    // FIXME: Is this pattern covered by another fold? No regression tests fail on    // removal. @@ -1187,12 +1188,12 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {        if (LHSConv->hasOneUse()) {          Constant *CI =              ConstantExpr::getTrunc(RHSC, LHSConv->getOperand(0)->getType()); -        if (ConstantExpr::getSExt(CI, I.getType()) == RHSC && +        if (ConstantExpr::getSExt(CI, Ty) == RHSC &&              willNotOverflowSignedAdd(LHSConv->getOperand(0), CI, I)) {            // Insert the new, smaller add.            Value *NewAdd =                Builder.CreateNSWAdd(LHSConv->getOperand(0), CI, "addconv"); -          return new SExtInst(NewAdd, I.getType()); +          return new SExtInst(NewAdd, Ty);          }        }      } @@ -1210,7 +1211,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {          // Insert the new integer add.          Value *NewAdd = Builder.CreateNSWAdd(LHSConv->getOperand(0),                                               RHSConv->getOperand(0), "addconv"); -        return new SExtInst(NewAdd, I.getType()); +        return new SExtInst(NewAdd, Ty);        }      }    } @@ -1223,12 +1224,12 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {        if (LHSConv->hasOneUse()) {          Constant *CI =              ConstantExpr::getTrunc(RHSC, LHSConv->getOperand(0)->getType()); -        if (ConstantExpr::getZExt(CI, I.getType()) == RHSC && +        if (ConstantExpr::getZExt(CI, Ty) == RHSC &&              willNotOverflowUnsignedAdd(LHSConv->getOperand(0), CI, I)) {            // Insert the new, smaller add.            Value *NewAdd =                Builder.CreateNUWAdd(LHSConv->getOperand(0), CI, "addconv"); -          return new ZExtInst(NewAdd, I.getType()); +          return new ZExtInst(NewAdd, Ty);          }        }      } @@ -1246,41 +1247,35 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {          // Insert the new integer add.          Value *NewAdd = Builder.CreateNUWAdd(              LHSConv->getOperand(0), RHSConv->getOperand(0), "addconv"); -        return new ZExtInst(NewAdd, I.getType()); +        return new ZExtInst(NewAdd, Ty);        }      }    }    // (add (xor A, B) (and A, B)) --> (or A, B) -  { -    Value *A = nullptr, *B = nullptr; -    if (match(RHS, m_Xor(m_Value(A), m_Value(B))) && -        match(LHS, m_c_And(m_Specific(A), m_Specific(B)))) -      return BinaryOperator::CreateOr(A, B); - -    if (match(LHS, m_Xor(m_Value(A), m_Value(B))) && -        match(RHS, m_c_And(m_Specific(A), m_Specific(B)))) -      return BinaryOperator::CreateOr(A, B); -  } +  if (match(LHS, m_Xor(m_Value(A), m_Value(B))) && +      match(RHS, m_c_And(m_Specific(A), m_Specific(B)))) +    return BinaryOperator::CreateOr(A, B); + +  // (add (and A, B) (xor A, B)) --> (or A, B) +  if (match(RHS, m_Xor(m_Value(A), m_Value(B))) && +      match(LHS, m_c_And(m_Specific(A), m_Specific(B)))) +    return BinaryOperator::CreateOr(A, B);    // (add (or A, B) (and A, B)) --> (add A, B) -  { -    Value *A = nullptr, *B = nullptr; -    if (match(RHS, m_Or(m_Value(A), m_Value(B))) && -        match(LHS, m_c_And(m_Specific(A), m_Specific(B)))) { -      auto *New = BinaryOperator::CreateAdd(A, B); -      New->setHasNoSignedWrap(I.hasNoSignedWrap()); -      New->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); -      return New; -    } +  if (match(LHS, m_Or(m_Value(A), m_Value(B))) && +      match(RHS, m_c_And(m_Specific(A), m_Specific(B)))) { +    I.setOperand(0, A); +    I.setOperand(1, B); +    return &I; +  } -    if (match(LHS, m_Or(m_Value(A), m_Value(B))) && -        match(RHS, m_c_And(m_Specific(A), m_Specific(B)))) { -      auto *New = BinaryOperator::CreateAdd(A, B); -      New->setHasNoSignedWrap(I.hasNoSignedWrap()); -      New->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); -      return New; -    } +  // (add (and A, B) (or A, B)) --> (add A, B) +  if (match(RHS, m_Or(m_Value(A), m_Value(B))) && +      match(LHS, m_c_And(m_Specific(A), m_Specific(B)))) { +    I.setOperand(0, A); +    I.setOperand(1, B); +    return &I;    }    // TODO(jingyue): Consider willNotOverflowSignedAdd and @@ -1387,32 +1382,11 @@ Instruction *InstCombiner::visitFAdd(BinaryOperator &I) {      }    } -  // select C, 0, B + select C, A, 0 -> select C, A, B -  { -    Value *A1, *B1, *C1, *A2, *B2, *C2; -    if (match(LHS, m_Select(m_Value(C1), m_Value(A1), m_Value(B1))) && -        match(RHS, m_Select(m_Value(C2), m_Value(A2), m_Value(B2)))) { -      if (C1 == C2) { -        Constant *Z1=nullptr, *Z2=nullptr; -        Value *A, *B, *C=C1; -        if (match(A1, m_AnyZero()) && match(B2, m_AnyZero())) { -            Z1 = dyn_cast<Constant>(A1); A = A2; -            Z2 = dyn_cast<Constant>(B2); B = B1; -        } else if (match(B1, m_AnyZero()) && match(A2, m_AnyZero())) { -            Z1 = dyn_cast<Constant>(B1); B = B2; -            Z2 = dyn_cast<Constant>(A2); A = A1; -        } - -        if (Z1 && Z2 && -            (I.hasNoSignedZeros() || -             (Z1->isNegativeZeroValue() && Z2->isNegativeZeroValue()))) { -          return SelectInst::Create(C, A, B); -        } -      } -    } -  } +  // Handle specials cases for FAdd with selects feeding the operation +  if (Value *V = SimplifySelectsFeedingBinaryOp(I, LHS, RHS)) +    return replaceInstUsesWith(I, V); -  if (I.hasUnsafeAlgebra()) { +  if (I.isFast()) {      if (Value *V = FAddCombine(Builder).simplify(&I))        return replaceInstUsesWith(I, V);    } @@ -1423,7 +1397,6 @@ Instruction *InstCombiner::visitFAdd(BinaryOperator &I) {  /// 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 *InstCombiner::OptimizePointerDifference(Value *LHS, Value *RHS,                                                 Type *Ty) {    // If LHS is a gep based on RHS or RHS is a gep based on LHS, we can optimize @@ -1465,12 +1438,31 @@ Value *InstCombiner::OptimizePointerDifference(Value *LHS, Value *RHS,      }    } -  // Avoid duplicating the arithmetic if GEP2 has non-constant indices and -  // multiple users. -  if (!GEP1 || -      (GEP2 && !GEP2->hasAllConstantIndices() && !GEP2->hasOneUse())) +  if (!GEP1) +    // No GEP found.      return nullptr; +  if (GEP2) { +    // (gep X, ...) - (gep X, ...) +    // +    // Avoid duplicating the arithmetic if there are more than one non-constant +    // indices between the two GEPs and either GEP has a non-constant index and +    // multiple users. If zero non-constant index, the result is a constant and +    // there is no duplication. If one non-constant index, the result is an add +    // or sub with a constant, which is no larger than the original code, and +    // there's no duplicated arithmetic, even if either GEP has multiple +    // users. If more than one non-constant indices combined, as long as the GEP +    // with at least one non-constant index doesn't have multiple users, there +    // is no duplication. +    unsigned NumNonConstantIndices1 = GEP1->countNonConstantIndices(); +    unsigned NumNonConstantIndices2 = GEP2->countNonConstantIndices(); +    if (NumNonConstantIndices1 + NumNonConstantIndices2 > 1 && +        ((NumNonConstantIndices1 > 0 && !GEP1->hasOneUse()) || +         (NumNonConstantIndices2 > 0 && !GEP2->hasOneUse()))) { +      return nullptr; +    } +  } +    // Emit the offset of the GEP and an intptr_t.    Value *Result = EmitGEPOffset(GEP1); @@ -1528,8 +1520,13 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {      return BinaryOperator::CreateNot(Op1);    if (Constant *C = dyn_cast<Constant>(Op0)) { +    Value *X; +    // C - zext(bool) -> bool ? C - 1 : C +    if (match(Op1, m_ZExt(m_Value(X))) && +        X->getType()->getScalarSizeInBits() == 1) +      return SelectInst::Create(X, SubOne(C), C); +      // C - ~X == X + (1+C) -    Value *X = nullptr;      if (match(Op1, m_Not(m_Value(X))))        return BinaryOperator::CreateAdd(X, AddOne(C)); @@ -1600,7 +1597,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {        return BinaryOperator::CreateNeg(Y);    } -  // (sub (or A, B) (xor A, B)) --> (and 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))) && @@ -1626,7 +1623,6 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {                                        Builder.CreateSub(Z, Y, Op1->getName()));      // (X - (X & Y))   -->   (X & ~Y) -    //      if (match(Op1, m_c_And(m_Value(Y), m_Specific(Op0))))        return BinaryOperator::CreateAnd(Op0,                                    Builder.CreateNot(Y, Y->getName() + ".not")); @@ -1741,7 +1737,11 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) {      }    } -  if (I.hasUnsafeAlgebra()) { +  // Handle specials cases for FSub with selects feeding the operation +  if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1)) +    return replaceInstUsesWith(I, V); + +  if (I.isFast()) {      if (Value *V = FAddCombine(Builder).simplify(&I))        return replaceInstUsesWith(I, V);    }  | 
