From 6eaff5cec66e6e8164b53823b3b113f96269a6fc Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 11 Apr 2016 15:43:41 +0000 Subject: [PATCH] [InstCombine] add helper function for shift-shift optimization (NFCI) This is step 2 of refactoring to solve PR26760: https://llvm.org/bugs/show_bug.cgi?id=26760 llvm-svn: 265951 --- .../Transforms/InstCombine/InstCombineShifts.cpp | 61 +++++++++++++--------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index fad7bc0..688afb9 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -55,6 +55,41 @@ Instruction *InstCombiner::commonShiftTransforms(BinaryOperator &I) { return nullptr; } +/// Return true if we can simplify two logical (either left or right) shifts +/// that have constant shift amounts. +/// FIXME: This can be extended to handle either a shl or lshr instruction, but +/// it is currently only valid for a shl. +static bool canEvaluateShiftedShift(unsigned NumBits, bool IsLeftShift, + Instruction *I, InstCombiner &IC, + Instruction *CxtI) { + // We can often fold the shift into shifts-by-a-constant. + ConstantInt *CI = dyn_cast(I->getOperand(1)); + if (!CI) + return false; + + // We can always fold shl(c1)+shl(c2) -> shl(c1+c2). + if (IsLeftShift) + return true; + + // We can always turn shl(c)+shr(c) -> and(c2). + if (CI->getValue() == NumBits) + return true; + + unsigned TypeWidth = I->getType()->getScalarSizeInBits(); + + // We can turn shl(c1)+shr(c2) -> shl(c3)+and(c4), but it isn't + // profitable unless we know the and'd out bits are already zero. + if (CI->getZExtValue() > NumBits) { + unsigned LowBits = TypeWidth - CI->getZExtValue(); + if (IC.MaskedValueIsZero( + I->getOperand(0), + APInt::getLowBitsSet(TypeWidth, NumBits) << LowBits, 0, CxtI)) + return true; + } + + return false; +} + /// See if we can compute the specified value, but shifted /// logically to the left or right by some number of bits. This should return /// true if the expression can be computed for the same cost as the current @@ -114,31 +149,9 @@ static bool CanEvaluateShifted(Value *V, unsigned NumBits, bool isLeftShift, return CanEvaluateShifted(I->getOperand(0), NumBits, isLeftShift, IC, I) && CanEvaluateShifted(I->getOperand(1), NumBits, isLeftShift, IC, I); - case Instruction::Shl: { - // We can often fold the shift into shifts-by-a-constant. - CI = dyn_cast(I->getOperand(1)); - if (!CI) return false; - - // We can always fold shl(c1)+shl(c2) -> shl(c1+c2). - if (isLeftShift) return true; - - // We can always turn shl(c)+shr(c) -> and(c2). - if (CI->getValue() == NumBits) return true; - - unsigned TypeWidth = I->getType()->getScalarSizeInBits(); - - // We can turn shl(c1)+shr(c2) -> shl(c3)+and(c4), but it isn't - // profitable unless we know the and'd out bits are already zero. - if (CI->getZExtValue() > NumBits) { - unsigned LowBits = TypeWidth - CI->getZExtValue(); - if (IC.MaskedValueIsZero(I->getOperand(0), - APInt::getLowBitsSet(TypeWidth, NumBits) << LowBits, - 0, CxtI)) - return true; - } + case Instruction::Shl: + return canEvaluateShiftedShift(NumBits, isLeftShift, I, IC, CxtI); - return false; - } case Instruction::LShr: { // We can often fold the shift into shifts-by-a-constant. CI = dyn_cast(I->getOperand(1)); -- 2.7.4