diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h --- a/llvm/include/llvm/ADT/APInt.h +++ b/llvm/include/llvm/ADT/APInt.h @@ -1491,6 +1491,13 @@ return U.pVal[0]; } + /// Get zero extended value if possible + /// + /// This method attempts to return the value of this APInt as a zero extended + /// uint64_t. The bitwidth must be <= 64 or the value must fit within a + /// uint64_t. Otherwise no value is returned. + Optional tryZExtValue() const; + /// Get sign extended value /// /// This method attempts to return the value of this APInt as a sign extended @@ -1503,6 +1510,13 @@ return int64_t(U.pVal[0]); } + /// Get sign extended value if possible + /// + /// This method attempts to return the value of this APInt as a zero extended + /// int64_t. The bitwidth must be <= 64 or the value must fit within an + /// int64_t. Otherwise no value is returned. + Optional trySExtValue() const; + /// Get bits required for string value. /// /// This method determines how many bits are required to hold the APInt diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -503,6 +503,16 @@ return retBits; } +Optional APInt::tryZExtValue() const { + return (getActiveBits() <= 64) ? Optional(getZExtValue()) + : Optional(); +} + +Optional APInt::trySExtValue() const { + return (getActiveBits() <= 64) ? Optional(getSExtValue()) + : Optional(); +} + unsigned APInt::getSufficientBitsNeeded(StringRef Str, uint8_t Radix) { assert(!Str.empty() && "Invalid string length"); size_t StrLen = Str.size(); diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -3133,4 +3133,15 @@ Map.find(ZeroWidthInt); } +TEST(APIntTest, TryExt) { + APInt small(32, 42); + APInt large(128, {0xffff, 0xffff}); + ASSERT_TRUE(small.tryZExtValue().has_value()); + ASSERT_TRUE(small.trySExtValue().has_value()); + ASSERT_FALSE(large.tryZExtValue().has_value()); + ASSERT_FALSE(large.trySExtValue().has_value()); + ASSERT_EQ(small.trySExtValue().value_or(41), 42); + ASSERT_EQ(large.trySExtValue().value_or(41), 41); +} + } // end anonymous namespace