<div dir="ltr">Thanks for the prompt fix! :-)</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Sep 8, 2021 at 4:35 PM Chris Lattner <<a href="mailto:clattner@nondot.org">clattner@nondot.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;">Fixed in rG717ed1c31052, sorry for the breakage!<div><br></div><div>-Chris<br><div><br><blockquote type="cite"><div>On Sep 8, 2021, at 4:32 PM, Geoffrey Martin-Noble <<a href="mailto:gcmn@google.com" target="_blank">gcmn@google.com</a>> wrote:</div><br><div><div dir="ltr">I'm seeing failures from this because clang uses APInt::needsCleanup in Expr.cpp which was public before<br><br>```<br>llvm-project/clang/lib/AST/Expr.cpp:260:25: error: 'needsCleanup' is a private member of 'llvm::APInt'<br>    if (!Value.getInt().needsCleanup())<br>                        ^<br>llvm-project/llvm/include/llvm/ADT/APInt.h:1994:8: note: declared private here<br>  bool needsCleanup() const { return !isSingleWord(); }<br><div>```</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Sep 8, 2021 at 4:09 PM Chris Lattner via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
Author: Chris Lattner<br>
Date: 2021-09-08T16:08:57-07:00<br>
New Revision: a024d35b3885490221e78b835b087a830cc3c325<br>
<br>
URL: <a href="https://github.com/llvm/llvm-project/commit/a024d35b3885490221e78b835b087a830cc3c325" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/a024d35b3885490221e78b835b087a830cc3c325</a><br>
DIFF: <a href="https://github.com/llvm/llvm-project/commit/a024d35b3885490221e78b835b087a830cc3c325.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/a024d35b3885490221e78b835b087a830cc3c325.diff</a><br>
<br>
LOG: [APInt.h] Clean up the APInt interface. NFC.<br>
<br>
This moves all the private implementation details to the bottom of<br>
the header, and pushes all the "make an APInt" stuff up to the top.<br>
This is in prep for making other changes to spiff up APInt a bit.<br>
<br>
Added: <br>
<br>
<br>
Modified: <br>
    llvm/include/llvm/ADT/APInt.h<br>
