[llvm] r300405 - [APInt] Fix a bug in lshr by a value more than 64 bits above the bit width.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 15 18:03:51 PDT 2017


Author: ctopper
Date: Sat Apr 15 20:03:51 2017
New Revision: 300405

URL: http://llvm.org/viewvc/llvm-project?rev=300405&view=rev
Log:
[APInt] Fix a bug in lshr by a value more than 64 bits above the bit width.

This was throwing an assert because we determined the intra-word shift amount by subtracting the size of the full word shift from the total shift amount. But we failed to account for the fact that we clipped the full word shifts by total words first. To fix this just calculate the intra-word shift as the remainder of dividing by bits per word.

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=300405&r1=300404&r2=300405&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APInt.cpp (original)
+++ llvm/trunk/lib/Support/APInt.cpp Sat Apr 15 20:03:51 2017
@@ -1188,7 +1188,7 @@ void APInt::lshrInPlace(unsigned shiftAm
 
   // Fill in first Words - ShiftFullWords by shifting.
   lshrWords(pVal, pVal + ShiftFullWords, Words - ShiftFullWords,
-            shiftAmt - (ShiftFullWords * APINT_BITS_PER_WORD));
+            shiftAmt % APINT_BITS_PER_WORD);
 
   // The remaining high words are all zero.
   for (unsigned I = Words - ShiftFullWords; I != Words; ++I)

Modified: llvm/trunk/unittests/ADT/APIntTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APIntTest.cpp?rev=300405&r1=300404&r2=300405&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APIntTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APIntTest.cpp Sat Apr 15 20:03:51 2017
@@ -37,6 +37,11 @@ TEST(APIntTest, i64_ArithmeticRightShift
   EXPECT_EQ(neg_one, neg_one.ashr(7));
 }
 
+TEST(APIntTest, i64_LogicalRightShiftNegative) {
+  const APInt neg_one(128, static_cast<uint64_t>(-1), true);
+  EXPECT_EQ(0, neg_one.lshr(257));
+}
+
 TEST(APIntTest, i128_NegativeCount) {
   APInt Minus3(128, static_cast<uint64_t>(-3), true);
   EXPECT_EQ(126u, Minus3.countLeadingOnes());




More information about the llvm-commits mailing list