diff options
Diffstat (limited to 'lib/Transforms/InstCombine/InstCombineAddSub.cpp')
| -rw-r--r-- | lib/Transforms/InstCombine/InstCombineAddSub.cpp | 73 | 
1 files changed, 32 insertions, 41 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 4891ff00e7b1..2da17f1dd501 100644 --- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -35,7 +35,7 @@ static Constant *SubOne(ConstantInt *C) {  // Otherwise, return null.  //  static inline Value *dyn_castFoldableMul(Value *V, ConstantInt *&CST) { -  if (!V->hasOneUse() || !V->getType()->isInteger()) +  if (!V->hasOneUse() || !V->getType()->isIntegerTy())      return 0;    Instruction *I = dyn_cast<Instruction>(V); @@ -121,50 +121,34 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {          match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) {        uint32_t TySizeBits = I.getType()->getScalarSizeInBits();        const APInt& RHSVal = cast<ConstantInt>(RHSC)->getValue(); -       -      uint32_t Size = TySizeBits / 2; -      APInt C0080Val(APInt(TySizeBits, 1ULL).shl(Size - 1)); -      APInt CFF80Val(-C0080Val); -      do { -        if (TySizeBits > Size) { -          // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext. -          // If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext. -          if ((RHSVal == CFF80Val && XorRHS->getValue() == C0080Val) || -              (RHSVal == C0080Val && XorRHS->getValue() == CFF80Val)) { -            // This is a sign extend if the top bits are known zero. -            if (!MaskedValueIsZero(XorLHS,  -                   APInt::getHighBitsSet(TySizeBits, TySizeBits - Size))) -              Size = 0;  // Not a sign ext, but can't be any others either. -            break; -          } -        } -        Size >>= 1; -        C0080Val = APIntOps::lshr(C0080Val, Size); -        CFF80Val = APIntOps::ashr(CFF80Val, Size); -      } while (Size >= 1); -       -      // FIXME: This shouldn't be necessary. When the backends can handle types -      // with funny bit widths then this switch statement should be removed. It -      // is just here to get the size of the "middle" type back up to something -      // that the back ends can handle. -      const Type *MiddleType = 0; -      switch (Size) { -        default: break; -        case 32: -        case 16: -        case  8: MiddleType = IntegerType::get(I.getContext(), Size); break; +      unsigned ExtendAmt = 0; +      // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext. +      // If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext. +      if (XorRHS->getValue() == -RHSVal) { +        if (RHSVal.isPowerOf2()) +          ExtendAmt = TySizeBits - RHSVal.logBase2() - 1; +        else if (XorRHS->getValue().isPowerOf2()) +          ExtendAmt = TySizeBits - XorRHS->getValue().logBase2() - 1; +      } + +      if (ExtendAmt) { +        APInt Mask = APInt::getHighBitsSet(TySizeBits, ExtendAmt); +        if (!MaskedValueIsZero(XorLHS, Mask)) +          ExtendAmt = 0;        } -      if (MiddleType) { -        Value *NewTrunc = Builder->CreateTrunc(XorLHS, MiddleType, "sext"); -        return new SExtInst(NewTrunc, I.getType(), I.getName()); + +      if (ExtendAmt) { +        Constant *ShAmt = ConstantInt::get(I.getType(), ExtendAmt); +        Value *NewShl = Builder->CreateShl(XorLHS, ShAmt, "sext"); +        return BinaryOperator::CreateAShr(NewShl, ShAmt);        }      }    } -  if (I.getType()->isInteger(1)) +  if (I.getType()->isIntegerTy(1))      return BinaryOperator::CreateXor(LHS, RHS); -  if (I.getType()->isInteger()) { +  if (I.getType()->isIntegerTy()) {      // X + X --> X << 1      if (LHS == RHS)        return BinaryOperator::CreateShl(LHS, ConstantInt::get(I.getType(), 1)); @@ -184,7 +168,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {    // -A + B  -->  B - A    // -A + -B  -->  -(A + B)    if (Value *LHSV = dyn_castNegVal(LHS)) { -    if (LHS->getType()->isIntOrIntVector()) { +    if (LHS->getType()->isIntOrIntVectorTy()) {        if (Value *RHSV = dyn_castNegVal(RHS)) {          Value *NewAdd = Builder->CreateAdd(LHSV, RHSV, "sum");          return BinaryOperator::CreateNeg(NewAdd); @@ -238,7 +222,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {    }    // W*X + Y*Z --> W * (X+Z)  iff W == Y -  if (I.getType()->isIntOrIntVector()) { +  if (I.getType()->isIntOrIntVectorTy()) {      Value *W, *X, *Y, *Z;      if (match(LHS, m_Mul(m_Value(W), m_Value(X))) &&          match(RHS, m_Mul(m_Value(Y), m_Value(Z)))) { @@ -576,7 +560,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {      return ReplaceInstUsesWith(I, Op0);    // undef - X -> undef    if (isa<UndefValue>(Op1))      return ReplaceInstUsesWith(I, Op1);    // X - undef -> undef -  if (I.getType()->isInteger(1)) +  if (I.getType()->isIntegerTy(1))      return BinaryOperator::CreateXor(Op0, Op1);    if (ConstantInt *C = dyn_cast<ConstantInt>(Op0)) { @@ -676,6 +660,13 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {                return BinaryOperator::CreateSDiv(Op1I->getOperand(0),                                            ConstantExpr::getNeg(DivRHS)); +      // 0 - (C << X)  -> (-C << X) +      if (Op1I->getOpcode() == Instruction::Shl) +        if (ConstantInt *CSI = dyn_cast<ConstantInt>(Op0)) +          if (CSI->isZero()) +            if (Value *ShlLHSNeg = dyn_castNegVal(Op1I->getOperand(0))) +              return BinaryOperator::CreateShl(ShlLHSNeg, Op1I->getOperand(1)); +        // X - X*C --> X * (1-C)        ConstantInt *C2 = 0;        if (dyn_castFoldableMul(Op1I, C2) == Op0) {  | 