<br>
Removed: <br>
<br>
<br>
<br>
################################################################################<br>
diff  --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h<br>
index 68a229478c189..7ab49d23840a1 100644<br>
--- a/llvm/include/llvm/ADT/APInt.h<br>
+++ b/llvm/include/llvm/ADT/APInt.h<br>
@@ -87,176 +87,6 @@ class LLVM_NODISCARD APInt {<br>
<br>
   static constexpr WordType WORDTYPE_MAX = ~WordType(0);<br>
<br>
-private:<br>
-  /// This union is used to store the integer value. When the<br>
-  /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.<br>
-  union {<br>
-    uint64_t VAL;   ///< Used to store the <= 64 bits integer value.<br>
-    uint64_t *pVal; ///< Used to store the >64 bits integer value.<br>
-  } U;<br>
-<br>
-  unsigned BitWidth; ///< The number of bits in this APInt.<br>
-<br>
-  friend struct DenseMapInfo<APInt>;<br>
-<br>
-  friend class APSInt;<br>
-<br>
-  /// Fast internal constructor<br>
-  ///<br>
-  /// This constructor is used only internally for speed of construction of<br>
-  /// temporaries. It is unsafe for general use so it is not public.<br>
-  APInt(uint64_t *val, unsigned bits) : BitWidth(bits) {<br>
-    U.pVal = val;<br>
-  }<br>
-<br>
-  /// Determine which word a bit is in.<br>
-  ///<br>
-  /// \returns the word position for the specified bit position.<br>
-  static unsigned whichWord(unsigned bitPosition) {<br>
-    return bitPosition / APINT_BITS_PER_WORD;<br>
-  }<br>
-<br>
-  /// Determine which bit in a word a bit is in.<br>
-  ///<br>
-  /// \returns the bit position in a word for the specified bit position<br>
-  /// in the APInt.<br>
-  static unsigned whichBit(unsigned bitPosition) {<br>
-    return bitPosition % APINT_BITS_PER_WORD;<br>
-  }<br>
-<br>
-  /// Get a single bit mask.<br>
-  ///<br>
-  /// \returns a uint64_t with only bit at "whichBit(bitPosition)" set<br>
-  /// This method generates and returns a uint64_t (word) mask for a single<br>
-  /// bit at a specific bit position. This is used to mask the bit in the<br>
-  /// corresponding word.<br>
-  static uint64_t maskBit(unsigned bitPosition) {<br>
-    return 1ULL << whichBit(bitPosition);<br>
-  }<br>
-<br>
-  /// Clear unused high order bits<br>
-  ///<br>
-  /// This method is used internally to clear the top "N" bits in the high order<br>
-  /// word that are not used by the APInt. This is needed after the most<br>
-  /// significant word is assigned a value to ensure that those bits are<br>
-  /// zero'd out.<br>
-  APInt &clearUnusedBits() {<br>
-    // Compute how many bits are used in the final word<br>
-    unsigned WordBits = ((BitWidth-1) % APINT_BITS_PER_WORD) + 1;<br>
-<br>
-    // Mask out the high bits.<br>
-    uint64_t mask = WORDTYPE_MAX >> (APINT_BITS_PER_WORD - WordBits);<br>
-    if (isSingleWord())<br>
-      U.VAL &= mask;<br>
-    else<br>
-      U.pVal[getNumWords() - 1] &= mask;<br>
-    return *this;<br>
-  }<br>
-<br>
-  /// Get the word corresponding to a bit position<br>
-  /// \returns the corresponding word for the specified bit position.<br>
-  uint64_t getWord(unsigned bitPosition) const {<br>
-    return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];<br>
-  }<br>
-<br>
-  /// Utility method to change the bit width of this APInt to new bit width,<br>
-  /// allocating and/or deallocating as necessary. There is no guarantee on the<br>
-  /// value of any bits upon return. Caller should populate the bits after.<br>
-  void reallocate(unsigned NewBitWidth);<br>
-<br>
-  /// Convert a char array into an APInt<br>
-  ///<br>
-  /// \param radix 2, 8, 10, 16, or 36<br>
-  /// Converts a string into a number.  The string must be non-empty<br>
-  /// and well-formed as a number of the given base. The bit-width<br>
-  /// must be sufficient to hold the result.<br>
-  ///<br>
-  /// This is used by the constructors that take string arguments.<br>
-  ///<br>
-  /// StringRef::getAsInteger is superficially similar but (1) does<br>
-  /// not assume that the string is well-formed and (2) grows the<br>
-  /// result to hold the input.<br>
-  void fromString(unsigned numBits, StringRef str, uint8_t radix);<br>
-<br>
-  /// An internal division function for dividing APInts.<br>
-  ///<br>
-  /// This is used by the toString method to divide by the radix. It simply<br>
-  /// provides a more convenient form of divide for internal use since KnuthDiv<br>
-  /// has specific constraints on its inputs. If those constraints are not met<br>
-  /// then it provides a simpler form of divide.<br>
-  static void divide(const WordType *LHS, unsigned lhsWords,<br>
-                     const WordType *RHS, unsigned rhsWords, WordType *Quotient,<br>
-                     WordType *Remainder);<br>
-<br>
-  /// out-of-line slow case for inline constructor<br>
-  void initSlowCase(uint64_t val, bool isSigned);<br>
-<br>
-  /// shared code between two array constructors<br>
-  void initFromArray(ArrayRef<uint64_t> array);<br>
-<br>
-  /// out-of-line slow case for inline copy constructor<br>
-  void initSlowCase(const APInt &that);<br>
-<br>
-  /// out-of-line slow case for shl<br>
-  void shlSlowCase(unsigned ShiftAmt);<br>
-<br>
-  /// out-of-line slow case for lshr.<br>
-  void lshrSlowCase(unsigned ShiftAmt);<br>
-<br>
-  /// out-of-line slow case for ashr.<br>
-  void ashrSlowCase(unsigned ShiftAmt);<br>
-<br>
-  /// out-of-line slow case for operator=<br>
-  void AssignSlowCase(const APInt &RHS);<br>
-<br>
-  /// out-of-line slow case for operator==<br>
-  bool EqualSlowCase(const APInt &RHS) const LLVM_READONLY;<br>
-<br>
-  /// out-of-line slow case for countLeadingZeros<br>
-  unsigned countLeadingZerosSlowCase() const LLVM_READONLY;<br>
-<br>
-  /// out-of-line slow case for countLeadingOnes.<br>
-  unsigned countLeadingOnesSlowCase() const LLVM_READONLY;<br>
-<br>
-  /// out-of-line slow case for countTrailingZeros.<br>
-  unsigned countTrailingZerosSlowCase() const LLVM_READONLY;<br>
-<br>
-  /// out-of-line slow case for countTrailingOnes<br>
-  unsigned countTrailingOnesSlowCase() const LLVM_READONLY;<br>
-<br>
-  /// out-of-line slow case for countPopulation<br>
-  unsigned countPopulationSlowCase() const LLVM_READONLY;<br>
-<br>
-  /// out-of-line slow case for intersects.<br>
-  bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY;<br>
-<br>
-  /// out-of-line slow case for isSubsetOf.<br>
-  bool isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY;<br>
-<br>
-  /// out-of-line slow case for setBits.<br>
-  void setBitsSlowCase(unsigned loBit, unsigned hiBit);<br>
-<br>
-  /// out-of-line slow case for flipAllBits.<br>
-  void flipAllBitsSlowCase();<br>
-<br>
-  /// out-of-line slow case for operator&=.<br>
-  void AndAssignSlowCase(const APInt& RHS);<br>
-<br>
-  /// out-of-line slow case for operator|=.<br>
-  void OrAssignSlowCase(const APInt& RHS);<br>
-<br>
-  /// out-of-line slow case for operator^=.<br>
-  void XorAssignSlowCase(const APInt& RHS);<br>
-<br>
-  /// Unsigned comparison. Returns -1, 0, or 1 if this APInt is less than, equal<br>
-  /// to, or greater than RHS.<br>
-  int compare(const APInt &RHS) const LLVM_READONLY;<br>
-<br>
-  /// Signed comparison. Returns -1, 0, or 1 if this APInt is less than, equal<br>
-  /// to, or greater than RHS.<br>
-  int compareSigned(const APInt &RHS) const LLVM_READONLY;<br>
-<br>
-public:<br>
   /// \name Constructors<br>
   /// @{<br>
