diff options
author | Dmitry Venikov <quolyk@gmail.com> | 2019-06-29 11:38:12 +0000 |
---|---|---|
committer | Dmitry Venikov <quolyk@gmail.com> | 2019-06-29 11:38:12 +0000 |
commit | 9e9eb62f9fd75706377ac6cf3abffad1328d0d4f (patch) | |
tree | 2c7c9df61ee027da81be92cc5e68970d3d1cbc8c | |
parent | 2d756c4feb69e4fe0ed8556e05bc2ff3c7bc1007 (diff) | |
download | bcm5719-llvm-9e9eb62f9fd75706377ac6cf3abffad1328d0d4f.tar.gz bcm5719-llvm-9e9eb62f9fd75706377ac6cf3abffad1328d0d4f.zip |
[APInt] Fix getBitsNeeded for INT_MIN values
Summary: This patch fixes behaviour of APInt::getBitsNeeded for INT_MIN 10 bits values.
Reviewers: regehr, RKSimon
Reviewed By: RKSimon
Subscribers: grandinj, dexonsmith, kristina, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D63691
llvm-svn: 364710
-rw-r--r-- | llvm/lib/Support/APInt.cpp | 5 | ||||
-rw-r--r-- | llvm/unittests/ADT/APIntTest.cpp | 17 |
2 files changed, 19 insertions, 3 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index d008055bd45..3b40d9bd734 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -482,10 +482,13 @@ unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) { APInt tmp(sufficient, StringRef(p, slen), radix); // Compute how many bits are required. If the log is infinite, assume we need - // just bit. + // just bit. If the log is exact and value is negative, then the value is + // MinSignedValue with (log + 1) bits. unsigned log = tmp.logBase2(); if (log == (unsigned)-1) { return isNegative + 1; + } else if (isNegative && tmp.isPowerOf2()) { + return isNegative + log; } else { return isNegative + log + 1; } diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp index f5f6594b836..64560669342 100644 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -1263,8 +1263,21 @@ TEST(APIntTest, StringBitsNeeded10) { EXPECT_EQ(6U, APInt::getBitsNeeded("-19", 10)); EXPECT_EQ(6U, APInt::getBitsNeeded("-20", 10)); - // TODO: INT_MIN cases need 1 less bit (PR40897) - EXPECT_EQ(9U, APInt::getBitsNeeded("-128", 10)); + EXPECT_EQ(1U, APInt::getBitsNeeded("-1", 10)); + EXPECT_EQ(2U, APInt::getBitsNeeded("-2", 10)); + EXPECT_EQ(3U, APInt::getBitsNeeded("-4", 10)); + EXPECT_EQ(4U, APInt::getBitsNeeded("-8", 10)); + EXPECT_EQ(5U, APInt::getBitsNeeded("-16", 10)); + EXPECT_EQ(6U, APInt::getBitsNeeded("-23", 10)); + EXPECT_EQ(6U, APInt::getBitsNeeded("-32", 10)); + EXPECT_EQ(7U, APInt::getBitsNeeded("-64", 10)); + EXPECT_EQ(8U, APInt::getBitsNeeded("-127", 10)); + EXPECT_EQ(8U, APInt::getBitsNeeded("-128", 10)); + EXPECT_EQ(9U, APInt::getBitsNeeded("-255", 10)); + EXPECT_EQ(9U, APInt::getBitsNeeded("-256", 10)); + EXPECT_EQ(10U, APInt::getBitsNeeded("-512", 10)); + EXPECT_EQ(11U, APInt::getBitsNeeded("-1024", 10)); + EXPECT_EQ(12U, APInt::getBitsNeeded("-1025", 10)); } TEST(APIntTest, StringBitsNeeded16) { |