From 7271492c50a439afcff7198dfc1037814ddfc9ee Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sun, 23 Apr 2017 17:16:24 +0000 Subject: [PATCH] [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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301133 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/APInt.cpp | 7 ++----- unittests/ADT/APIntTest.cpp | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 9bb364af279..3f552db7963 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -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); diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp index 5d3afe9a159..1e20ebb320c 100644 --- a/unittests/ADT/APIntTest.cpp +++ b/unittests/ADT/APIntTest.cpp @@ -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 -- 2.40.0