diff options
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index deb2fb9509b..80a08e2fdd0 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4044,21 +4044,17 @@ OverflowResult llvm::computeOverflowForUnsignedAdd( bool UseInstrInfo) { KnownBits LHSKnown = computeKnownBits(LHS, DL, /*Depth=*/0, AC, CxtI, DT, nullptr, UseInstrInfo); - if (LHSKnown.isNonNegative() || LHSKnown.isNegative()) { - KnownBits RHSKnown = computeKnownBits(RHS, DL, /*Depth=*/0, AC, CxtI, DT, - nullptr, UseInstrInfo); - - if (LHSKnown.isNegative() && RHSKnown.isNegative()) { - // The sign bit is set in both cases: this MUST overflow. - return OverflowResult::AlwaysOverflows; - } - - if (LHSKnown.isNonNegative() && RHSKnown.isNonNegative()) { - // The sign bit is clear in both cases: this CANNOT overflow. - return OverflowResult::NeverOverflows; - } - } + 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; } |