diff options
| author | Chris Lattner <sabre@nondot.org> | 2010-01-08 19:04:21 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2010-01-08 19:04:21 +0000 |
| commit | a1e223ea1044612210e5fc785f436f2d268e7270 (patch) | |
| tree | e214601c85685f28c9134b4a24e409a49eacaab2 /llvm/lib/Transforms | |
| parent | a69f89c17a85d504d31a187111e5f0a0677c1921 (diff) | |
| download | bcm5719-llvm-a1e223ea1044612210e5fc785f436f2d268e7270.tar.gz bcm5719-llvm-a1e223ea1044612210e5fc785f436f2d268e7270.zip | |
teach instcombine to delete sign extending shift pairs (sra(shl X, C), C) when
the input is already sign extended.
llvm-svn: 93019
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 404fcecc334..1c75e558a96 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -414,17 +414,28 @@ Instruction *InstCombiner::visitAShr(BinaryOperator &I) { if (Instruction *R = commonShiftTransforms(I)) return R; - Value *Op0 = I.getOperand(0); + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - // ashr int -1, X = -1 (for any arithmetic shift rights of ~0) - if (ConstantInt *CSI = dyn_cast<ConstantInt>(Op0)) + if (ConstantInt *CSI = dyn_cast<ConstantInt>(Op0)) { + // ashr int -1, X = -1 (for any arithmetic shift rights of ~0) if (CSI->isAllOnesValue()) return ReplaceInstUsesWith(I, CSI); + } + + if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) { + // If the input is a SHL by the same constant (ashr (shl X, C), C), then we + // have a sign-extend idiom. If the input value is known to already be sign + // extended enough, delete the extension. + Value *X; + if (match(Op0, m_Shl(m_Value(X), m_Specific(Op1))) && + ComputeNumSignBits(X) > Op1C->getZExtValue()) + return ReplaceInstUsesWith(I, X); + } // See if we can turn a signed shr into an unsigned shr. if (MaskedValueIsZero(Op0, APInt::getSignBit(I.getType()->getScalarSizeInBits()))) - return BinaryOperator::CreateLShr(Op0, I.getOperand(1)); + return BinaryOperator::CreateLShr(Op0, Op1); // Arithmetic shifting an all-sign-bit value is a no-op. unsigned NumSignBits = ComputeNumSignBits(Op0); |

