1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

[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
This commit is contained in:
Sanjay Patel 2016-04-11 15:43:41 +00:00
parent 23c7d74ce2
commit 2bc03c53fa

View File

@ -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;
case Instruction::Shl:
return canEvaluateShiftedShift(NumBits, isLeftShift, I, IC, CxtI);
// 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;
}
case Instruction::LShr: {
// We can often fold the shift into shifts-by-a-constant.
CI = dyn_cast<ConstantInt>(I->getOperand(1));