diff options
author | Sanjay Patel <spatel@rotateright.com> | 2016-08-19 22:33:26 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2016-08-19 22:33:26 +0000 |
commit | fa7de606c439d90665ef25f0c6d447a9476c2fc6 (patch) | |
tree | bb58c6b6c98cbe020ff90e16d54ec27d8332e622 /llvm/lib/Transforms | |
parent | a7d6fc9618aaee28fbbe2324ee8f6168e551d64f (diff) | |
download | bcm5719-llvm-fa7de606c439d90665ef25f0c6d447a9476c2fc6.tar.gz bcm5719-llvm-fa7de606c439d90665ef25f0c6d447a9476c2fc6.zip |
[InstCombine] use m_APInt to allow icmp (shl X, Y), C folds for splat constant vectors, part 1
This is a partial enablement (move the ConstantInt guard down) because there are many
different folds here and one of the later ones will require reworking 'isSignBitCheck'.
llvm-svn: 279339
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index f9a7eb2a512..33d97e10aa8 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1990,20 +1990,14 @@ static Instruction *foldICmpShlOne(ICmpInst &Cmp, Instruction *Shl, /// Fold icmp (shl X, Y), C. Instruction *InstCombiner::foldICmpShlConstant(ICmpInst &Cmp, Instruction *Shl, const APInt *C) { - // FIXME: This should use m_APInt to allow splat vectors. - ConstantInt *ShAmt = dyn_cast<ConstantInt>(Shl->getOperand(1)); - if (!ShAmt) + const APInt *ShiftAmt; + if (!match(Shl->getOperand(1), m_APInt(ShiftAmt))) return foldICmpShlOne(Cmp, Shl, C); - // FIXME: This check restricts all folds under here to scalar types. - ConstantInt *RHS = dyn_cast<ConstantInt>(Cmp.getOperand(1)); - if (!RHS) - return nullptr; - // Check that the shift amount is in range. If not, don't perform undefined // shifts. When the shift is visited it will be simplified. unsigned TypeBits = C->getBitWidth(); - if (ShAmt->uge(TypeBits)) + if (ShiftAmt->uge(TypeBits)) return nullptr; ICmpInst::Predicate Pred = Cmp.getPredicate(); @@ -2011,25 +2005,30 @@ Instruction *InstCombiner::foldICmpShlConstant(ICmpInst &Cmp, Instruction *Shl, if (Cmp.isEquality()) { // If the shift is NUW, then it is just shifting out zeros, no need for an // AND. + Constant *LShrC = ConstantInt::get(Shl->getType(), C->lshr(*ShiftAmt)); if (cast<BinaryOperator>(Shl)->hasNoUnsignedWrap()) - return new ICmpInst(Pred, X, ConstantExpr::getLShr(RHS, ShAmt)); + return new ICmpInst(Pred, X, LShrC); // If the shift is NSW and we compare to 0, then it is just shifting out // sign bits, no need for an AND either. if (cast<BinaryOperator>(Shl)->hasNoSignedWrap() && *C == 0) - return new ICmpInst(Pred, X, ConstantExpr::getLShr(RHS, ShAmt)); + return new ICmpInst(Pred, X, LShrC); if (Shl->hasOneUse()) { // Otherwise strength reduce the shift into an and. - uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits); - Constant *Mask = - Builder->getInt(APInt::getLowBitsSet(TypeBits, TypeBits - ShAmtVal)); + Constant *Mask = ConstantInt::get(Shl->getType(), + APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt->getZExtValue())); Value *And = Builder->CreateAnd(X, Mask, Shl->getName() + ".mask"); - return new ICmpInst(Pred, And, ConstantExpr::getLShr(RHS, ShAmt)); + return new ICmpInst(Pred, And, LShrC); } } + // FIXME: This check restricts all folds under here to scalar types. + ConstantInt *RHS = dyn_cast<ConstantInt>(Cmp.getOperand(1)); + if (!RHS) + return nullptr; + // If this is a signed comparison to 0 and the shift is sign preserving, // use the shift LHS operand instead; isSignTest may change 'Pred', so only // do that if we're sure to not continue on in this function. @@ -2042,7 +2041,7 @@ Instruction *InstCombiner::foldICmpShlConstant(ICmpInst &Cmp, Instruction *Shl, // (X << 31) <s 0 --> (X&1) != 0 Constant *Mask = ConstantInt::get( X->getType(), - APInt::getOneBitSet(TypeBits, TypeBits - ShAmt->getZExtValue() - 1)); + APInt::getOneBitSet(TypeBits, TypeBits - ShiftAmt->getZExtValue() - 1)); Value *And = Builder->CreateAnd(X, Mask, Shl->getName() + ".mask"); return new ICmpInst(TrueIfSigned ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ, And, Constant::getNullValue(And->getType())); @@ -2054,7 +2053,7 @@ Instruction *InstCombiner::foldICmpShlConstant(ICmpInst &Cmp, Instruction *Shl, // This enables to get rid of the shift in favor of a trunc which can be // free on the target. It has the additional benefit of comparing to a // smaller constant, which will be target friendly. - unsigned Amt = ShAmt->getLimitedValue(TypeBits - 1); + unsigned Amt = ShiftAmt->getLimitedValue(TypeBits - 1); if (Shl->hasOneUse() && Amt != 0 && C->countTrailingZeros() >= Amt) { Type *NTy = IntegerType::get(Cmp.getContext(), TypeBits - Amt); Constant *NCI = ConstantExpr::getTrunc( |