summaryrefslogtreecommitdiff
path: root/lib/Support/APInt.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-02-03 03:42:44 +0000
committerJohn McCall <rjmccall@apple.com>2010-02-03 03:42:44 +0000
commit281d051921be84e2f790dd567958cd200b28e2dd (patch)
tree50e4c874d9cbddc81024ed8e9a4acf4154b12c0d /lib/Support/APInt.cpp
parent86809ccdaddf48a87ed772bc01464812caaf4baf (diff)
downloadllvm-281d051921be84e2f790dd567958cd200b28e2dd.tar.gz
llvm-281d051921be84e2f790dd567958cd200b28e2dd.tar.bz2
llvm-281d051921be84e2f790dd567958cd200b28e2dd.tar.xz
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
Diffstat (limited to 'lib/Support/APInt.cpp')
-rw-r--r--lib/Support/APInt.cpp24
1 files changed, 18 insertions, 6 deletions
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 9d1468493d..f41b31a883 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) {