[llvm] r301133 - [APInt] In sext single word case, use SignExtend64 and let the APInt constructor mask off any excess bits.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 23 10:16:24 PDT 2017


Author: ctopper
Date: Sun Apr 23 12:16:24 2017
New Revision: 301133

URL: http://llvm.org/viewvc/llvm-project?rev=301133&view=rev
Log:
[APInt] In sext single word case, use SignExtend64 and let the APInt constructor mask off any excess bits.

The current code is trying to be clever with shifts to avoid needing to clear unused bits. But it looks like the compiler is unable to optimize out the unused bit handling in the APInt constructor. Given this its better to just use SignExtend64 and have more readable code.

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=301133&r1=301132&r2=301133&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APInt.cpp (original)
+++ llvm/trunk/lib/Support/APInt.cpp Sun Apr 23 12:16:24 2017
@@ -942,11 +942,8 @@ APInt APInt::trunc(unsigned width) const
 APInt APInt::sext(unsigned width) const {
   assert(width > BitWidth && "Invalid APInt SignExtend request");
 
-  if (width <= APINT_BITS_PER_WORD) {
-    uint64_t val = VAL << (APINT_BITS_PER_WORD - BitWidth);
-    val = (int64_t)val >> (width - BitWidth);
-    return APInt(width, val >> (APINT_BITS_PER_WORD - width));
-  }
+  if (width <= APINT_BITS_PER_WORD)
+    return APInt(width, SignExtend64(VAL, BitWidth));
 
   APInt Result(getMemory(getNumWords(width)), width);
 

Modified: llvm/trunk/unittests/ADT/APIntTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APIntTest.cpp?rev=301133&r1=301132&r2=301133&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APIntTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APIntTest.cpp Sun Apr 23 12:16:24 2017
@@ -2086,4 +2086,24 @@ TEST(APIntTest, isSubsetOf) {
   EXPECT_TRUE(i128_3.isSubsetOf(i128_3));
 }
 
+TEST(APIntTest, sext) {
+  EXPECT_EQ(0, APInt(1, 0).sext(64));
+  EXPECT_EQ(~uint64_t(0), APInt(1, 1).sext(64));
+
+  APInt i32_max(APInt::getSignedMaxValue(32).sext(63));
+  EXPECT_EQ(32U, i32_max.countLeadingZeros());
+  EXPECT_EQ(0U, i32_max.countTrailingZeros());
+  EXPECT_EQ(31U, i32_max.countPopulation());
+
+  APInt i32_min(APInt::getSignedMinValue(32).sext(63));
+  EXPECT_EQ(32U, i32_min.countLeadingOnes());
+  EXPECT_EQ(31U, i32_min.countTrailingZeros());
+  EXPECT_EQ(32U, i32_min.countPopulation());
+
+  APInt i32_neg1(APInt(32, ~uint64_t(0)).sext(63));
+  EXPECT_EQ(63U, i32_neg1.countLeadingOnes());
+  EXPECT_EQ(0U, i32_neg1.countTrailingZeros());
+  EXPECT_EQ(63U, i32_neg1.countPopulation());
+}
+
 } // end anonymous namespace




More information about the llvm-commits mailing list