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
This commit is contained in:
John McCall 2010-02-03 03:42:44 +00:00
parent 86809ccdad
commit 281d051921
2 changed files with 20 additions and 6 deletions

View File

@ -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) {

View File

@ -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