[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:
parent
5af1c22d0b
commit
614b1bea97
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue