diff options
| author | Dan Gohman <gohman@apple.com> | 2009-06-18 16:30:21 +0000 | 
|---|---|---|
| committer | Dan Gohman <gohman@apple.com> | 2009-06-18 16:30:21 +0000 | 
| commit | 56bd02c55c7e512e140003015ab201441ef9eeac (patch) | |
| tree | 6433461d2c858fffd3658795b388e4e04204a14c /llvm/lib/Transforms | |
| parent | 5a728c908c556d72d4ef9c6355a21073cdfb76c2 (diff) | |
| download | bcm5719-llvm-56bd02c55c7e512e140003015ab201441ef9eeac.tar.gz bcm5719-llvm-56bd02c55c7e512e140003015ab201441ef9eeac.zip | |
Generalize the zext(trunc(t) & C) instcombine to work even with
C is not a low-bits mask, and add a similar instcombine for
zext((trunc(t) & C) ^ C).
llvm-svn: 73705
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 29 | 
1 files changed, 21 insertions, 8 deletions
| diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index bf287f2c680..5bd17e0737b 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -8564,20 +8564,33 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {      }    } -  // zext(trunc(t) & C) -> (t & C)  if C is a mask. +  // zext(trunc(t) & C) -> (t & zext(C)).    if (SrcI && SrcI->getOpcode() == Instruction::And && SrcI->hasOneUse())      if (ConstantInt *C = dyn_cast<ConstantInt>(SrcI->getOperand(1)))        if (TruncInst *TI = dyn_cast<TruncInst>(SrcI->getOperand(0))) {          Value *TI0 = TI->getOperand(0); -        if (TI0->getType() == CI.getType()) { -          unsigned TO = C->getValue().countTrailingOnes(); -          if (APIntOps::isMask(TO, C->getValue())) -            return -              BinaryOperator::Create(Instruction::And, TI0, -                                     ConstantExpr::getZExt(C, CI.getType())); -        } +        if (TI0->getType() == CI.getType()) +          return +            BinaryOperator::CreateAnd(TI0, +                                      ConstantExpr::getZExt(C, CI.getType()));        } +  // zext((trunc(t) & C) ^ C) -> ((t & zext(C)) ^ zext(C)). +  if (SrcI && SrcI->getOpcode() == Instruction::Xor && SrcI->hasOneUse()) +    if (ConstantInt *C = dyn_cast<ConstantInt>(SrcI->getOperand(1))) +      if (BinaryOperator *And = dyn_cast<BinaryOperator>(SrcI->getOperand(0))) +        if (And->getOpcode() == Instruction::And && And->hasOneUse() && +            And->getOperand(1) == C) +          if (TruncInst *TI = dyn_cast<TruncInst>(And->getOperand(0))) { +            Value *TI0 = TI->getOperand(0); +            if (TI0->getType() == CI.getType()) { +              Constant *ZC = ConstantExpr::getZExt(C, CI.getType()); +              Instruction *NewAnd = BinaryOperator::CreateAnd(TI0, ZC, "tmp"); +              InsertNewInstBefore(NewAnd, *And); +              return BinaryOperator::CreateXor(NewAnd, ZC); +            } +          } +    return 0;  } | 

