[llvm] r364710 - [APInt] Fix getBitsNeeded for INT_MIN values

Dmitry Venikov via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 29 04:38:12 PDT 2019


Author: quolyk
Date: Sat Jun 29 04:38:12 2019
New Revision: 364710

URL: http://llvm.org/viewvc/llvm-project?rev=364710&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/Support/APInt.cpp
    llvm/trunk/unittests/ADT/APIntTest.cpp

Modified: llvm/trunk/lib/Support/APInt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=364710&r1=364709&r2=364710&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APInt.cpp (original)
+++ llvm/trunk/lib/Support/APInt.cpp Sat Jun 29 04:38:12 2019
@@ -482,10 +482,13 @@ unsigned APInt::getBitsNeeded(StringRef
   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;
   }

Modified: llvm/trunk/unittests/ADT/APIntTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APIntTest.cpp?rev=364710&r1=364709&r2=364710&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APIntTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APIntTest.cpp Sat Jun 29 04:38:12 2019
@@ -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) {




More information about the llvm-commits mailing list