]> granicus.if.org Git - llvm/commitdiff
[APInt] In sext single word case, use SignExtend64 and let the APInt constructor...
authorCraig Topper <craig.topper@gmail.com>
Sun, 23 Apr 2017 17:16:24 +0000 (17:16 +0000)
committerCraig Topper <craig.topper@gmail.com>
Sun, 23 Apr 2017 17:16:24 +0000 (17:16 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301133 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/APInt.cpp
unittests/ADT/APIntTest.cpp

index 9bb364af27918193f15ba5d9935bafe6891fbf2f..3f552db796393a7a399ad96122c207ae780ef6c1 100644 (file)
@@ -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);
 
index 5d3afe9a159f39b99a4a420175fe693da90008a6..1e20ebb320c9c717827b2969bc5d8610629db4ca 100644 (file)
@@ -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