From: John McCall Date: Wed, 3 Feb 2010 03:42:44 +0000 (+0000) Subject: Make APInt::countLeadingZerosSlowCase() treat the contents of padding bits X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=281d051921be84e2f790dd567958cd200b28e2dd;p=oota-llvm.git Make APInt::countLeadingZerosSlowCase() treat the contents of padding bits as undefined. Fixes an assertion in APFloat::toString noticed by Dale. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95196 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 9d1468493d5..f41b31a883c 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -767,8 +767,23 @@ bool APInt::isPowerOf2() const { } unsigned APInt::countLeadingZerosSlowCase() const { - unsigned Count = 0; - for (unsigned i = getNumWords(); i > 0u; --i) { + // Treat the most significand word differently because it might have + // meaningless bits set beyond the precision. + unsigned BitsInMSW = BitWidth % APINT_BITS_PER_WORD; + integerPart MSWMask; + if (BitsInMSW) MSWMask = (integerPart(1) << BitsInMSW) - 1; + else { + MSWMask = ~integerPart(0); + BitsInMSW = APINT_BITS_PER_WORD; + } + + unsigned i = getNumWords(); + integerPart MSW = pVal[i-1] & MSWMask; + if (MSW) + return CountLeadingZeros_64(MSW) - (APINT_BITS_PER_WORD - BitsInMSW); + + unsigned Count = BitsInMSW; + for (--i; i > 0u; --i) { if (pVal[i-1] == 0) Count += APINT_BITS_PER_WORD; else { @@ -776,10 +791,7 @@ unsigned APInt::countLeadingZerosSlowCase() const { break; } } - unsigned remainder = BitWidth % APINT_BITS_PER_WORD; - if (remainder) - Count -= APINT_BITS_PER_WORD - remainder; - return std::min(Count, BitWidth); + return Count; } static unsigned countLeadingOnes_64(uint64_t V, unsigned skip) { diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp index 76cdafcf3fe..b02cc3e3172 100644 --- a/unittests/ADT/APFloatTest.cpp +++ b/unittests/ADT/APFloatTest.cpp @@ -333,6 +333,8 @@ TEST(APFloatTest, toString) { ASSERT_EQ("1.01E-2", convertToString(1.01E-2, 5, 1)); ASSERT_EQ("0.7853981633974483", convertToString(0.78539816339744830961, 0, 3)); ASSERT_EQ("4.940656458412465E-324", convertToString(4.9406564584124654e-324, 0, 3)); + ASSERT_EQ("873.1834", convertToString(873.1834, 0, 1)); + ASSERT_EQ("8.731834E+2", convertToString(873.1834, 0, 0)); } #ifdef GTEST_HAS_DEATH_TEST