diff options
| author | Chris Lattner <sabre@nondot.org> | 2010-01-05 07:23:56 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2010-01-05 07:23:56 +0000 | 
| commit | 9da1cb243b93216204d071433a967c211d40f7ef (patch) | |
| tree | 98c8d91bc4f46a1e66c6280144f0da212850b074 /llvm/lib | |
| parent | 85e65e58ac76acbc1dac340c87699c4889f67802 (diff) | |
| download | bcm5719-llvm-9da1cb243b93216204d071433a967c211d40f7ef.tar.gz bcm5719-llvm-9da1cb243b93216204d071433a967c211d40f7ef.zip | |
optimize cttz and ctlz when we can prove something about the 
leading/trailing bits.  Patch by Alastair Lynn!
llvm-svn: 92706
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 35 | 
1 files changed, 34 insertions, 1 deletions
| diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 1b08b0e0557..81640f36a8e 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3144,7 +3144,40 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {                                            II->getOperand(1));      }      break; -       +  case Intrinsic::cttz: { +    // If all bits below the first known one are known zero, +    // this value is constant. +    const IntegerType *IT = cast<IntegerType>(II->getOperand(1)->getType()); +    uint32_t BitWidth = IT->getBitWidth(); +    APInt KnownZero(BitWidth, 0); +    APInt KnownOne(BitWidth, 0); +    ComputeMaskedBits(II->getOperand(1), APInt::getAllOnesValue(BitWidth), +                      KnownZero, KnownOne); +    unsigned TrailingZeros = KnownOne.countTrailingZeros(); +    APInt Mask(APInt::getLowBitsSet(BitWidth, TrailingZeros)); +    if ((Mask & KnownZero) == Mask) +      return ReplaceInstUsesWith(CI, ConstantInt::get(IT, +                                 APInt(BitWidth, TrailingZeros))); +     +    } +    break; +  case Intrinsic::ctlz: { +    // If all bits above the first known one are known zero, +    // this value is constant. +    const IntegerType *IT = cast<IntegerType>(II->getOperand(1)->getType()); +    uint32_t BitWidth = IT->getBitWidth(); +    APInt KnownZero(BitWidth, 0); +    APInt KnownOne(BitWidth, 0); +    ComputeMaskedBits(II->getOperand(1), APInt::getAllOnesValue(BitWidth), +                      KnownZero, KnownOne); +    unsigned LeadingZeros = KnownOne.countLeadingZeros(); +    APInt Mask(APInt::getHighBitsSet(BitWidth, LeadingZeros)); +    if ((Mask & KnownZero) == Mask) +      return ReplaceInstUsesWith(CI, ConstantInt::get(IT, +                                 APInt(BitWidth, LeadingZeros))); +     +    } +    break;    case Intrinsic::uadd_with_overflow: {      Value *LHS = II->getOperand(1), *RHS = II->getOperand(2);      const IntegerType *IT = cast<IntegerType>(II->getOperand(1)->getType()); | 

