diff options
author | Jay Foad <jay.foad@amd.com> | 2021-10-06 09:49:51 +0100 |
---|---|---|
committer | Jay Foad <jay.foad@amd.com> | 2022-05-14 09:54:24 +0100 |
commit | 169ae6db69882605a69e184237640f0c557243ee (patch) | |
tree | 90405959572d3e8d747182b5790ef3ce15bd897d /llvm/lib/Support/APInt.cpp | |
parent | 1ecc3d86ae3eeb43336c27c4d653e06236b918a2 (diff) | |
download | llvm-169ae6db69882605a69e184237640f0c557243ee.zip llvm-169ae6db69882605a69e184237640f0c557243ee.tar.gz llvm-169ae6db69882605a69e184237640f0c557243ee.tar.bz2 |
[APInt] Allow extending and truncating to the same width
Allow zext, sext, trunc, truncUSat and truncSSat to extend or truncate
to the same bit width, which is a no-op.
Disallowing this forced clients to use workarounds like using
zextOrTrunc (even though they never wanted truncation) or zextOrSelf
(even though they did not want its strange behaviour of allowing a
*smaller* bit width, which is also treated as a no-op).
Differential Revision: https://reviews.llvm.org/D125556
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r-- | llvm/lib/Support/APInt.cpp | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 401b4f7..3fc0415 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -896,11 +896,14 @@ double APInt::roundToDouble(bool isSigned) const { // Truncate to new width. APInt APInt::trunc(unsigned width) const { - assert(width < BitWidth && "Invalid APInt Truncate request"); + assert(width <= BitWidth && "Invalid APInt Truncate request"); if (width <= APINT_BITS_PER_WORD) return APInt(width, getRawData()[0]); + if (width == BitWidth) + return *this; + APInt Result(getMemory(getNumWords(width)), width); // Copy full words. @@ -918,7 +921,7 @@ APInt APInt::trunc(unsigned width) const { // Truncate to new width with unsigned saturation. APInt APInt::truncUSat(unsigned width) const { - assert(width < BitWidth && "Invalid APInt Truncate request"); + assert(width <= BitWidth && "Invalid APInt Truncate request"); // Can we just losslessly truncate it? if (isIntN(width)) @@ -929,7 +932,7 @@ APInt APInt::truncUSat(unsigned width) const { // Truncate to new width with signed saturation. APInt APInt::truncSSat(unsigned width) const { - assert(width < BitWidth && "Invalid APInt Truncate request"); + assert(width <= BitWidth && "Invalid APInt Truncate request"); // Can we just losslessly truncate it? if (isSignedIntN(width)) @@ -941,11 +944,14 @@ APInt APInt::truncSSat(unsigned width) const { // Sign extend to a new width. APInt APInt::sext(unsigned Width) const { - assert(Width > BitWidth && "Invalid APInt SignExtend request"); + assert(Width >= BitWidth && "Invalid APInt SignExtend request"); if (Width <= APINT_BITS_PER_WORD) return APInt(Width, SignExtend64(U.VAL, BitWidth)); + if (Width == BitWidth) + return *this; + APInt Result(getMemory(getNumWords(Width)), Width); // Copy words. @@ -965,11 +971,14 @@ APInt APInt::sext(unsigned Width) const { // Zero extend to a new width. APInt APInt::zext(unsigned width) const { - assert(width > BitWidth && "Invalid APInt ZeroExtend request"); + assert(width >= BitWidth && "Invalid APInt ZeroExtend request"); if (width <= APINT_BITS_PER_WORD) return APInt(width, U.VAL); + if (width == BitWidth) + return *this; + APInt Result(getMemory(getNumWords(width)), width); // Copy words. |