diff options
| author | Benjamin Kramer <benny.kra@googlemail.com> | 2010-11-23 18:52:42 +0000 | 
|---|---|---|
| committer | Benjamin Kramer <benny.kra@googlemail.com> | 2010-11-23 18:52:42 +0000 | 
| commit | b5afa65b0a426ef8ce7b4602952b5c3b106071e7 (patch) | |
| tree | 19b8f73545bb7dbdbfc2c625bd1f119edcd0be1d /llvm/lib/Transforms | |
| parent | e3120ed1bfc0b8163186732efce14f3b5d9ecf5f (diff) | |
| download | bcm5719-llvm-b5afa65b0a426ef8ce7b4602952b5c3b106071e7.tar.gz bcm5719-llvm-b5afa65b0a426ef8ce7b4602952b5c3b106071e7.zip | |
InstCombine: Reduce "X shift (A srem B)" to "X shift (A urem B)" iff B is positive.
This allows to transform the rem in "1 << ((int)x % 8);" to an and.
llvm-svn: 120028
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 15 | 
1 files changed, 15 insertions, 0 deletions
| diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 9f7d98ed794..7969dbfec04 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -53,6 +53,21 @@ Instruction *InstCombiner::commonShiftTransforms(BinaryOperator &I) {    if (ConstantInt *CUI = dyn_cast<ConstantInt>(Op1))      if (Instruction *Res = FoldShiftByConstant(Op0, CUI, I))        return Res; + +  // X shift (A srem B) -> X shift (A urem B) iff B is positive. +  // Because shifts by negative values are undefined. +  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op1)) +    if (BO->getOpcode() == Instruction::SRem && BO->getType()->isIntegerTy()) { +      // Make sure the divisor's sign bit is zero. +      APInt Mask = APInt::getSignBit(BO->getType()->getPrimitiveSizeInBits()); +      if (MaskedValueIsZero(BO->getOperand(1), Mask)) { +        Value *URem = Builder->CreateURem(BO->getOperand(0), BO->getOperand(1), +                                          BO->getName()); +        I.setOperand(1, URem); +        return &I; +      } +    } +    return 0;  } | 