<br>
@@ -312,7 +142,13 @@ class LLVM_NODISCARD APInt {<br>
   /// \param radix the radix to use for the conversion<br>
   APInt(unsigned numBits, StringRef str, uint8_t radix);<br>
<br>
-  /// Simply makes *this a copy of that.<br>
+  /// Default constructor that creates an uninteresting APInt<br>
+  /// representing a 1-bit zero value.<br>
+  ///<br>
+  /// This is useful for object deserialization (pair this with the static<br>
+  ///  method Read).<br>
+  explicit APInt() : BitWidth(1) { U.VAL = 0; }<br>
+<br>
   /// Copy Constructor.<br>
   APInt(const APInt &that) : BitWidth(that.BitWidth) {<br>
     if (isSingleWord())<br>
@@ -333,19 +169,135 @@ class LLVM_NODISCARD APInt {<br>
       delete[] U.pVal;<br>
   }<br>
<br>
-  /// Default constructor that creates an uninteresting APInt<br>
-  /// representing a 1-bit zero value.<br>
+  /// @}<br>
+  /// \name Value Generators<br>
+  /// @{<br>
+<br>
+  /// Get the '0' value.<br>
   ///<br>
-  /// This is useful for object deserialization (pair this with the static<br>
-  ///  method Read).<br>
-  explicit APInt() : BitWidth(1) { U.VAL = 0; }<br>
+  /// \returns the '0' value for an APInt of the specified bit-width.<br>
+  static APInt getNullValue(unsigned numBits) { return APInt(numBits, 0); }<br>
<br>
-  /// Returns whether this instance allocated memory.<br>
-  bool needsCleanup() const { return !isSingleWord(); }<br>
+  /// Gets maximum unsigned value of APInt for specific bit width.<br>
+  static APInt getMaxValue(unsigned numBits) {<br>
+    return getAllOnesValue(numBits);<br>
+  }<br>
<br>
-  /// Used to insert APInt objects, or objects that contain APInt objects, into<br>
-  ///  FoldingSets.<br>
-  void Profile(FoldingSetNodeID &id) const;<br>
+  /// Gets maximum signed value of APInt for a specific bit width.<br>
+  static APInt getSignedMaxValue(unsigned numBits) {<br>
+    APInt API = getAllOnesValue(numBits);<br>
+    API.clearBit(numBits - 1);<br>
+    return API;<br>
+  }<br>
+<br>
+  /// Gets minimum unsigned value of APInt for a specific bit width.<br>
+  static APInt getMinValue(unsigned numBits) { return APInt(numBits, 0); }<br>
+<br>
+  /// Gets minimum signed value of APInt for a specific bit width.<br>
+  static APInt getSignedMinValue(unsigned numBits) {<br>
+    APInt API(numBits, 0);<br>
+    API.setBit(numBits - 1);<br>
+    return API;<br>
+  }<br>
+<br>
+  /// Get the SignMask for a specific bit width.<br>
+  ///<br>
+  /// This is just a wrapper function of getSignedMinValue(), and it helps code<br>
+  /// readability when we want to get a SignMask.<br>
+  static APInt getSignMask(unsigned BitWidth) {<br>
+    return getSignedMinValue(BitWidth);<br>
+  }<br>
+<br>
+  /// Get the all-ones value.<br>
+  ///<br>
+  /// \returns the all-ones value for an APInt of the specified bit-width.<br>
+  static APInt getAllOnesValue(unsigned numBits) {<br>
+    return APInt(numBits, WORDTYPE_MAX, true);<br>
+  }<br>
+<br>
+  /// Return an APInt with exactly one bit set in the result.<br>
+  static APInt getOneBitSet(unsigned numBits, unsigned BitNo) {<br>
+    APInt Res(numBits, 0);<br>
+    Res.setBit(BitNo);<br>
+    return Res;<br>
+  }<br>
+<br>
+  /// Get a value with a block of bits set.<br>
+  ///<br>
+  /// Constructs an APInt value that has a contiguous range of bits set. The<br>
+  /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other<br>
+  /// bits will be zero. For example, with parameters(32, 0, 16) you would get<br>
+  /// 0x0000FFFF. Please call getBitsSetWithWrap if \p loBit may be greater than<br>
+  /// \p hiBit.<br>
+  ///<br>
+  /// \param numBits the intended bit width of the result<br>
+  /// \param loBit the index of the lowest bit set.<br>
+  /// \param hiBit the index of the highest bit set.<br>
+  ///<br>
+  /// \returns An APInt value with the requested bits set.<br>
+  static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit) {<br>
+    assert(loBit <= hiBit && "loBit greater than hiBit");<br>
+    APInt Res(numBits, 0);<br>
+    Res.setBits(loBit, hiBit);<br>
+    return Res;<br>
+  }<br>
+<br>
+  /// Wrap version of getBitsSet.<br>
+  /// If \p hiBit is bigger than \p loBit, this is same with getBitsSet.<br>
+  /// If \p hiBit is not bigger than \p loBit, the set bits "wrap". For example,<br>
+  /// with parameters (32, 28, 4), you would get 0xF000000F.<br>
+  /// If \p hiBit is equal to \p loBit, you would get a result with all bits<br>
+  /// set.<br>
+  static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit,<br>
+                                  unsigned hiBit) {<br>
+    APInt Res(numBits, 0);<br>
+    Res.setBitsWithWrap(loBit, hiBit);<br>
+    return Res;<br>
+  }<br>
+<br>
+  /// Get a value with upper bits starting at loBit set.<br>
+  ///<br>
+  /// Constructs an APInt value that has a contiguous range of bits set. The<br>
+  /// bits from loBit (inclusive) to numBits (exclusive) will be set. All other<br>
+  /// bits will be zero. For example, with parameters(32, 12) you would get<br>
+  /// 0xFFFFF000.<br>
+  ///<br>
+  /// \param numBits the intended bit width of the result<br>
+  /// \param loBit the index of the lowest bit to set.<br>
+  ///<br>
+  /// \returns An APInt value with the requested bits set.<br>
+  static APInt getBitsSetFrom(unsigned numBits, unsigned loBit) {<br>
+    APInt Res(numBits, 0);<br>
+    Res.setBitsFrom(loBit);<br>
+    return Res;<br>
+  }<br>
+<br>
+  /// Get a value with high bits set<br>
+  ///<br>
+  /// Constructs an APInt value that has the top hiBitsSet bits set.<br>
+  ///<br>
+  /// \param numBits the bitwidth of the result<br>
+  /// \param hiBitsSet the number of high-order bits set in the result.<br>
+  static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) {<br>
+    APInt Res(numBits, 0);<br>
+    Res.setHighBits(hiBitsSet);<br>
+    return Res;<br>
+  }<br>
+<br>
+  /// Get a value with low bits set<br>
+  ///<br>
+  /// Constructs an APInt value that has the bottom loBitsSet bits set.<br>
+  ///<br>
+  /// \param numBits the bitwidth of the result<br>
+  /// \param loBitsSet the number of low-order bits set in the result.<br>
+  static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) {<br>
+    APInt Res(numBits, 0);<br>
+    Res.setLowBits(loBitsSet);<br>
+    return Res;<br>
+  }<br>
+<br>
+  /// Return a value containing V broadcasted over NewLen bits.<br>
+  static APInt getSplat(unsigned NewLen, const APInt &V);<br>
<br>
   /// @}<br>
   /// \name Value Tests<br>
