From 2e33bbaff0904a8568eac4c9329a39834edf2c68 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 12 Jun 2017 14:23:43 +0000 Subject: [InstCombine] lshr (sext iM X to iN), N-M --> zext (ashr X, min(N-M, M-1)) to iN This is a follow-up to https://reviews.llvm.org/D33879 / https://reviews.llvm.org/rL304939 , and was discussed in https://reviews.llvm.org/D33338. We prefer this form because a narrower shift may be cheaper, and we can more easily fold a zext than a sext. http://rise4fun.com/Alive/slVe Name: shz %s = sext i8 %x to i12 %r = lshr i12 %s, 4 => %a = ashr i8 %x, 4 %r = zext i8 %a to i12 llvm-svn: 305190 --- llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'llvm/lib/Transforms') diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 3f2ddcacce2..8cec865c642 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -682,11 +682,11 @@ Instruction *InstCombiner::visitLShr(BinaryOperator &I) { return BinaryOperator::CreateAnd(X, ConstantInt::get(Ty, Mask)); } - if (match(Op0, m_SExt(m_Value(X)))) { + if (match(Op0, m_SExt(m_Value(X))) && + (!Ty->isIntegerTy() || shouldChangeType(Ty, X->getType()))) { // Are we moving the sign bit to the low bit and widening with high zeros? unsigned SrcTyBitWidth = X->getType()->getScalarSizeInBits(); - if (ShAmt == BitWidth - 1 && - (!Ty->isIntegerTy() || shouldChangeType(Ty, X->getType()))) { + if (ShAmt == BitWidth - 1) { // lshr (sext i1 X to iN), N-1 --> zext X to iN if (SrcTyBitWidth == 1) return new ZExtInst(X, Ty); @@ -698,7 +698,13 @@ Instruction *InstCombiner::visitLShr(BinaryOperator &I) { } } - // TODO: Convert to ashr+zext if the shift equals the extension amount. + // lshr (sext iM X to iN), N-M --> zext (ashr X, min(N-M, M-1)) to iN + if (ShAmt == BitWidth - SrcTyBitWidth && Op0->hasOneUse()) { + // The new shift amount can't be more than the narrow source type. + unsigned NewShAmt = std::min(ShAmt, SrcTyBitWidth - 1); + Value *AShr = Builder->CreateAShr(X, NewShAmt); + return new ZExtInst(AShr, Ty); + } } if (match(Op0, m_LShr(m_Value(X), m_APInt(ShOp1)))) { -- cgit v1.2.3