Make APInt::countLeadingZerosSlowCase() treat the contents of padding bits
authorJohn McCall <rjmccall@apple.com>
Wed, 3 Feb 2010 03:42:44 +0000 (03:42 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 3 Feb 2010 03:42:44 +0000 (03:42 +0000)
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

lib/Support/APInt.cpp
unittests/ADT/APFloatTest.cpp

index 9d1468493d5b4c577de1025146b466466225630d..f41b31a883ca5d9ae6c3816aca40a5f307bd569b 100644 (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) {
index 76cdafcf3fe16e008fba61e99bded2e8d06c9a08..b02cc3e31722df8e3c86d2c674fc970f46db6173 100644 (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