@@ -373,7 +325,7 @@ class LLVM_NODISCARD APInt {<br>
   /// This tests the high bit of this APInt to determine if it is set.<br>
   ///<br>
   /// \returns true if this APInt has its sign bit set, false otherwise.<br>
-  bool isSignBitSet() const { return (*this)[BitWidth-1]; }<br>
+  bool isSignBitSet() const { return (*this)[BitWidth - 1]; }<br>
<br>
   /// Determine if sign bit of this APInt is clear.<br>
   ///<br>
@@ -453,13 +405,13 @@ class LLVM_NODISCARD APInt {<br>
<br>
   /// Check if this APInt has an N-bits unsigned integer value.<br>
   bool isIntN(unsigned N) const {<br>
-    assert(N && "N == 0 ???");<br>
+    assert(N && "0 bit APInt not supported");<br>
     return getActiveBits() <= N;<br>
   }<br>
<br>
   /// Check if this APInt has an N-bits signed integer value.<br>
   bool isSignedIntN(unsigned N) const {<br>
-    assert(N && "N == 0 ???");<br>
+    assert(N && "0 bit APInt not supported");<br>
     return getMinSignedBits() <= N;<br>
   }<br>
<br>
@@ -498,180 +450,50 @@ class LLVM_NODISCARD APInt {<br>
   /// \returns true if this APInt value is a sequence of \param numBits ones<br>
   /// starting at the least significant bit with the remainder zero.<br>
   bool isMask(unsigned numBits) const {<br>
-    assert(numBits != 0 && "numBits must be non-zero");<br>
-    assert(numBits <= BitWidth && "numBits out of range");<br>
-    if (isSingleWord())<br>
-      return U.VAL == (WORDTYPE_MAX >> (APINT_BITS_PER_WORD - numBits));<br>
-    unsigned Ones = countTrailingOnesSlowCase();<br>
-    return (numBits == Ones) &&<br>
-           ((Ones + countLeadingZerosSlowCase()) == BitWidth);<br>
-  }<br>
-<br>
-  /// \returns true if this APInt is a non-empty sequence of ones starting at<br>
-  /// the least significant bit with the remainder zero.<br>
-  /// Ex. isMask(0x0000FFFFU) == true.<br>
-  bool isMask() const {<br>
-    if (isSingleWord())<br>
-      return isMask_64(U.VAL);<br>
-    unsigned Ones = countTrailingOnesSlowCase();<br>
-    return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) == BitWidth);<br>
-  }<br>
-<br>
-  /// Return true if this APInt value contains a sequence of ones with<br>
-  /// the remainder zero.<br>
-  bool isShiftedMask() const {<br>
-    if (isSingleWord())<br>
-      return isShiftedMask_64(U.VAL);<br>
-    unsigned Ones = countPopulationSlowCase();<br>
-    unsigned LeadZ = countLeadingZerosSlowCase();<br>
-    return (Ones + LeadZ + countTrailingZeros()) == BitWidth;<br>
-  }<br>
-<br>
-  /// @}<br>
-  /// \name Value Generators<br>
-  /// @{<br>
-<br>
-  /// Gets maximum unsigned value of APInt for specific bit width.<br>
-  static APInt getMaxValue(unsigned numBits) {<br>
-    return getAllOnesValue(numBits);<br>
-  }<br>
-<br>
-  /// Gets maximum signed value of APInt for a specific bit width.<br>
-  static APInt getSignedMaxValue(unsigned numBits) {<br>
-    APInt API = getAllOnesValue(numBits);<br>
-    API.clearBit(numBits - 1);<br>
-    return API;<br>
-  }<br>
-<br>
-  /// Gets minimum unsigned value of APInt for a specific bit width.<br>
-  static APInt getMinValue(unsigned numBits) { return APInt(numBits, 0); }<br>
-<br>
-  /// Gets minimum signed value of APInt for a specific bit width.<br>
-  static APInt getSignedMinValue(unsigned numBits) {<br>
-    APInt API(numBits, 0);<br>
-    API.setBit(numBits - 1);<br>
-    return API;<br>
-  }<br>
-<br>
-  /// Get the SignMask for a specific bit width.<br>
-  ///<br>
-  /// This is just a wrapper function of getSignedMinValue(), and it helps code<br>
-  /// readability when we want to get a SignMask.<br>
-  static APInt getSignMask(unsigned BitWidth) {<br>
-    return getSignedMinValue(BitWidth);<br>
-  }<br>
-<br>
-  /// Get the all-ones value.<br>
-  ///<br>
-  /// \returns the all-ones value for an APInt of the specified bit-width.<br>
-  static APInt getAllOnesValue(unsigned numBits) {<br>
-    return APInt(numBits, WORDTYPE_MAX, true);<br>
-  }<br>
-<br>
-  /// Get the '0' value.<br>
-  ///<br>
-  /// \returns the '0' value for an APInt of the specified bit-width.<br>
-  static APInt getNullValue(unsigned numBits) { return APInt(numBits, 0); }<br>
-<br>
-  /// Compute an APInt containing numBits highbits from this APInt.<br>
-  ///<br>
-  /// Get an APInt with the same BitWidth as this APInt, just zero mask<br>
-  /// the low bits and right shift to the least significant bit.<br>
-  ///<br>
-  /// \returns the high "numBits" bits of this APInt.<br>
-  APInt getHiBits(unsigned numBits) const;<br>
-<br>
-  /// Compute an APInt containing numBits lowbits from this APInt.<br>
-  ///<br>
-  /// Get an APInt with the same BitWidth as this APInt, just zero mask<br>
-  /// the high bits.<br>
-  ///<br>
-  /// \returns the low "numBits" bits of this APInt.<br>
-  APInt getLoBits(unsigned numBits) const;<br>
-<br>
-  /// Return an APInt with exactly one bit set in the result.<br>
-  static APInt getOneBitSet(unsigned numBits, unsigned BitNo) {<br>
-    APInt Res(numBits, 0);<br>
-    Res.setBit(BitNo);<br>
-    return Res;<br>
-  }<br>
-<br>
-  /// Get a value with a block of bits set.<br>
-  ///<br>
-  /// Constructs an APInt value that has a contiguous range of bits set. The<br>
-  /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other<br>
-  /// bits will be zero. For example, with parameters(32, 0, 16) you would get<br>
-  /// 0x0000FFFF. Please call getBitsSetWithWrap if \p loBit may be greater than<br>
-  /// \p hiBit.<br>
-  ///<br>
-  /// \param numBits the intended bit width of the result<br>
-  /// \param loBit the index of the lowest bit set.<br>
-  /// \param hiBit the index of the highest bit set.<br>
-  ///<br>
-  /// \returns An APInt value with the requested bits set.<br>
-  static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit) {<br>
-    assert(loBit <= hiBit && "loBit greater than hiBit");<br>
-    APInt Res(numBits, 0);<br>
-    Res.setBits(loBit, hiBit);<br>
-    return Res;<br>
+    assert(numBits != 0 && "numBits must be non-zero");<br>
+    assert(numBits <= BitWidth && "numBits out of range");<br>
+    if (isSingleWord())<br>
+      return U.VAL == (WORDTYPE_MAX >> (APINT_BITS_PER_WORD - numBits));<br>
+    unsigned Ones = countTrailingOnesSlowCase();<br>
+    return (numBits == Ones) &&<br>
+           ((Ones + countLeadingZerosSlowCase()) == BitWidth);<br>
   }<br>
