InstSimplify: Optimize ICmpInst xform that uses computeKnownBits

A few things:
- computeKnownBits is relatively expensive, let's delay its use as long
  as we can.
- Don't create two APInt values just to run computeKnownBits on a
  ConstantInt, we already know the exact value!
- Avoid creating a temporary APInt value in order to calculate unary
  negation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222092 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer 2014-11-16 02:20:08 +00:00
parent 37f645cb34
commit f5dc5ae36b

View File

@ -2422,27 +2422,6 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
}
}
// If a bit is known to be zero for A and known to be one for B,
// then A and B cannot be equal.
if (ICmpInst::isEquality(Pred)) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
uint32_t BitWidth = CI->getBitWidth();
APInt LHSKnownZero(BitWidth, 0);
APInt LHSKnownOne(BitWidth, 0);
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, Q.DL,
0, Q.AT, Q.CxtI, Q.DT);
APInt RHSKnownZero(BitWidth, 0);
APInt RHSKnownOne(BitWidth, 0);
computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, Q.DL,
0, Q.AT, Q.CxtI, Q.DT);
if (((LHSKnownOne & RHSKnownZero) != 0) ||
((LHSKnownZero & RHSKnownOne) != 0))
return (Pred == ICmpInst::ICMP_EQ)
? ConstantInt::getFalse(CI->getContext())
: ConstantInt::getTrue(CI->getContext());
}
}
// Special logic for binary operators.
BinaryOperator *LBO = dyn_cast<BinaryOperator>(LHS);
BinaryOperator *RBO = dyn_cast<BinaryOperator>(RHS);
@ -2881,6 +2860,23 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
}
}
// If a bit is known to be zero for A and known to be one for B,
// then A and B cannot be equal.
if (ICmpInst::isEquality(Pred)) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
uint32_t BitWidth = CI->getBitWidth();
APInt LHSKnownZero(BitWidth, 0);
APInt LHSKnownOne(BitWidth, 0);
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, Q.DL, /*Depth=*/0, Q.AT,
Q.CxtI, Q.DT);
const APInt &RHSVal = CI->getValue();
if (((LHSKnownZero & RHSVal) != 0) || ((LHSKnownOne & ~RHSVal) != 0))
return Pred == ICmpInst::ICMP_EQ
? ConstantInt::getFalse(CI->getContext())
: ConstantInt::getTrue(CI->getContext());
}
}
// If the comparison is with the result of a select instruction, check whether
// comparing with either branch of the select always yields the same value.
if (isa<SelectInst>(LHS) || isa<SelectInst>(RHS))