Analysis: Reformulate WillNotOverflowUnsignedAdd for reusability

WillNotOverflowUnsignedAdd's smarts will live in ValueTracking as
computeOverflowForUnsignedAdd.  It now returns a tri-state result:
never overflows, always overflows and sometimes overflows.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225329 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer
2015-01-07 00:39:50 +00:00
parent c8c560867f
commit 72a9513e92
5 changed files with 46 additions and 45 deletions

View File

@@ -352,33 +352,11 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
break;
case Intrinsic::uadd_with_overflow: {
Value *LHS = II->getArgOperand(0), *RHS = II->getArgOperand(1);
IntegerType *IT = cast<IntegerType>(II->getArgOperand(0)->getType());
uint32_t BitWidth = IT->getBitWidth();
APInt LHSKnownZero(BitWidth, 0);
APInt LHSKnownOne(BitWidth, 0);
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, 0, II);
bool LHSKnownNegative = LHSKnownOne[BitWidth - 1];
bool LHSKnownPositive = LHSKnownZero[BitWidth - 1];
if (LHSKnownNegative || LHSKnownPositive) {
APInt RHSKnownZero(BitWidth, 0);
APInt RHSKnownOne(BitWidth, 0);
computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, 0, II);
bool RHSKnownNegative = RHSKnownOne[BitWidth - 1];
bool RHSKnownPositive = RHSKnownZero[BitWidth - 1];
if (LHSKnownNegative && RHSKnownNegative) {
// The sign bit is set in both cases: this MUST overflow.
// Create a simple add instruction, and insert it into the struct.
return CreateOverflowTuple(II, Builder->CreateAdd(LHS, RHS), true,
/*ReUseName*/true);
}
if (LHSKnownPositive && RHSKnownPositive) {
// The sign bit is clear in both cases: this CANNOT overflow.
// Create a simple add instruction, and insert it into the struct.
return CreateOverflowTuple(II, Builder->CreateNUWAdd(LHS, RHS), false);
}
}
OverflowResult OR = computeOverflowForUnsignedAdd(LHS, RHS, II);
if (OR == OverflowResult::NeverOverflows)
return CreateOverflowTuple(II, Builder->CreateNUWAdd(LHS, RHS), false);
if (OR == OverflowResult::AlwaysOverflows)
return CreateOverflowTuple(II, Builder->CreateAdd(LHS, RHS), true);
}
// FALL THROUGH uadd into sadd
case Intrinsic::sadd_with_overflow: