diff options
author | Sanjay Patel <spatel@rotateright.com> | 2016-04-11 15:43:41 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2016-04-11 15:43:41 +0000 |
commit | 6eaff5cec66e6e8164b53823b3b113f96269a6fc (patch) | |
tree | 68162b72d9b0be145b13ad0a1c35cd81b6e99461 /llvm/lib | |
parent | f9d88e650b89aebb0af85cd00639b55e740f2569 (diff) | |
download | bcm5719-llvm-6eaff5cec66e6e8164b53823b3b113f96269a6fc.tar.gz bcm5719-llvm-6eaff5cec66e6e8164b53823b3b113f96269a6fc.zip |
[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
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 61 |
1 files changed, 37 insertions, 24 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index fad7bc06ff2..688afb9d2e9 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<ConstantInt>(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<ConstantInt>(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<ConstantInt>(I->getOperand(1)); |