<br>
-  /// Wrap version of getBitsSet.<br>
-  /// If \p hiBit is bigger than \p loBit, this is same with getBitsSet.<br>
-  /// If \p hiBit is not bigger than \p loBit, the set bits "wrap". For example,<br>
-  /// with parameters (32, 28, 4), you would get 0xF000000F.<br>
-  /// If \p hiBit is equal to \p loBit, you would get a result with all bits<br>
-  /// set.<br>
-  static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit,<br>
-                                  unsigned hiBit) {<br>
-    APInt Res(numBits, 0);<br>
-    Res.setBitsWithWrap(loBit, hiBit);<br>
-    return Res;<br>
+  /// \returns true if this APInt is a non-empty sequence of ones starting at<br>
+  /// the least significant bit with the remainder zero.<br>
+  /// Ex. isMask(0x0000FFFFU) == true.<br>
+  bool isMask() const {<br>
+    if (isSingleWord())<br>
+      return isMask_64(U.VAL);<br>
+    unsigned Ones = countTrailingOnesSlowCase();<br>
+    return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) == BitWidth);<br>
   }<br>
<br>
-  /// Get a value with upper bits starting at loBit set.<br>
-  ///<br>
-  /// Constructs an APInt value that has a contiguous range of bits set. The<br>
-  /// bits from loBit (inclusive) to numBits (exclusive) will be set. All other<br>
-  /// bits will be zero. For example, with parameters(32, 12) you would get<br>
-  /// 0xFFFFF000.<br>
-  ///<br>
-  /// \param numBits the intended bit width of the result<br>
-  /// \param loBit the index of the lowest bit to set.<br>
-  ///<br>
-  /// \returns An APInt value with the requested bits set.<br>
-  static APInt getBitsSetFrom(unsigned numBits, unsigned loBit) {<br>
-    APInt Res(numBits, 0);<br>
-    Res.setBitsFrom(loBit);<br>
-    return Res;<br>
+  /// Return true if this APInt value contains a sequence of ones with<br>
+  /// the remainder zero.<br>
+  bool isShiftedMask() const {<br>
+    if (isSingleWord())<br>
+      return isShiftedMask_64(U.VAL);<br>
+    unsigned Ones = countPopulationSlowCase();<br>
+    unsigned LeadZ = countLeadingZerosSlowCase();<br>
+    return (Ones + LeadZ + countTrailingZeros()) == BitWidth;<br>
   }<br>
<br>
-  /// Get a value with high bits set<br>
+  /// Compute an APInt containing numBits highbits from this APInt.<br>
   ///<br>
-  /// Constructs an APInt value that has the top hiBitsSet bits set.<br>
+  /// Get an APInt with the same BitWidth as this APInt, just zero mask<br>
+  /// the low bits and right shift to the least significant bit.<br>
   ///<br>
-  /// \param numBits the bitwidth of the result<br>
-  /// \param hiBitsSet the number of high-order bits set in the result.<br>
-  static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) {<br>
-    APInt Res(numBits, 0);<br>
-    Res.setHighBits(hiBitsSet);<br>
-    return Res;<br>
-  }<br>
+  /// \returns the high "numBits" bits of this APInt.<br>
+  APInt getHiBits(unsigned numBits) const;<br>
<br>
-  /// Get a value with low bits set<br>
+  /// Compute an APInt containing numBits lowbits from this APInt.<br>
   ///<br>
