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 | fd3daa74c2e2df49150c710270c767a4564f04e1 (patch) | |
| tree | a08d25bb0e029404b4c72f557effc80f0c6d9738 /lib/Transforms | |
| parent | 6864db6fac4b9e0c857966e529961c0f31da5814 (diff) | |
| download | external_llvm-fd3daa74c2e2df49150c710270c767a4564f04e1.zip external_llvm-fd3daa74c2e2df49150c710270c767a4564f04e1.tar.gz external_llvm-fd3daa74c2e2df49150c710270c767a4564f04e1.tar.bz2 | |
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).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73705 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
| -rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index bf287f2..5bd17e0 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/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; } |
