Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -4077,13 +4077,35 @@ llvm_unreachable("Unknown OverflowResult"); } -static ConstantRange constantRangeFromKnownBits(const KnownBits &Known) { +/// Create a ConstantRange from KnownBits that avoids wrapping in the unsigned +/// domain. +static ConstantRange unsignedConstantRangeFromKnownBits( + const KnownBits &Known) { if (Known.isUnknown()) return ConstantRange(Known.getBitWidth(), /* full */ true); return ConstantRange(Known.One, ~Known.Zero + 1); } +/// Create a ConstantRange from KnownBits that avoids wrapping in the singed +/// domain. +static ConstantRange signedConstantRangeFromKnownBits( + const KnownBits &Known) { + if (Known.isUnknown()) + return ConstantRange(Known.getBitWidth(), /* full */ true); + + // If we know the sign bit, this is the same as for unsigned ranges. + if (Known.isNegative() || Known.isNonNegative()) + return ConstantRange(Known.One, ~Known.Zero + 1); + + // If we don't know the sign bit, pick the lower bound as a negative number + // and the upper bound as a non-negative one. + APInt Lower = Known.One, Upper = ~Known.Zero; + Lower.setSignBit(); + Upper.clearSignBit(); + return ConstantRange(Lower, Upper + 1); +} + OverflowResult llvm::computeOverflowForUnsignedAdd( const Value *LHS, const Value *RHS, const DataLayout &DL, AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT, @@ -4092,56 +4114,11 @@ nullptr, UseInstrInfo); KnownBits RHSKnown = computeKnownBits(RHS, DL, /*Depth=*/0, AC, CxtI, DT, nullptr, UseInstrInfo); - ConstantRange LHSRange = constantRangeFromKnownBits(LHSKnown); - ConstantRange RHSRange = constantRangeFromKnownBits(RHSKnown); + ConstantRange LHSRange = unsignedConstantRangeFromKnownBits(LHSKnown); + ConstantRange RHSRange = unsignedConstantRangeFromKnownBits(RHSKnown); return mapOverflowResult(LHSRange.unsignedAddMayOverflow(RHSRange)); } -/// Return true if we can prove that adding the two values of the -/// knownbits will not overflow. -/// Otherwise return false. -static bool checkRippleForSignedAdd(const KnownBits &LHSKnown, - const KnownBits &RHSKnown) { - // Addition of two 2's complement numbers having opposite signs will never - // overflow. - if ((LHSKnown.isNegative() && RHSKnown.isNonNegative()) || - (LHSKnown.isNonNegative() && RHSKnown.isNegative())) - return true; - - // If either of the values is known to be non-negative, adding them can only - // overflow if the second is also non-negative, so we can assume that. - // Two non-negative numbers will only overflow if there is a carry to the - // sign bit, so we can check if even when the values are as big as possible - // there is no overflow to the sign bit. - if (LHSKnown.isNonNegative() || RHSKnown.isNonNegative()) { - APInt MaxLHS = ~LHSKnown.Zero; - MaxLHS.clearSignBit(); - APInt MaxRHS = ~RHSKnown.Zero; - MaxRHS.clearSignBit(); - APInt Result = std::move(MaxLHS) + std::move(MaxRHS); - return Result.isSignBitClear(); - } - - // If either of the values is known to be negative, adding them can only - // overflow if the second is also negative, so we can assume that. - // Two negative number will only overflow if there is no carry to the sign - // bit, so we can check if even when the values are as small as possible - // there is overflow to the sign bit. - if (LHSKnown.isNegative() || RHSKnown.isNegative()) { - APInt MinLHS = LHSKnown.One; - MinLHS.clearSignBit(); - APInt MinRHS = RHSKnown.One; - MinRHS.clearSignBit(); - APInt Result = std::move(MinLHS) + std::move(MinRHS); - return Result.isSignBitSet(); - } - - // If we reached here it means that we know nothing about the sign bits. - // In this case we can't know if there will be an overflow, since by - // changing the sign bits any two values can be made to overflow. - return false; -} - static OverflowResult computeOverflowForSignedAdd(const Value *LHS, const Value *RHS, const AddOperator *Add, @@ -4173,9 +4150,12 @@ KnownBits LHSKnown = computeKnownBits(LHS, DL, /*Depth=*/0, AC, CxtI, DT); KnownBits RHSKnown = computeKnownBits(RHS, DL, /*Depth=*/0, AC, CxtI, DT); - - if (checkRippleForSignedAdd(LHSKnown, RHSKnown)) - return OverflowResult::NeverOverflows; + ConstantRange LHSRange = signedConstantRangeFromKnownBits(LHSKnown); + ConstantRange RHSRange = signedConstantRangeFromKnownBits(RHSKnown); + OverflowResult OR = + mapOverflowResult(LHSRange.signedAddMayOverflow(RHSRange)); + if (OR != OverflowResult::MayOverflow) + return OR; // The remaining code needs Add to be available. Early returns if not so. if (!Add) @@ -4208,8 +4188,8 @@ const DominatorTree *DT) { KnownBits LHSKnown = computeKnownBits(LHS, DL, /*Depth=*/0, AC, CxtI, DT); KnownBits RHSKnown = computeKnownBits(RHS, DL, /*Depth=*/0, AC, CxtI, DT); - ConstantRange LHSRange = constantRangeFromKnownBits(LHSKnown); - ConstantRange RHSRange = constantRangeFromKnownBits(RHSKnown); + ConstantRange LHSRange = unsignedConstantRangeFromKnownBits(LHSKnown); + ConstantRange RHSRange = unsignedConstantRangeFromKnownBits(RHSKnown); return mapOverflowResult(LHSRange.unsignedSubMayOverflow(RHSRange)); }