-  /// Constructs an APInt value that has the bottom loBitsSet bits set.<br>
+  /// Get an APInt with the same BitWidth as this APInt, just zero mask<br>
+  /// the high bits.<br>
   ///<br>
-  /// \param numBits the bitwidth of the result<br>
-  /// \param loBitsSet the number of low-order bits set in the result.<br>
-  static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) {<br>
-    APInt Res(numBits, 0);<br>
-    Res.setLowBits(loBitsSet);<br>
-    return Res;<br>
-  }<br>
-<br>
-  /// Return a value containing V broadcasted over NewLen bits.<br>
-  static APInt getSplat(unsigned NewLen, const APInt &V);<br>
+  /// \returns the low "numBits" bits of this APInt.<br>
+  APInt getLoBits(unsigned numBits) const;<br>
<br>
   /// Determine if two APInts have the same value, after zero-extending<br>
   /// one of them (if needed!) to ensure that the bit-widths match.<br>
@@ -827,7 +649,7 @@ class LLVM_NODISCARD APInt {<br>
       return *this;<br>
     }<br>
     U.pVal[0] &= RHS;<br>
-    memset(U.pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);<br>
+    memset(U.pVal + 1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);<br>
     return *this;<br>
   }<br>
<br>
@@ -1449,9 +1271,7 @@ class LLVM_NODISCARD APInt {<br>
   }<br>
<br>
   /// Set the sign bit to 1.<br>
