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

@@ -2729,3 +2729,32 @@ OverflowResult llvm::computeOverflowForUnsignedMul(Value *LHS, Value *RHS,
return OverflowResult::MayOverflow;
}
OverflowResult llvm::computeOverflowForUnsignedAdd(Value *LHS, Value *RHS,
const DataLayout *DL,
AssumptionCache *AC,
const Instruction *CxtI,
const DominatorTree *DT) {
bool LHSKnownNonNegative, LHSKnownNegative;
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, DL, /*Depth=*/0,
AC, CxtI, DT);
if (LHSKnownNonNegative || LHSKnownNegative) {
bool RHSKnownNonNegative, RHSKnownNegative;
ComputeSignBit(RHS, RHSKnownNonNegative, RHSKnownNegative, DL, /*Depth=*/0,
AC, CxtI, DT);
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 OverflowResult::AlwaysOverflows;
}
if (LHSKnownNonNegative && RHSKnownNonNegative) {
// The sign bit is clear in both cases: this CANNOT overflow.
// Create a simple add instruction, and insert it into the struct.
return OverflowResult::NeverOverflows;
}
}
return OverflowResult::MayOverflow;
}