InstSimplify: Move a transform from InstCombine to InstSimplify

Several combines involving icmp (shl C2, %X) C1 can be simplified
without introducing any new instructions.  Move them to InstSimplify;
while we are at it, make them more powerful.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216642 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer
2014-08-28 03:34:28 +00:00
parent 4a76317ebb
commit b11fff1d8a
4 changed files with 105 additions and 44 deletions

View File

@ -2388,6 +2388,41 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
return getTrue(ITy);
}
// handle:
// CI2 << X == CI
// CI2 << X != CI
//
// where CI2 is a power of 2 and CI isn't
if (auto *CI = dyn_cast<ConstantInt>(RHS)) {
const APInt *CI2Val, *CIVal = &CI->getValue();
if (LBO && match(LBO, m_Shl(m_APInt(CI2Val), m_Value())) &&
CI2Val->isPowerOf2()) {
if (!CIVal->isPowerOf2()) {
// CI2 << X can equal zero in some circumstances,
// this simplification is unsafe if CI is zero.
//
// We know it is safe if:
// - The shift is nsw, we can't shift out the one bit.
// - The shift is nuw, we can't shift out the one bit.
// - CI2 is one
// - CI isn't zero
if (LBO->hasNoSignedWrap() || LBO->hasNoUnsignedWrap() ||
*CI2Val == 1 || !CI->isZero()) {
if (Pred == ICmpInst::ICMP_EQ)
return ConstantInt::getFalse(RHS->getContext());
if (Pred == ICmpInst::ICMP_NE)
return ConstantInt::getTrue(RHS->getContext());
}
}
if (CIVal->isSignBit() && *CI2Val == 1) {
if (Pred == ICmpInst::ICMP_UGT)
return ConstantInt::getFalse(RHS->getContext());
if (Pred == ICmpInst::ICMP_ULE)
return ConstantInt::getTrue(RHS->getContext());
}
}
}
if (MaxRecurse && LBO && RBO && LBO->getOpcode() == RBO->getOpcode() &&
LBO->getOperand(1) == RBO->getOperand(1)) {
switch (LBO->getOpcode()) {