diff options
| author | Chris Lattner <sabre@nondot.org> | 2009-02-17 20:47:23 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2009-02-17 20:47:23 +0000 | 
| commit | 24f31a0e59873421311bbe0b16198b4e3ad0cd91 (patch) | |
| tree | 64c60773dc9efefcbca2b6b3b9468db3209e693f /llvm/lib/Transforms | |
| parent | 8c8073592921d657ce31bf25e6b9d072a0edfbd4 (diff) | |
| download | bcm5719-llvm-24f31a0e59873421311bbe0b16198b4e3ad0cd91.tar.gz bcm5719-llvm-24f31a0e59873421311bbe0b16198b4e3ad0cd91.zip | |
commit a tweaked version of Daniel's patch for PR3599.  We now
eliminate all the extensions and all but the one required truncate
from the testcase, but the or/and/shift stuff still isn't zapped.
llvm-svn: 64809
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 55 | 
1 files changed, 29 insertions, 26 deletions
| diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 8bdeb7f514c..bca6abc6051 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -8271,32 +8271,35 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {    Value *Src = CI.getOperand(0); -  // If this is a cast of a cast -  if (CastInst *CSrc = dyn_cast<CastInst>(Src)) {   // A->B->C cast -    // If this is a TRUNC followed by a ZEXT then we are dealing with integral -    // types and if the sizes are just right we can convert this into a logical -    // 'and' which will be much cheaper than the pair of casts. -    if (isa<TruncInst>(CSrc)) { -      // Get the sizes of the types involved -      Value *A = CSrc->getOperand(0); -      uint32_t SrcSize = A->getType()->getPrimitiveSizeInBits(); -      uint32_t MidSize = CSrc->getType()->getPrimitiveSizeInBits(); -      uint32_t DstSize = CI.getType()->getPrimitiveSizeInBits(); -      // If we're actually extending zero bits and the trunc is a no-op -      if (MidSize < DstSize && SrcSize == DstSize) { -        // Replace both of the casts with an And of the type mask. -        APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize)); -        Constant *AndConst = ConstantInt::get(AndValue); -        Instruction *And =  -          BinaryOperator::CreateAnd(CSrc->getOperand(0), AndConst); -        // Unfortunately, if the type changed, we need to cast it back. -        if (And->getType() != CI.getType()) { -          And->setName(CSrc->getName()+".mask"); -          InsertNewInstBefore(And, CI); -          And = CastInst::CreateIntegerCast(And, CI.getType(), false/*ZExt*/); -        } -        return And; -      } +  // If this is a TRUNC followed by a ZEXT then we are dealing with integral +  // types and if the sizes are just right we can convert this into a logical +  // 'and' which will be much cheaper than the pair of casts. +  if (TruncInst *CSrc = dyn_cast<TruncInst>(Src)) {   // A->B->C cast +    // Get the sizes of the types involved.  We know that the intermediate type +    // will be smaller than A or C, but don't know the relation between A and C. +    Value *A = CSrc->getOperand(0); +    unsigned SrcSize = A->getType()->getPrimitiveSizeInBits(); +    unsigned MidSize = CSrc->getType()->getPrimitiveSizeInBits(); +    unsigned DstSize = CI.getType()->getPrimitiveSizeInBits(); +    // If we're actually extending zero bits, then if +    // SrcSize <  DstSize: zext(a & mask) +    // SrcSize == DstSize: a & mask +    // SrcSize  > DstSize: trunc(a) & mask +    if (SrcSize < DstSize) { +      APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize)); +      Constant *AndConst = ConstantInt::get(AndValue); +      Instruction *And = +        BinaryOperator::CreateAnd(A, AndConst, CSrc->getName()+".mask"); +      InsertNewInstBefore(And, CI); +      return new ZExtInst(And, CI.getType()); +    } else if (SrcSize == DstSize) { +      APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize)); +      return BinaryOperator::CreateAnd(A, ConstantInt::get(AndValue)); +    } else if (SrcSize > DstSize) { +      Instruction *Trunc = new TruncInst(A, CI.getType(), "tmp"); +      InsertNewInstBefore(Trunc, CI); +      APInt AndValue(APInt::getLowBitsSet(DstSize, MidSize)); +      return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(AndValue));      }    } | 

