diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 23f89bb66f..d01238a552 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -70,7 +70,7 @@ inline static unsigned getDigit(char cdigit, uint8_t radix) { if (r < radix) return r; - return -1U; + return std::numeric_limits::max(); } @@ -79,7 +79,7 @@ void APInt::initSlowCase(unsigned numBits, uint64_t val, bool isSigned) { pVal[0] = val; if (isSigned && int64_t(val) < 0) for (unsigned i = 1; i < getNumWords(); ++i) - pVal[i] = -1ULL; + pVal[i] = std::numeric_limits::max(); } void APInt::initSlowCase(const APInt& that) { @@ -735,7 +735,7 @@ unsigned APInt::countLeadingOnes() const { unsigned Count = llvm::countLeadingOnes(pVal[i] << shift); if (Count == highWordBits) { for (i--; i >= 0; --i) { - if (pVal[i] == -1ULL) + if (pVal[i] == std::numeric_limits::max()) Count += APINT_BITS_PER_WORD; else { Count += llvm::countLeadingOnes(pVal[i]); @@ -761,7 +761,8 @@ unsigned APInt::countTrailingZeros() const { unsigned APInt::countTrailingOnesSlowCase() const { unsigned Count = 0; unsigned i = 0; - for (; i < getNumWords() && pVal[i] == -1ULL; ++i) + for (; i < getNumWords() && pVal[i] == std::numeric_limits::max(); + ++i) Count += APINT_BITS_PER_WORD; if (i < getNumWords()) Count += llvm::countTrailingOnes(pVal[i]); @@ -1070,7 +1071,7 @@ APInt APInt::ashr(unsigned shiftAmt) const { // issues in the algorithm below. if (shiftAmt == BitWidth) { if (isNegative()) - return APInt(BitWidth, -1ULL, true); + return APInt(BitWidth, std::numeric_limits::max(), true); else return APInt(BitWidth, 0); } @@ -1123,7 +1124,8 @@ APInt APInt::ashr(unsigned shiftAmt) const { } // Remaining words are 0 or -1, just assign them. - uint64_t fillValue = (isNegative() ? -1ULL : 0); + uint64_t fillValue = + (isNegative() ? std::numeric_limits::max() : 0); for (unsigned i = breakWord+1; i < getNumWords(); ++i) val[i] = fillValue; APInt Result(val, BitWidth); @@ -2192,7 +2194,18 @@ void APInt::toString(SmallVectorImpl &Str, unsigned Radix, N = I; } else { Str.push_back('-'); - N = -(uint64_t)I; + // In this else block, all values of I must be less than 0. + // + // Because values are stored in 2's complement and I is a signed + // integer, the expression -I is equivalent to (~I + 1) for all values + // of I, except INT64_MIN, where -I is undefined behavior in C++ due to + // overflow. + // + // However, (~I + 1) is still well-defined even when I == INT64_MIN, and + // it evaluates to the same bit pattern as INT64_MIN. Because N is + // unsigned, assigning N = ~I + 1 preserves the exact bit pattern + // and correctly represents the 2's complement value of -I. + N = (~I + 1); } } @@ -2408,7 +2421,7 @@ APInt::tcLSB(const integerPart *parts, unsigned int n) } } - return -1U; + return std::numeric_limits::max(); } /* Returns the bit number of the most significant set bit of a number. @@ -2428,7 +2441,7 @@ APInt::tcMSB(const integerPart *parts, unsigned int n) } } while (n); - return -1U; + return std::numeric_limits::max(); } /* Copy the bit vector of width srcBITS from SRC, starting at bit