summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Support/APInt.cpp7
-rw-r--r--llvm/unittests/ADT/APIntTest.cpp20
2 files changed, 22 insertions, 5 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 9bb364af279..3f552db7963 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/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/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp
index 5d3afe9a159..1e20ebb320c 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/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
OpenPOWER on IntegriCloud