summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/APInt.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2017-04-24 17:37:10 +0000
committerCraig Topper <craig.topper@gmail.com>2017-04-24 17:37:10 +0000
commit1dec2811040cec45972dd926ccfa6f34c6f489b2 (patch)
tree6722f51aa46add8d5395e9c91d5528e132df1842 /llvm/lib/Support/APInt.cpp
parent0ab4f06bf11ab0d295f1d249f75a804b96fa2b2a (diff)
downloadbcm5719-llvm-1dec2811040cec45972dd926ccfa6f34c6f489b2.tar.gz
bcm5719-llvm-1dec2811040cec45972dd926ccfa6f34c6f489b2.zip
[APInt] Simplify the zext and sext methods
This replaces a hand written copy loop with a call to memcpy for both zext and sext. For sext, it replaces multiple if/else blocks propagating sign information forward. Now we just do a copy, a sign extension on the last copied word, a memset, and clearUnusedBits. Differential Revision: https://reviews.llvm.org/D32417 llvm-svn: 301201
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r--llvm/lib/Support/APInt.cpp51
1 files changed, 18 insertions, 33 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 9c668468ff9..1227d7528c8 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -939,40 +939,26 @@ APInt APInt::trunc(unsigned width) const {
}
// Sign extend to a new width.
-APInt APInt::sext(unsigned width) const {
- assert(width > BitWidth && "Invalid APInt SignExtend request");
+APInt APInt::sext(unsigned Width) const {
+ assert(Width > BitWidth && "Invalid APInt SignExtend request");
- if (width <= APINT_BITS_PER_WORD)
- return APInt(width, SignExtend64(VAL, BitWidth));
+ if (Width <= APINT_BITS_PER_WORD)
+ return APInt(Width, SignExtend64(VAL, BitWidth));
- APInt Result(getMemory(getNumWords(width)), width);
+ APInt Result(getMemory(getNumWords(Width)), Width);
- // Copy full words.
- unsigned i;
- uint64_t word = 0;
- for (i = 0; i != BitWidth / APINT_BITS_PER_WORD; i++) {
- word = getRawData()[i];
- Result.pVal[i] = word;
- }
-
- // Read and sign-extend any partial word.
- unsigned bits = (0 - BitWidth) % APINT_BITS_PER_WORD;
- if (bits != 0)
- word = (int64_t)getRawData()[i] << bits >> bits;
- else
- word = (int64_t)word >> (APINT_BITS_PER_WORD - 1);
-
- // Write remaining full words.
- for (; i != width / APINT_BITS_PER_WORD; i++) {
- Result.pVal[i] = word;
- word = (int64_t)word >> (APINT_BITS_PER_WORD - 1);
- }
+ // Copy words.
+ std::memcpy(Result.pVal, getRawData(), getNumWords() * APINT_WORD_SIZE);
- // Write any partial word.
- bits = (0 - width) % APINT_BITS_PER_WORD;
- if (bits != 0)
- Result.pVal[i] = word << bits >> bits;
+ // Sign extend the last word since there may be unused bits in the input.
+ Result.pVal[getNumWords() - 1] =
+ SignExtend64(Result.pVal[getNumWords() - 1],
+ ((BitWidth - 1) % APINT_BITS_PER_WORD) + 1);
+ // Fill with sign bits.
+ std::memset(Result.pVal + getNumWords(), isNegative() ? -1 : 0,
+ (Result.getNumWords() - getNumWords()) * APINT_WORD_SIZE);
+ Result.clearUnusedBits();
return Result;
}
@@ -986,12 +972,11 @@ APInt APInt::zext(unsigned width) const {
APInt Result(getMemory(getNumWords(width)), width);
// Copy words.
- unsigned i;
- for (i = 0; i != getNumWords(); i++)
- Result.pVal[i] = getRawData()[i];
+ std::memcpy(Result.pVal, getRawData(), getNumWords() * APINT_WORD_SIZE);
// Zero remaining words.
- memset(&Result.pVal[i], 0, (Result.getNumWords() - i) * APINT_WORD_SIZE);
+ std::memset(Result.pVal + getNumWords(), 0,
+ (Result.getNumWords() - getNumWords()) * APINT_WORD_SIZE);
return Result;
}
OpenPOWER on IntegriCloud