[ValueTracking] Use ConstantRange overflow checks for unsigned add/sub; NFC

Use the methods introduced in rL356276 to implement the
computeOverflowForUnsigned(Add|Sub) functions in ValueTracking, by
converting the KnownBits into a ConstantRange.

This is NFC: The existing KnownBits based implementation uses the same
logic as the the ConstantRange based one. This is not the case for the
signed equivalents, so I'm only changing unsigned here.

This is in preparation for D59386, which will also intersect the
computeConstantRange() result into the range determined from KnownBits.

llvm-svn: 356290
This commit is contained in:
Nikita Popov 2019-03-15 18:37:45 +00:00
parent 5af1c22d0b
commit 614b1bea97
1 changed files with 26 additions and 20 deletions

View File

@ -4064,6 +4064,26 @@ llvm::computeOverflowForSignedMul(const Value *LHS, const Value *RHS,
return OverflowResult::MayOverflow;
}
/// Convert ConstantRange OverflowResult into ValueTracking OverflowResult.
static OverflowResult mapOverflowResult(ConstantRange::OverflowResult OR) {
switch (OR) {
case ConstantRange::OverflowResult::MayOverflow:
return OverflowResult::MayOverflow;
case ConstantRange::OverflowResult::AlwaysOverflows:
return OverflowResult::AlwaysOverflows;
case ConstantRange::OverflowResult::NeverOverflows:
return OverflowResult::NeverOverflows;
}
llvm_unreachable("Unknown OverflowResult");
}
static ConstantRange constantRangeFromKnownBits(const KnownBits &Known) {
if (Known.isUnknown())
return ConstantRange(Known.getBitWidth(), /* full */ true);
return ConstantRange(Known.One, ~Known.Zero + 1);
}
OverflowResult llvm::computeOverflowForUnsignedAdd(
const Value *LHS, const Value *RHS, const DataLayout &DL,
AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT,
@ -4072,16 +4092,9 @@ OverflowResult llvm::computeOverflowForUnsignedAdd(
nullptr, UseInstrInfo);
KnownBits RHSKnown = computeKnownBits(RHS, DL, /*Depth=*/0, AC, CxtI, DT,
nullptr, UseInstrInfo);
// a + b overflows iff a > ~b. Determine whether this is never/always true
// based on the min/max values achievable under the known bits constraint.
APInt MinLHS = LHSKnown.One, MaxLHS = ~LHSKnown.Zero;
APInt MinInvRHS = RHSKnown.Zero, MaxInvRHS = ~RHSKnown.One;
if (MaxLHS.ule(MinInvRHS))
return OverflowResult::NeverOverflows;
if (MinLHS.ugt(MaxInvRHS))
return OverflowResult::AlwaysOverflows;
return OverflowResult::MayOverflow;
ConstantRange LHSRange = constantRangeFromKnownBits(LHSKnown);
ConstantRange RHSRange = constantRangeFromKnownBits(RHSKnown);
return mapOverflowResult(LHSRange.unsignedAddMayOverflow(RHSRange));
}
/// Return true if we can prove that adding the two values of the
@ -4195,16 +4208,9 @@ OverflowResult llvm::computeOverflowForUnsignedSub(const Value *LHS,
const DominatorTree *DT) {
KnownBits LHSKnown = computeKnownBits(LHS, DL, /*Depth=*/0, AC, CxtI, DT);
KnownBits RHSKnown = computeKnownBits(RHS, DL, /*Depth=*/0, AC, CxtI, DT);
// a - b overflows iff a < b. Determine whether this is never/always true
// based on the min/max values achievable under the known bits constraint.
APInt MinLHS = LHSKnown.One, MaxLHS = ~LHSKnown.Zero;
APInt MinRHS = RHSKnown.One, MaxRHS = ~RHSKnown.Zero;
if (MinLHS.uge(MaxRHS))
return OverflowResult::NeverOverflows;
if (MaxLHS.ult(MinRHS))
return OverflowResult::AlwaysOverflows;
return OverflowResult::MayOverflow;
ConstantRange LHSRange = constantRangeFromKnownBits(LHSKnown);
ConstantRange RHSRange = constantRangeFromKnownBits(RHSKnown);
return mapOverflowResult(LHSRange.unsignedSubMayOverflow(RHSRange));
}
OverflowResult llvm::computeOverflowForSignedSub(const Value *LHS,