From 9edfb08d935a3d4c2bd662732cd5a93254452f51 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sun, 16 Apr 2017 01:03:51 +0000 Subject: [PATCH] [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. llvm-svn: 300405 --- llvm/lib/Support/APInt.cpp | 2 +- llvm/unittests/ADT/APIntTest.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 03f7f5b56e31..0c7da1dad0d2 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -1188,7 +1188,7 @@ void APInt::lshrInPlace(unsigned shiftAmt) { // 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) diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp index 17542383b33a..65481f5b2f22 100644 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -37,6 +37,11 @@ TEST(APIntTest, i64_ArithmeticRightShiftNegative) { EXPECT_EQ(neg_one, neg_one.ashr(7)); } +TEST(APIntTest, i64_LogicalRightShiftNegative) { + const APInt neg_one(128, static_cast(-1), true); + EXPECT_EQ(0, neg_one.lshr(257)); +} + TEST(APIntTest, i128_NegativeCount) { APInt Minus3(128, static_cast(-3), true); EXPECT_EQ(126u, Minus3.countLeadingOnes());