-  void setSignBit() {<br>
-    setBit(BitWidth - 1);<br>
-  }<br>
+  void setSignBit() { setBit(BitWidth - 1); }<br>
<br>
   /// Set a given bit to a given value.<br>
   void setBitVal(unsigned BitPosition, bool BitValue) {<br>
@@ -1497,14 +1317,10 @@ class LLVM_NODISCARD APInt {<br>
   }<br>
<br>
   /// Set the top bits starting from loBit.<br>
-  void setBitsFrom(unsigned loBit) {<br>
-    return setBits(loBit, BitWidth);<br>
-  }<br>
+  void setBitsFrom(unsigned loBit) { return setBits(loBit, BitWidth); }<br>
<br>
   /// Set the bottom loBits bits.<br>
-  void setLowBits(unsigned loBits) {<br>
-    return setBits(0, loBits);<br>
-  }<br>
+  void setLowBits(unsigned loBits) { return setBits(0, loBits); }<br>
<br>
   /// Set the top hiBits bits.<br>
   void setHighBits(unsigned hiBits) {<br>
@@ -1539,9 +1355,7 @@ class LLVM_NODISCARD APInt {<br>
   }<br>
<br>
   /// Set the sign bit to 0.<br>
-  void clearSignBit() {<br>
-    clearBit(BitWidth - 1);<br>
-  }<br>
+  void clearSignBit() { clearBit(BitWidth - 1); }<br>
<br>
   /// Toggle every bit to its opposite value.<br>
   void flipAllBits() {<br>
@@ -1774,9 +1588,7 @@ class LLVM_NODISCARD APInt {<br>
   /// The conversion does not do a translation from integer to double, it just<br>
   /// re-interprets the bits as a double. Note that it is valid to do this on<br>
   /// any bit width. Exactly 64 bits will be translated.<br>
-  double bitsToDouble() const {<br>
-    return BitsToDouble(getWord(0));<br>
-  }<br>
+  double bitsToDouble() const { return BitsToDouble(getWord(0)); }<br>
<br>
   /// Converts APInt bits to a float<br>
   ///<br>
@@ -1808,7 +1620,7 @@ class LLVM_NODISCARD APInt {<br>
   /// @{<br>
<br>
   /// \returns the floor log base 2 of this APInt.<br>
-  unsigned logBase2() const { return getActiveBits() -  1; }<br>
+  unsigned logBase2() const { return getActiveBits() - 1; }<br>
<br>
   /// \returns the ceil log base 2 of this APInt.<br>
   unsigned ceilLogBase2() const {<br>
@@ -1908,9 +1720,8 @@ class LLVM_NODISCARD APInt {<br>
   /// DST, of dstCOUNT parts, such that the bit srcLSB becomes the least<br>
   /// significant bit of DST.  All high bits above srcBITS in DST are<br>
   /// zero-filled.<br>
-  static void tcExtract(WordType *, unsigned dstCount,<br>
-                        const WordType *, unsigned srcBits,<br>
-                        unsigned srcLSB);<br>
+  static void tcExtract(WordType *, unsigned dstCount, const WordType *,<br>
+                        unsigned srcBits, unsigned srcLSB);<br>
<br>
   /// Set the given bit of a bignum.  Zero-based.<br>
   static void tcSetBit(WordType *, unsigned bit);<br>
@@ -1927,14 +1738,13 @@ class LLVM_NODISCARD APInt {<br>
   static void tcNegate(WordType *, unsigned);<br>
<br>
   /// DST += RHS + CARRY where CARRY is zero or one.  Returns the carry flag.<br>
-  static WordType tcAdd(WordType *, const WordType *,<br>
-                        WordType carry, unsigned);<br>
+  static WordType tcAdd(WordType *, const WordType *, WordType carry, unsigned);<br>
   /// DST += RHS.  Returns the carry flag.<br>
   static WordType tcAddPart(WordType *, WordType, unsigned);<br>
<br>
   /// DST -= RHS + CARRY where CARRY is zero or one. Returns the carry flag.<br>
-  static WordType tcSubtract(WordType *, const WordType *,<br>
-                             WordType carry, unsigned);<br>
+  static WordType tcSubtract(WordType *, const WordType *, WordType carry,<br>
+                             unsigned);<br>
   /// DST -= RHS.  Returns the carry flag.<br>
   static WordType tcSubtractPart(WordType *, WordType, unsigned);<br>
<br>
@@ -1950,8 +1760,7 @@ class LLVM_NODISCARD APInt {<br>
   /// otherwise overflow occurred and return one.<br>
   static int tcMultiplyPart(WordType *dst, const WordType *src,<br>
                             WordType multiplier, WordType carry,<br>
-                            unsigned srcParts, unsigned dstParts,<br>
-                            bool add);<br>
+                            unsigned srcParts, unsigned dstParts, bool add);<br>
<br>
   /// DST = LHS * RHS, where DST has the same width as the operands and is<br>
   /// filled with the least significant parts of the result.  Returns one if<br>
@@ -1962,8 +1771,8 @@ class LLVM_NODISCARD APInt {<br>
<br>
   /// DST = LHS * RHS, where DST has width the sum of the widths of the<br>
   /// operands. No overflow occurs. DST must be disjoint from both operands.<br>
-  static void tcFullMultiply(WordType *, const WordType *,<br>
-                             const WordType *, unsigned, unsigned);<br>
+  static void tcFullMultiply(WordType *, const WordType *, const WordType *,<br>
+                             unsigned, unsigned);<br>
<br>
   /// If RHS is zero LHS and REMAINDER are left unchanged, return one.<br>
   /// Otherwise set LHS to LHS / RHS with the fractional part discarded, set<br>
@@ -1974,9 +1783,8 @@ class LLVM_NODISCARD APInt {<br>
   /// SCRATCH is a bignum of the same size as the operands and result for use by<br>
   /// the routine; its contents need not be initialized and are destroyed.  LHS,<br>
   /// REMAINDER and SCRATCH must be distinct.<br>
-  static int tcDivide(WordType *lhs, const WordType *rhs,<br>
-                      WordType *remainder, WordType *scratch,<br>
-                      unsigned parts);<br>
+  static int tcDivide(WordType *lhs, const WordType *rhs, WordType *remainder,<br>
+                      WordType *scratch, unsigned parts);<br>
<br>
   /// Shift a bignum left Count bits. Shifted in bits are zero. There are no<br>
   /// restrictions on Count.<br>
@@ -2008,9 +1816,183 @@ class LLVM_NODISCARD APInt {<br>
   /// Set the least significant BITS and clear the rest.<br>
   static void tcSetLeastSignificantBits(WordType *, unsigned, unsigned bits);<br>
<br>
+  /// Used to insert APInt objects, or objects that contain APInt objects, into<br>
+  ///  FoldingSets.<br>
+  void Profile(FoldingSetNodeID &id) const;<br>
+<br>
   /// debug method<br>
   void dump() const;<br>
<br>
+private:<br>
+  /// This union is used to store the integer value. When the<br>
+  /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.<br>
+  union {<br>
+    uint64_t VAL;   ///< Used to store the <= 64 bits integer value.<br>
+    uint64_t *pVal; ///< Used to store the >64 bits integer value.<br>
+  } U;<br>
+<br>
+  unsigned BitWidth; ///< The number of bits in this APInt.<br>
+<br>
+  friend struct DenseMapInfo<APInt>;<br>
+<br>
+  friend class APSInt;<br>
+<br>
+  /// Fast internal constructor<br>
+  ///<br>
+  /// This constructor is used only internally for speed of construction of<br>
+  /// temporaries. It is unsafe for general use so it is not public.<br>
+  APInt(uint64_t *val, unsigned bits) : BitWidth(bits) { U.pVal = val; }<br>
+<br>
+  /// Determine which word a bit is in.<br>
+  ///<br>
+  /// \returns the word position for the specified bit position.<br>
+  static unsigned whichWord(unsigned bitPosition) {<br>
+    return bitPosition / APINT_BITS_PER_WORD;<br>
+  }<br>
+<br>
+  /// Determine which bit in a word a bit is in.<br>
+  ///<br>
+  /// \returns the bit position in a word for the specified bit position<br>
+  /// in the APInt.<br>
+  static unsigned whichBit(unsigned bitPosition) {<br>
+    return bitPosition % APINT_BITS_PER_WORD;<br>
+  }<br>
+<br>
+  /// Get a single bit mask.<br>
+  ///<br>
+  /// \returns a uint64_t with only bit at "whichBit(bitPosition)" set<br>
+  /// This method generates and returns a uint64_t (word) mask for a single<br>
+  /// bit at a specific bit position. This is used to mask the bit in the<br>
+  /// corresponding word.<br>
+  static uint64_t maskBit(unsigned bitPosition) {<br>
+    return 1ULL << whichBit(bitPosition);<br>
+  }<br>
+<br>
+  /// Clear unused high order bits<br>
+  ///<br>
+  /// This method is used internally to clear the top "N" bits in the high order<br>
+  /// word that are not used by the APInt. This is needed after the most<br>
+  /// significant word is assigned a value to ensure that those bits are<br>
+  /// zero'd out.<br>
+  APInt &clearUnusedBits() {<br>
+    // Compute how many bits are used in the final word<br>
+    unsigned WordBits = ((BitWidth - 1) % APINT_BITS_PER_WORD) + 1;<br>
+<br>
+    // Mask out the high bits.<br>
+    uint64_t mask = WORDTYPE_MAX >> (APINT_BITS_PER_WORD - WordBits);<br>
+    if (isSingleWord())<br>
+      U.VAL &= mask;<br>
+    else<br>
+      U.pVal[getNumWords() - 1] &= mask;<br>
+    return *this;<br>
+  }<br>
+<br>
+  /// Get the word corresponding to a bit position<br>
+  /// \returns the corresponding word for the specified bit position.<br>
+  uint64_t getWord(unsigned bitPosition) const {<br>
+    return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];<br>
+  }<br>
+<br>
+  /// Utility method to change the bit width of this APInt to new bit width,<br>
+  /// allocating and/or deallocating as necessary. There is no guarantee on the<br>
+  /// value of any bits upon return. Caller should populate the bits after.<br>
+  void reallocate(unsigned NewBitWidth);<br>
+<br>
+  /// Convert a char array into an APInt<br>
+  ///<br>
+  /// \param radix 2, 8, 10, 16, or 36<br>
+  /// Converts a string into a number.  The string must be non-empty<br>
+  /// and well-formed as a number of the given base. The bit-width<br>
+  /// must be sufficient to hold the result.<br>
+  ///<br>
+  /// This is used by the constructors that take string arguments.<br>
+  ///<br>
+  /// StringRef::getAsInteger is superficially similar but (1) does<br>
+  /// not assume that the string is well-formed and (2) grows the<br>
+  /// result to hold the input.<br>
+  void fromString(unsigned numBits, StringRef str, uint8_t radix);<br>
+<br>
+  /// An internal division function for dividing APInts.<br>
+  ///<br>
+  /// This is used by the toString method to divide by the radix. It simply<br>
+  /// provides a more convenient form of divide for internal use since KnuthDiv<br>
+  /// has specific constraints on its inputs. If those constraints are not met<br>
+  /// then it provides a simpler form of divide.<br>
+  static void divide(const WordType *LHS, unsigned lhsWords,<br>
+                     const WordType *RHS, unsigned rhsWords, WordType *Quotient,<br>
+                     WordType *Remainder);<br>
+<br>
+  /// out-of-line slow case for inline constructor<br>
+  void initSlowCase(uint64_t val, bool isSigned);<br>
+<br>
+  /// shared code between two array constructors<br>
+  void initFromArray(ArrayRef<uint64_t> array);<br>
+<br>
+  /// out-of-line slow case for inline copy constructor<br>
+  void initSlowCase(const APInt &that);<br>
+<br>
+  /// out-of-line slow case for shl<br>
+  void shlSlowCase(unsigned ShiftAmt);<br>
+<br>
+  /// out-of-line slow case for lshr.<br>
+  void lshrSlowCase(unsigned ShiftAmt);<br>
+<br>
+  /// out-of-line slow case for ashr.<br>
+  void ashrSlowCase(unsigned ShiftAmt);<br>
+<br>
+  /// out-of-line slow case for operator=<br>
+  void AssignSlowCase(const APInt &RHS);<br>
+<br>
+  /// out-of-line slow case for operator==<br>
+  bool EqualSlowCase(const APInt &RHS) const LLVM_READONLY;<br>
+<br>
+  /// out-of-line slow case for countLeadingZeros<br>
+  unsigned countLeadingZerosSlowCase() const LLVM_READONLY;<br>
+<br>
+  /// out-of-line slow case for countLeadingOnes.<br>
+  unsigned countLeadingOnesSlowCase() const LLVM_READONLY;<br>
+<br>
+  /// out-of-line slow case for countTrailingZeros.<br>
+  unsigned countTrailingZerosSlowCase() const LLVM_READONLY;<br>
+<br>
+  /// out-of-line slow case for countTrailingOnes<br>
+  unsigned countTrailingOnesSlowCase() const LLVM_READONLY;<br>
+<br>
+  /// out-of-line slow case for countPopulation<br>
+  unsigned countPopulationSlowCase() const LLVM_READONLY;<br>
+<br>
+  /// out-of-line slow case for intersects.<br>
+  bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY;<br>
+<br>
+  /// out-of-line slow case for isSubsetOf.<br>
+  bool isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY;<br>
+<br>
+  /// out-of-line slow case for setBits.<br>
+  void setBitsSlowCase(unsigned loBit, unsigned hiBit);<br>
+<br>
+  /// out-of-line slow case for flipAllBits.<br>
+  void flipAllBitsSlowCase();<br>
+<br>
+  /// out-of-line slow case for operator&=.<br>
+  void AndAssignSlowCase(const APInt &RHS);<br>
+<br>
+  /// out-of-line slow case for operator|=.<br>
+  void OrAssignSlowCase(const APInt &RHS);<br>
+<br>
+  /// out-of-line slow case for operator^=.<br>
+  void XorAssignSlowCase(const APInt &RHS);<br>
+<br>
+  /// Unsigned comparison. Returns -1, 0, or 1 if this APInt is less than, equal<br>
+  /// to, or greater than RHS.<br>
+  int compare(const APInt &RHS) const LLVM_READONLY;<br>
+<br>
+  /// Signed comparison. Returns -1, 0, or 1 if this APInt is less than, equal<br>
+  /// to, or greater than RHS.<br>
+  int compareSigned(const APInt &RHS) const LLVM_READONLY;<br>
+<br>
+  /// Returns whether this instance allocated memory.<br>
+  bool needsCleanup() const { return !isSingleWord(); }<br>
+<br>
   /// @}<br>
 };<br>
<br>
@@ -2161,7 +2143,6 @@ inline APInt operator*(uint64_t LHS, APInt b) {<br>
   return b;<br>
 }<br>
<br>
-<br>
 namespace APIntOps {<br>
<br>
 /// Determine the smaller of two APInts considered to be signed.<br>
@@ -2277,7 +2258,7 @@ Optional<APInt> SolveQuadraticEquationWrap(APInt A, APInt B, APInt C,<br>
 Optional<unsigned> GetMostSignificantDifferentBit(const APInt &A,<br>
                                                   const APInt &B);<br>
<br>
-} // End of APIntOps namespace<br>
+} // namespace APIntOps<br>
<br>
 // See friend declaration above. This additional declaration is required in<br>
 // order to compile LLVM with IBM xlC compiler.<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>
</div></blockquote></div><br></div></div></blockquote></div>