diff options
author | Chris Lattner <sabre@nondot.org> | 2010-01-23 18:49:30 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-01-23 18:49:30 +0000 |
commit | 818ff34bc0841edda10951b7b043076b6e7159ef (patch) | |
tree | c98b6b028a742d8c58e9b2cf66a33ce49ae1b35e /lib/Transforms | |
parent | a9cf5b3cc9082acee5b6e30e989a667fed286b05 (diff) |
implement a simple instcombine xform that has been in the
readme forever.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94318 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineShifts.cpp | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineShifts.cpp b/lib/Transforms/InstCombine/InstCombineShifts.cpp index 321c91d57d..9dd60dd4a2 100644 --- a/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "InstCombine.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Support/PatternMatch.h" using namespace llvm; using namespace PatternMatch; @@ -69,10 +70,9 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1, if (Op1->uge(TypeBits)) { if (I.getOpcode() != Instruction::AShr) return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType())); - else { - I.setOperand(1, ConstantInt::get(I.getType(), TypeBits-1)); - return &I; - } + // ashr i32 X, 32 --> ashr i32 X, 31 + I.setOperand(1, ConstantInt::get(I.getType(), TypeBits-1)); + return &I; } // ((X*C1) << C2) == (X * (C1 << C2)) @@ -387,7 +387,29 @@ Instruction *InstCombiner::visitShl(BinaryOperator &I) { } Instruction *InstCombiner::visitLShr(BinaryOperator &I) { - return commonShiftTransforms(I); + if (Instruction *R = commonShiftTransforms(I)) + return R; + + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) + if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Op0)) { + // ctlz.i32(x)>>5 --> zext(x == 0) + // cttz.i32(x)>>5 --> zext(x == 0) + // ctpop.i32(x)>>5 --> zext(x == -1) + if ((II->getIntrinsicID() == Intrinsic::ctlz || + II->getIntrinsicID() == Intrinsic::cttz || + II->getIntrinsicID() == Intrinsic::ctpop) && + (1ULL << Op1C->getZExtValue()) == + Op0->getType()->getScalarSizeInBits()) { + bool isCtPop = II->getIntrinsicID() == Intrinsic::ctpop; + Constant *RHS = ConstantInt::getSigned(Op0->getType(), isCtPop ? -1 : 0); + Value *Cmp = Builder->CreateICmpEQ(II->getOperand(1), RHS); + return new ZExtInst(Cmp, II->getType()); + } + } + + return 0; } Instruction *InstCombiner::visitAShr(BinaryOperator &I) { |