diff --git a/llvm/include/llvm/ADT/APFixedPoint.h b/llvm/include/llvm/ADT/APFixedPoint.h index 0a47cd50516d4..6ce49f25fb988 100644 --- a/llvm/include/llvm/ADT/APFixedPoint.h +++ b/llvm/include/llvm/ADT/APFixedPoint.h @@ -56,28 +56,33 @@ class FixedPointSemantics { /// Check if the Semantic follow the requirements of an older more limited /// version of this class - bool isValidLegacySema() const { + [[nodiscard]] bool isValidLegacySema() const { return LsbWeight <= 0 && static_cast(Width) >= -LsbWeight; } - unsigned getWidth() const { return Width; } - unsigned getScale() const { assert(isValidLegacySema()); return -LsbWeight; } - int getLsbWeight() const { return LsbWeight; } - int getMsbWeight() const { + [[nodiscard]] unsigned getWidth() const { return Width; } + [[nodiscard]] unsigned getScale() const { + assert(isValidLegacySema()); + return -LsbWeight; + } + [[nodiscard]] int getLsbWeight() const { return LsbWeight; } + [[nodiscard]] int getMsbWeight() const { return LsbWeight + Width - 1 /*Both lsb and msb are both part of width*/; } - bool isSigned() const { return IsSigned; } - bool isSaturated() const { return IsSaturated; } - bool hasUnsignedPadding() const { return HasUnsignedPadding; } + [[nodiscard]] bool isSigned() const { return IsSigned; } + [[nodiscard]] bool isSaturated() const { return IsSaturated; } + [[nodiscard]] bool hasUnsignedPadding() const { return HasUnsignedPadding; } void setSaturated(bool Saturated) { IsSaturated = Saturated; } /// return true if the first bit doesn't have a strictly positive weight - bool hasSignOrPaddingBit() const { return IsSigned || HasUnsignedPadding; } + [[nodiscard]] bool hasSignOrPaddingBit() const { + return IsSigned || HasUnsignedPadding; + } /// Return the number of integral bits represented by these semantics. These /// are separate from the fractional bits and do not include the sign or /// padding bit. - unsigned getIntegralBits() const { + [[nodiscard]] unsigned getIntegralBits() const { return std::max(getMsbWeight() + 1 - hasSignOrPaddingBit(), 0); } @@ -85,7 +90,7 @@ class FixedPointSemantics { /// precision semantic that can precisely represent the precision and ranges /// of both input values. This does not compute the resulting semantics for a /// given binary operation. - LLVM_ABI FixedPointSemantics + [[nodiscard]] LLVM_ABI FixedPointSemantics getCommonSemantics(const FixedPointSemantics &Other) const; /// Print semantics for debug purposes @@ -98,7 +103,8 @@ class FixedPointSemantics { /// minimum integer representation of 127 and -128, respectively. If both of /// these values can be represented (possibly inexactly) in the floating /// point semantic without overflowing, this returns true. - LLVM_ABI bool fitsInFloatSemantics(const fltSemantics &FloatSema) const; + [[nodiscard]] LLVM_ABI bool + fitsInFloatSemantics(const fltSemantics &FloatSema) const; /// Return the FixedPointSemantics for an integer type. static FixedPointSemantics GetIntegerSemantics(unsigned Width, @@ -119,7 +125,7 @@ class FixedPointSemantics { /// The result is dependent on the host endianness and not stable across LLVM /// versions. See getFromOpaqueInt() to convert it back to a /// FixedPointSemantics object. - LLVM_ABI uint32_t toOpaqueInt() const; + [[nodiscard]] LLVM_ABI uint32_t toOpaqueInt() const; /// Create a FixedPointSemantics object from an integer created via /// toOpaqueInt(). LLVM_ABI static FixedPointSemantics getFromOpaqueInt(uint32_t); @@ -177,16 +183,18 @@ class APFixedPoint { APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {} APSInt getValue() const { return APSInt(Val, !Sema.isSigned()); } - inline unsigned getWidth() const { return Sema.getWidth(); } - inline unsigned getScale() const { return Sema.getScale(); } - int getLsbWeight() const { return Sema.getLsbWeight(); } - int getMsbWeight() const { return Sema.getMsbWeight(); } - inline bool isSaturated() const { return Sema.isSaturated(); } - inline bool isSigned() const { return Sema.isSigned(); } - inline bool hasPadding() const { return Sema.hasUnsignedPadding(); } - FixedPointSemantics getSemantics() const { return Sema; } + [[nodiscard]] inline unsigned getWidth() const { return Sema.getWidth(); } + [[nodiscard]] inline unsigned getScale() const { return Sema.getScale(); } + [[nodiscard]] int getLsbWeight() const { return Sema.getLsbWeight(); } + [[nodiscard]] int getMsbWeight() const { return Sema.getMsbWeight(); } + [[nodiscard]] inline bool isSaturated() const { return Sema.isSaturated(); } + [[nodiscard]] inline bool isSigned() const { return Sema.isSigned(); } + [[nodiscard]] inline bool hasPadding() const { + return Sema.hasUnsignedPadding(); + } + [[nodiscard]] FixedPointSemantics getSemantics() const { return Sema; } - bool getBoolValue() const { return Val.getBoolValue(); } + [[nodiscard]] bool getBoolValue() const { return Val.getBoolValue(); } // Convert this number to match the semantics provided. If the overflow // parameter is provided, set this value to true or false to indicate if this @@ -244,10 +252,11 @@ class APFixedPoint { /// Convert this fixed point number to a floating point value with the /// provided semantics. - LLVM_ABI APFloat convertToFloat(const fltSemantics &FloatSema) const; + [[nodiscard]] LLVM_ABI APFloat + convertToFloat(const fltSemantics &FloatSema) const; LLVM_ABI void toString(SmallVectorImpl &Str) const; - std::string toString() const { + [[nodiscard]] std::string toString() const { SmallString<40> S; toString(S); return std::string(S); @@ -260,7 +269,7 @@ class APFixedPoint { #endif // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1. - LLVM_ABI int compare(const APFixedPoint &Other) const; + [[nodiscard]] LLVM_ABI int compare(const APFixedPoint &Other) const; bool operator==(const APFixedPoint &Other) const { return compare(Other) == 0; } diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h index 6bc62845fddf4..79336fd48852f 100644 --- a/llvm/include/llvm/ADT/APFloat.h +++ b/llvm/include/llvm/ADT/APFloat.h @@ -420,7 +420,7 @@ class IEEEFloat final { /// @} /// Returns whether this instance allocated memory. - bool needsCleanup() const { return partCount() > 1; } + [[nodiscard]] bool needsCleanup() const { return partCount() > 1; } /// \name Convenience "constructors" /// @{ @@ -462,11 +462,11 @@ class IEEEFloat final { LLVM_ABI opStatus convertFromAPInt(const APInt &, bool, roundingMode); LLVM_ABI Expected convertFromString(StringRef, roundingMode); LLVM_ABI APInt bitcastToAPInt() const; - LLVM_ABI double convertToDouble() const; + [[nodiscard]] LLVM_ABI double convertToDouble() const; #ifdef HAS_IEE754_FLOAT128 - LLVM_ABI float128 convertToQuad() const; + [[nodiscard]] LLVM_ABI float128 convertToQuad() const; #endif - LLVM_ABI float convertToFloat() const; + [[nodiscard]] LLVM_ABI float convertToFloat() const; /// @} @@ -477,10 +477,10 @@ class IEEEFloat final { /// IEEE comparison with another floating point number (NaNs compare /// unordered, 0==-0). - LLVM_ABI cmpResult compare(const IEEEFloat &) const; + [[nodiscard]] LLVM_ABI cmpResult compare(const IEEEFloat &) const; /// Bitwise comparison for equality (QNaNs compare equal, 0!=-0). - LLVM_ABI bool bitwiseIsEqual(const IEEEFloat &) const; + [[nodiscard]] LLVM_ABI bool bitwiseIsEqual(const IEEEFloat &) const; /// Write out a hexadecimal representation of the floating point value to DST, /// which must be of sufficient size, in the C99 form [-]0xh.hhhhp[+-]d. @@ -495,62 +495,66 @@ class IEEEFloat final { /// negative. /// /// This applies to zeros and NaNs as well. - bool isNegative() const { return sign; } + [[nodiscard]] bool isNegative() const { return sign; } /// IEEE-754R isNormal: Returns true if and only if the current value is normal. /// /// This implies that the current value of the float is not zero, subnormal, /// infinite, or NaN following the definition of normality from IEEE-754R. - bool isNormal() const { return !isDenormal() && isFiniteNonZero(); } + [[nodiscard]] bool isNormal() const { + return !isDenormal() && isFiniteNonZero(); + } /// Returns true if and only if the current value is zero, subnormal, or /// normal. /// /// This means that the value is not infinite or NaN. - bool isFinite() const { return !isNaN() && !isInfinity(); } + [[nodiscard]] bool isFinite() const { return !isNaN() && !isInfinity(); } /// Returns true if and only if the float is plus or minus zero. - bool isZero() const { return category == fltCategory::fcZero; } + [[nodiscard]] bool isZero() const { return category == fltCategory::fcZero; } /// IEEE-754R isSubnormal(): Returns true if and only if the float is a /// denormal. - LLVM_ABI bool isDenormal() const; + [[nodiscard]] LLVM_ABI bool isDenormal() const; /// IEEE-754R isInfinite(): Returns true if and only if the float is infinity. - bool isInfinity() const { return category == fcInfinity; } + [[nodiscard]] bool isInfinity() const { return category == fcInfinity; } /// Returns true if and only if the float is a quiet or signaling NaN. - bool isNaN() const { return category == fcNaN; } + [[nodiscard]] bool isNaN() const { return category == fcNaN; } /// Returns true if and only if the float is a signaling NaN. - LLVM_ABI bool isSignaling() const; + [[nodiscard]] LLVM_ABI bool isSignaling() const; /// @} /// \name Simple Queries /// @{ - fltCategory getCategory() const { return category; } - const fltSemantics &getSemantics() const { return *semantics; } - bool isNonZero() const { return category != fltCategory::fcZero; } - bool isFiniteNonZero() const { return isFinite() && !isZero(); } - bool isPosZero() const { return isZero() && !isNegative(); } - bool isNegZero() const { return isZero() && isNegative(); } + [[nodiscard]] fltCategory getCategory() const { return category; } + [[nodiscard]] const fltSemantics &getSemantics() const { return *semantics; } + [[nodiscard]] bool isNonZero() const { + return category != fltCategory::fcZero; + } + [[nodiscard]] bool isFiniteNonZero() const { return isFinite() && !isZero(); } + [[nodiscard]] bool isPosZero() const { return isZero() && !isNegative(); } + [[nodiscard]] bool isNegZero() const { return isZero() && isNegative(); } /// Returns true if and only if the number has the smallest possible non-zero /// magnitude in the current semantics. - LLVM_ABI bool isSmallest() const; + [[nodiscard]] LLVM_ABI bool isSmallest() const; /// Returns true if this is the smallest (by magnitude) normalized finite /// number in the given semantics. - LLVM_ABI bool isSmallestNormalized() const; + [[nodiscard]] LLVM_ABI bool isSmallestNormalized() const; /// Returns true if and only if the number has the largest possible finite /// magnitude in the current semantics. - LLVM_ABI bool isLargest() const; + [[nodiscard]] LLVM_ABI bool isLargest() const; /// Returns true if and only if the number is an exact integer. - LLVM_ABI bool isInteger() const; + [[nodiscard]] LLVM_ABI bool isInteger() const; /// @} @@ -599,7 +603,7 @@ class IEEEFloat final { unsigned FormatMaxPadding = 3, bool TruncateZero = true) const; - LLVM_ABI LLVM_READONLY int getExactLog2Abs() const; + [[nodiscard]] LLVM_ABI LLVM_READONLY int getExactLog2Abs() const; LLVM_ABI friend int ilogb(const IEEEFloat &Arg); @@ -626,15 +630,16 @@ class IEEEFloat final { /// @} - LLVM_ABI cmpResult compareAbsoluteValue(const IEEEFloat &) const; + [[nodiscard]] LLVM_ABI cmpResult + compareAbsoluteValue(const IEEEFloat &) const; private: /// \name Simple Queries /// @{ integerPart *significandParts(); - const integerPart *significandParts() const; - LLVM_ABI unsigned int partCount() const; + [[nodiscard]] const integerPart *significandParts() const; + [[nodiscard]] LLVM_ABI unsigned int partCount() const; /// @} @@ -654,16 +659,16 @@ class IEEEFloat final { void initialize(const fltSemantics *); void shiftSignificandLeft(unsigned int); lostFraction shiftSignificandRight(unsigned int); - unsigned int significandLSB() const; - unsigned int significandMSB() const; + [[nodiscard]] unsigned int significandLSB() const; + [[nodiscard]] unsigned int significandMSB() const; void zeroSignificand(); - unsigned int getNumHighBits() const; + [[nodiscard]] unsigned int getNumHighBits() const; /// Return true if the significand excluding the integral bit is all ones. - bool isSignificandAllOnes() const; - bool isSignificandAllOnesExceptLSB() const; + [[nodiscard]] bool isSignificandAllOnes() const; + [[nodiscard]] bool isSignificandAllOnesExceptLSB() const; /// Return true if the significand excluding the integral bit is all zeros. - bool isSignificandAllZeros() const; - bool isSignificandAllZerosExceptMSB() const; + [[nodiscard]] bool isSignificandAllZeros() const; + [[nodiscard]] bool isSignificandAllZerosExceptMSB() const; /// @} @@ -685,7 +690,8 @@ class IEEEFloat final { opStatus normalize(roundingMode, lostFraction); opStatus addOrSubtract(const IEEEFloat &, roundingMode, bool subtract); opStatus handleOverflow(roundingMode); - bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const; + [[nodiscard]] bool roundAwayFromZero(roundingMode, lostFraction, + unsigned int) const; opStatus convertToSignExtendedInteger(MutableArrayRef, unsigned int, bool, roundingMode, bool *) const; @@ -697,9 +703,9 @@ class IEEEFloat final { roundingMode) const; opStatus roundSignificandWithExponent(const integerPart *, unsigned int, int, roundingMode); - ExponentType exponentNaN() const; - ExponentType exponentInf() const; - ExponentType exponentZero() const; + [[nodiscard]] ExponentType exponentNaN() const; + [[nodiscard]] ExponentType exponentInf() const; + [[nodiscard]] ExponentType exponentZero() const; /// @} @@ -823,12 +829,12 @@ class DoubleAPFloat final { LLVM_ABI DoubleAPFloat &operator=(const DoubleAPFloat &RHS); inline DoubleAPFloat &operator=(DoubleAPFloat &&RHS); - bool needsCleanup() const { return Floats != nullptr; } + [[nodiscard]] bool needsCleanup() const { return Floats != nullptr; } inline APFloat &getFirst(); - inline const APFloat &getFirst() const; + [[nodiscard]] inline const APFloat &getFirst() const; inline APFloat &getSecond(); - inline const APFloat &getSecond() const; + [[nodiscard]] inline const APFloat &getSecond() const; LLVM_ABI opStatus add(const DoubleAPFloat &RHS, roundingMode RM); LLVM_ABI opStatus subtract(const DoubleAPFloat &RHS, roundingMode RM); @@ -841,10 +847,11 @@ class DoubleAPFloat final { roundingMode RM); LLVM_ABI opStatus roundToIntegral(roundingMode RM); LLVM_ABI void changeSign(); - LLVM_ABI cmpResult compareAbsoluteValue(const DoubleAPFloat &RHS) const; + [[nodiscard]] LLVM_ABI cmpResult + compareAbsoluteValue(const DoubleAPFloat &RHS) const; - LLVM_ABI fltCategory getCategory() const; - LLVM_ABI bool isNegative() const; + [[nodiscard]] LLVM_ABI fltCategory getCategory() const; + [[nodiscard]] LLVM_ABI bool isNegative() const; LLVM_ABI void makeInf(bool Neg); LLVM_ABI void makeZero(bool Neg); @@ -853,8 +860,8 @@ class DoubleAPFloat final { LLVM_ABI void makeSmallestNormalized(bool Neg); LLVM_ABI void makeNaN(bool SNaN, bool Neg, const APInt *fill); - LLVM_ABI cmpResult compare(const DoubleAPFloat &RHS) const; - LLVM_ABI bool bitwiseIsEqual(const DoubleAPFloat &RHS) const; + [[nodiscard]] LLVM_ABI cmpResult compare(const DoubleAPFloat &RHS) const; + [[nodiscard]] LLVM_ABI bool bitwiseIsEqual(const DoubleAPFloat &RHS) const; LLVM_ABI APInt bitcastToAPInt() const; LLVM_ABI Expected convertFromString(StringRef, roundingMode); LLVM_ABI opStatus next(bool nextDown); @@ -868,17 +875,17 @@ class DoubleAPFloat final { bool UpperCase, roundingMode RM) const; - LLVM_ABI bool isDenormal() const; - LLVM_ABI bool isSmallest() const; - LLVM_ABI bool isSmallestNormalized() const; - LLVM_ABI bool isLargest() const; - LLVM_ABI bool isInteger() const; + [[nodiscard]] LLVM_ABI bool isDenormal() const; + [[nodiscard]] LLVM_ABI bool isSmallest() const; + [[nodiscard]] LLVM_ABI bool isSmallestNormalized() const; + [[nodiscard]] LLVM_ABI bool isLargest() const; + [[nodiscard]] LLVM_ABI bool isInteger() const; LLVM_ABI void toString(SmallVectorImpl &Str, unsigned FormatPrecision, unsigned FormatMaxPadding, bool TruncateZero = true) const; - LLVM_ABI LLVM_READONLY int getExactLog2Abs() const; + [[nodiscard]] LLVM_ABI LLVM_READONLY int getExactLog2Abs() const; LLVM_ABI friend int ilogb(const DoubleAPFloat &X); LLVM_ABI friend DoubleAPFloat scalbn(const DoubleAPFloat &X, int Exp, @@ -1009,7 +1016,7 @@ class APFloat : public APFloatBase { llvm_unreachable("Unexpected semantics"); } - const IEEEFloat &getIEEE() const { + [[nodiscard]] const IEEEFloat &getIEEE() const { if (usesLayout(*U.semantics)) return U.IEEE; if (usesLayout(*U.semantics)) @@ -1043,7 +1050,7 @@ class APFloat : public APFloatBase { // Compares the absolute value of this APFloat with another. Both operands // must be finite non-zero. - cmpResult compareAbsoluteValue(const APFloat &RHS) const { + [[nodiscard]] cmpResult compareAbsoluteValue(const APFloat &RHS) const { assert(&getSemantics() == &RHS.getSemantics() && "Should only compare APFloats with the same semantics"); if (usesLayout(getSemantics())) @@ -1071,7 +1078,9 @@ class APFloat : public APFloatBase { ~APFloat() = default; - bool needsCleanup() const { APFLOAT_DISPATCH_ON_SEMANTICS(needsCleanup()); } + [[nodiscard]] bool needsCleanup() const { + APFLOAT_DISPATCH_ON_SEMANTICS(needsCleanup()); + } /// Factory for Positive and Negative Zero. /// @@ -1313,7 +1322,7 @@ class APFloat : public APFloatBase { /// Assuming this is an IEEE-754 NaN value, quiet its signaling bit. /// This preserves the sign and payload bits. - APFloat makeQuiet() const { + [[nodiscard]] APFloat makeQuiet() const { APFloat Result(*this); Result.getIEEE().makeQuiet(); return Result; @@ -1359,7 +1368,7 @@ class APFloat : public APFloatBase { /// \pre The APFloat must be built using semantics, that can be represented by /// the host double type without loss of precision. It can be IEEEdouble and /// shorter semantics, like IEEEsingle and others. - LLVM_ABI double convertToDouble() const; + [[nodiscard]] LLVM_ABI double convertToDouble() const; /// Converts this APFloat to host float value. /// @@ -1367,7 +1376,7 @@ class APFloat : public APFloatBase { /// the host float type without loss of precision. It can be IEEEquad and /// shorter semantics, like IEEEdouble and others. #ifdef HAS_IEE754_FLOAT128 - LLVM_ABI float128 convertToQuad() const; + [[nodiscard]] LLVM_ABI float128 convertToQuad() const; #endif /// Converts this APFloat to host float value. @@ -1375,7 +1384,7 @@ class APFloat : public APFloatBase { /// \pre The APFloat must be built using semantics, that can be represented by /// the host float type without loss of precision. It can be IEEEsingle and /// shorter semantics, like IEEEhalf. - LLVM_ABI float convertToFloat() const; + [[nodiscard]] LLVM_ABI float convertToFloat() const; bool operator==(const APFloat &RHS) const { return compare(RHS) == cmpEqual; } @@ -1401,7 +1410,7 @@ class APFloat : public APFloatBase { // IEEE comparison with another floating point number (NaNs compare unordered, // 0==-0). - cmpResult compare(const APFloat &RHS) const { + [[nodiscard]] cmpResult compare(const APFloat &RHS) const { assert(&getSemantics() == &RHS.getSemantics() && "Should only compare APFloats with the same semantics"); if (usesLayout(getSemantics())) @@ -1411,7 +1420,7 @@ class APFloat : public APFloatBase { llvm_unreachable("Unexpected semantics"); } - bool bitwiseIsEqual(const APFloat &RHS) const { + [[nodiscard]] bool bitwiseIsEqual(const APFloat &RHS) const { if (&getSemantics() != &RHS.getSemantics()) return false; if (usesLayout(getSemantics())) @@ -1429,7 +1438,7 @@ class APFloat : public APFloatBase { /// We leave the version with the double argument here because it's just so /// convenient to write "2.0" and the like. Without this function we'd /// have to duplicate its logic everywhere it's called. - bool isExactlyValue(double V) const { + [[nodiscard]] bool isExactlyValue(double V) const { bool ignored; APFloat Tmp(V); Tmp.convert(getSemantics(), APFloat::rmNearestTiesToEven, &ignored); @@ -1442,35 +1451,53 @@ class APFloat : public APFloatBase { convertToHexString(DST, HexDigits, UpperCase, RM)); } - bool isZero() const { return getCategory() == fcZero; } - bool isInfinity() const { return getCategory() == fcInfinity; } - bool isNaN() const { return getCategory() == fcNaN; } + [[nodiscard]] bool isZero() const { return getCategory() == fcZero; } + [[nodiscard]] bool isInfinity() const { return getCategory() == fcInfinity; } + [[nodiscard]] bool isNaN() const { return getCategory() == fcNaN; } - bool isNegative() const { return getIEEE().isNegative(); } - bool isDenormal() const { APFLOAT_DISPATCH_ON_SEMANTICS(isDenormal()); } - bool isSignaling() const { return getIEEE().isSignaling(); } + [[nodiscard]] bool isNegative() const { return getIEEE().isNegative(); } + [[nodiscard]] bool isDenormal() const { + APFLOAT_DISPATCH_ON_SEMANTICS(isDenormal()); + } + [[nodiscard]] bool isSignaling() const { return getIEEE().isSignaling(); } - bool isNormal() const { return !isDenormal() && isFiniteNonZero(); } - bool isFinite() const { return !isNaN() && !isInfinity(); } + [[nodiscard]] bool isNormal() const { + return !isDenormal() && isFiniteNonZero(); + } + [[nodiscard]] bool isFinite() const { return !isNaN() && !isInfinity(); } - fltCategory getCategory() const { return getIEEE().getCategory(); } - const fltSemantics &getSemantics() const { return *U.semantics; } - bool isNonZero() const { return !isZero(); } - bool isFiniteNonZero() const { return isFinite() && !isZero(); } - bool isPosZero() const { return isZero() && !isNegative(); } - bool isNegZero() const { return isZero() && isNegative(); } - bool isPosInfinity() const { return isInfinity() && !isNegative(); } - bool isNegInfinity() const { return isInfinity() && isNegative(); } - bool isSmallest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isSmallest()); } - bool isLargest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isLargest()); } - bool isInteger() const { APFLOAT_DISPATCH_ON_SEMANTICS(isInteger()); } + [[nodiscard]] fltCategory getCategory() const { + return getIEEE().getCategory(); + } + [[nodiscard]] const fltSemantics &getSemantics() const { + return *U.semantics; + } + [[nodiscard]] bool isNonZero() const { return !isZero(); } + [[nodiscard]] bool isFiniteNonZero() const { return isFinite() && !isZero(); } + [[nodiscard]] bool isPosZero() const { return isZero() && !isNegative(); } + [[nodiscard]] bool isNegZero() const { return isZero() && isNegative(); } + [[nodiscard]] bool isPosInfinity() const { + return isInfinity() && !isNegative(); + } + [[nodiscard]] bool isNegInfinity() const { + return isInfinity() && isNegative(); + } + [[nodiscard]] bool isSmallest() const { + APFLOAT_DISPATCH_ON_SEMANTICS(isSmallest()); + } + [[nodiscard]] bool isLargest() const { + APFLOAT_DISPATCH_ON_SEMANTICS(isLargest()); + } + [[nodiscard]] bool isInteger() const { + APFLOAT_DISPATCH_ON_SEMANTICS(isInteger()); + } - bool isSmallestNormalized() const { + [[nodiscard]] bool isSmallestNormalized() const { APFLOAT_DISPATCH_ON_SEMANTICS(isSmallestNormalized()); } /// Return the FPClassTest which will return true for the value. - LLVM_ABI FPClassTest classify() const; + [[nodiscard]] LLVM_ABI FPClassTest classify() const; APFloat &operator=(const APFloat &RHS) = default; APFloat &operator=(APFloat &&RHS) = default; @@ -1493,15 +1520,13 @@ class APFloat : public APFloatBase { // If this is an exact power of two, return the exponent while ignoring the // sign bit. If it's not an exact power of 2, return INT_MIN - LLVM_READONLY - int getExactLog2Abs() const { + [[nodiscard]] LLVM_READONLY int getExactLog2Abs() const { APFLOAT_DISPATCH_ON_SEMANTICS(getExactLog2Abs()); } // If this is an exact power of two, return the exponent. If it's not an exact // power of 2, return INT_MIN - LLVM_READONLY - int getExactLog2() const { + [[nodiscard]] LLVM_READONLY int getExactLog2() const { return isNegative() ? INT_MIN : getExactLog2Abs(); } diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h index 9fa98ad4ddde1..cc58ea48c3a41 100644 --- a/llvm/include/llvm/ADT/APInt.h +++ b/llvm/include/llvm/ADT/APInt.h @@ -319,33 +319,35 @@ class [[nodiscard]] APInt { /// Determine if this APInt just has one word to store value. /// /// \returns true if the number of bits <= 64, false otherwise. - bool isSingleWord() const { return BitWidth <= APINT_BITS_PER_WORD; } + [[nodiscard]] bool isSingleWord() const { + return BitWidth <= APINT_BITS_PER_WORD; + } /// Determine sign of this APInt. /// /// This tests the high bit of this APInt to determine if it is set. /// /// \returns true if this APInt is negative, false otherwise - bool isNegative() const { return (*this)[BitWidth - 1]; } + [[nodiscard]] bool isNegative() const { return (*this)[BitWidth - 1]; } /// Determine if this APInt Value is non-negative (>= 0) /// /// This tests the high bit of the APInt to determine if it is unset. - bool isNonNegative() const { return !isNegative(); } + [[nodiscard]] bool isNonNegative() const { return !isNegative(); } /// Determine if sign bit of this APInt is set. /// /// This tests the high bit of this APInt to determine if it is set. /// /// \returns true if this APInt has its sign bit set, false otherwise. - bool isSignBitSet() const { return (*this)[BitWidth - 1]; } + [[nodiscard]] bool isSignBitSet() const { return (*this)[BitWidth - 1]; } /// Determine if sign bit of this APInt is clear. /// /// This tests the high bit of this APInt to determine if it is clear. /// /// \returns true if this APInt has its sign bit clear, false otherwise. - bool isSignBitClear() const { return !isSignBitSet(); } + [[nodiscard]] bool isSignBitClear() const { return !isSignBitSet(); } /// Determine if this APInt Value is positive. /// @@ -353,22 +355,24 @@ class [[nodiscard]] APInt { /// that 0 is not a positive value. /// /// \returns true if this APInt is positive. - bool isStrictlyPositive() const { return isNonNegative() && !isZero(); } + [[nodiscard]] bool isStrictlyPositive() const { + return isNonNegative() && !isZero(); + } /// Determine if this APInt Value is non-positive (<= 0). /// /// \returns true if this APInt is non-positive. - bool isNonPositive() const { return !isStrictlyPositive(); } + [[nodiscard]] bool isNonPositive() const { return !isStrictlyPositive(); } /// Determine if this APInt Value only has the specified bit set. /// /// \returns true if this APInt only has the specified bit set. - bool isOneBitSet(unsigned BitNo) const { + [[nodiscard]] bool isOneBitSet(unsigned BitNo) const { return (*this)[BitNo] && popcount() == 1; } /// Determine if all bits are set. This is true for zero-width values. - bool isAllOnes() const { + [[nodiscard]] bool isAllOnes() const { if (BitWidth == 0) return true; if (isSingleWord()) @@ -377,7 +381,7 @@ class [[nodiscard]] APInt { } /// Determine if this value is zero, i.e. all bits are clear. - bool isZero() const { + [[nodiscard]] bool isZero() const { if (isSingleWord()) return U.VAL == 0; return countLeadingZerosSlowCase() == BitWidth; @@ -386,7 +390,7 @@ class [[nodiscard]] APInt { /// Determine if this is a value of 1. /// /// This checks to see if the value of this APInt is one. - bool isOne() const { + [[nodiscard]] bool isOne() const { if (isSingleWord()) return U.VAL == 1; return countLeadingZerosSlowCase() == BitWidth - 1; @@ -396,13 +400,13 @@ class [[nodiscard]] APInt { /// /// This checks to see if the value of this APInt is the maximum unsigned /// value for the APInt's bit width. - bool isMaxValue() const { return isAllOnes(); } + [[nodiscard]] bool isMaxValue() const { return isAllOnes(); } /// Determine if this is the largest signed value. /// /// This checks to see if the value of this APInt is the maximum signed /// value for the APInt's bit width. - bool isMaxSignedValue() const { + [[nodiscard]] bool isMaxSignedValue() const { if (isSingleWord()) { assert(BitWidth && "zero width values not allowed"); return U.VAL == ((WordType(1) << (BitWidth - 1)) - 1); @@ -414,13 +418,13 @@ class [[nodiscard]] APInt { /// /// This checks to see if the value of this APInt is the minimum unsigned /// value for the APInt's bit width. - bool isMinValue() const { return isZero(); } + [[nodiscard]] bool isMinValue() const { return isZero(); } /// Determine if this is the smallest signed value. /// /// This checks to see if the value of this APInt is the minimum signed /// value for the APInt's bit width. - bool isMinSignedValue() const { + [[nodiscard]] bool isMinSignedValue() const { if (isSingleWord()) { assert(BitWidth && "zero width values not allowed"); return U.VAL == (WordType(1) << (BitWidth - 1)); @@ -429,15 +433,17 @@ class [[nodiscard]] APInt { } /// Check if this APInt has an N-bits unsigned integer value. - bool isIntN(unsigned N) const { return getActiveBits() <= N; } + [[nodiscard]] bool isIntN(unsigned N) const { return getActiveBits() <= N; } /// Check if this APInt has an N-bits signed integer value. - bool isSignedIntN(unsigned N) const { return getSignificantBits() <= N; } + [[nodiscard]] bool isSignedIntN(unsigned N) const { + return getSignificantBits() <= N; + } /// Check if this APInt's value is a power of two greater than zero. /// /// \returns true if the argument APInt value is a power of two > 0. - bool isPowerOf2() const { + [[nodiscard]] bool isPowerOf2() const { if (isSingleWord()) { assert(BitWidth && "zero width values not allowed"); return isPowerOf2_64(U.VAL); @@ -446,7 +452,7 @@ class [[nodiscard]] APInt { } /// Check if this APInt's negated value is a power of two greater than zero. - bool isNegatedPowerOf2() const { + [[nodiscard]] bool isNegatedPowerOf2() const { assert(BitWidth && "zero width values not allowed"); if (isNonNegative()) return false; @@ -458,21 +464,21 @@ class [[nodiscard]] APInt { /// Checks if this APInt -interpreted as an address- is aligned to the /// provided value. - LLVM_ABI bool isAligned(Align A) const; + [[nodiscard]] LLVM_ABI bool isAligned(Align A) const; /// Check if the APInt's value is returned by getSignMask. /// /// \returns true if this is the value returned by getSignMask. - bool isSignMask() const { return isMinSignedValue(); } + [[nodiscard]] bool isSignMask() const { return isMinSignedValue(); } /// Convert APInt to a boolean value. /// /// This converts the APInt to a boolean value as a test against zero. - bool getBoolValue() const { return !isZero(); } + [[nodiscard]] bool getBoolValue() const { return !isZero(); } /// If this value is smaller than the specified limit, return it, otherwise /// return the limit value. This causes the value to saturate to the limit. - uint64_t getLimitedValue(uint64_t Limit = UINT64_MAX) const { + [[nodiscard]] uint64_t getLimitedValue(uint64_t Limit = UINT64_MAX) const { return ugt(Limit) ? Limit : getZExtValue(); } @@ -481,11 +487,11 @@ class [[nodiscard]] APInt { /// e.g. 0x01010101 satisfies isSplat(8). /// \param SplatSizeInBits The size of the pattern in bits. Must divide bit /// width without remainder. - LLVM_ABI bool isSplat(unsigned SplatSizeInBits) const; + [[nodiscard]] LLVM_ABI bool isSplat(unsigned SplatSizeInBits) const; /// \returns true if this APInt value is a sequence of \param numBits ones /// starting at the least significant bit with the remainder zero. - bool isMask(unsigned numBits) const { + [[nodiscard]] bool isMask(unsigned numBits) const { assert(numBits != 0 && "numBits must be non-zero"); assert(numBits <= BitWidth && "numBits out of range"); if (isSingleWord()) @@ -498,7 +504,7 @@ class [[nodiscard]] APInt { /// \returns true if this APInt is a non-empty sequence of ones starting at /// the least significant bit with the remainder zero. /// Ex. isMask(0x0000FFFFU) == true. - bool isMask() const { + [[nodiscard]] bool isMask() const { if (isSingleWord()) return isMask_64(U.VAL); unsigned Ones = countTrailingOnesSlowCase(); @@ -507,7 +513,7 @@ class [[nodiscard]] APInt { /// Return true if this APInt value contains a non-empty sequence of ones with /// the remainder zero. - bool isShiftedMask() const { + [[nodiscard]] bool isShiftedMask() const { if (isSingleWord()) return isShiftedMask_64(U.VAL); unsigned Ones = countPopulationSlowCase(); @@ -566,7 +572,7 @@ class [[nodiscard]] APInt { /// This function returns a pointer to the internal storage of the APInt. /// This is useful for writing out the APInt in binary form without any /// conversions. - const uint64_t *getRawData() const { + [[nodiscard]] const uint64_t *getRawData() const { if (isSingleWord()) return &U.VAL; return &U.pVal[0]; @@ -978,7 +984,7 @@ class [[nodiscard]] APInt { /// /// \returns a new APInt value containing the remainder result LLVM_ABI APInt urem(const APInt &RHS) const; - LLVM_ABI uint64_t urem(uint64_t RHS) const; + [[nodiscard]] LLVM_ABI uint64_t urem(uint64_t RHS) const; /// Function for signed remainder operation. /// @@ -987,7 +993,7 @@ class [[nodiscard]] APInt { /// Note that this is a true remainder operation and not a modulo operation /// because the sign follows the sign of the dividend which is *this. LLVM_ABI APInt srem(const APInt &RHS) const; - LLVM_ABI int64_t srem(int64_t RHS) const; + [[nodiscard]] LLVM_ABI int64_t srem(int64_t RHS) const; /// Dual division/remainder interface. /// @@ -1076,7 +1082,7 @@ class [[nodiscard]] APInt { /// relationship. /// /// \returns true if *this == Val - bool eq(const APInt &RHS) const { return (*this) == RHS; } + [[nodiscard]] bool eq(const APInt &RHS) const { return (*this) == RHS; } /// Inequality operator. /// @@ -1100,7 +1106,7 @@ class [[nodiscard]] APInt { /// relationship. /// /// \returns true if *this != Val - bool ne(const APInt &RHS) const { return !((*this) == RHS); } + [[nodiscard]] bool ne(const APInt &RHS) const { return !((*this) == RHS); } /// Unsigned less than comparison /// @@ -1108,7 +1114,7 @@ class [[nodiscard]] APInt { /// the validity of the less-than relationship. /// /// \returns true if *this < RHS when both are considered unsigned. - bool ult(const APInt &RHS) const { return compare(RHS) < 0; } + [[nodiscard]] bool ult(const APInt &RHS) const { return compare(RHS) < 0; } /// Unsigned less than comparison /// @@ -1116,7 +1122,7 @@ class [[nodiscard]] APInt { /// the validity of the less-than relationship. /// /// \returns true if *this < RHS when considered unsigned. - bool ult(uint64_t RHS) const { + [[nodiscard]] bool ult(uint64_t RHS) const { // Only need to check active bits if not a single word. return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() < RHS; } @@ -1127,7 +1133,9 @@ class [[nodiscard]] APInt { /// validity of the less-than relationship. /// /// \returns true if *this < RHS when both are considered signed. - bool slt(const APInt &RHS) const { return compareSigned(RHS) < 0; } + [[nodiscard]] bool slt(const APInt &RHS) const { + return compareSigned(RHS) < 0; + } /// Signed less than comparison /// @@ -1135,7 +1143,7 @@ class [[nodiscard]] APInt { /// the validity of the less-than relationship. /// /// \returns true if *this < RHS when considered signed. - bool slt(int64_t RHS) const { + [[nodiscard]] bool slt(int64_t RHS) const { return (!isSingleWord() && getSignificantBits() > 64) ? isNegative() : getSExtValue() < RHS; @@ -1147,7 +1155,7 @@ class [[nodiscard]] APInt { /// validity of the less-or-equal relationship. /// /// \returns true if *this <= RHS when both are considered unsigned. - bool ule(const APInt &RHS) const { return compare(RHS) <= 0; } + [[nodiscard]] bool ule(const APInt &RHS) const { return compare(RHS) <= 0; } /// Unsigned less or equal comparison /// @@ -1155,7 +1163,7 @@ class [[nodiscard]] APInt { /// the validity of the less-or-equal relationship. /// /// \returns true if *this <= RHS when considered unsigned. - bool ule(uint64_t RHS) const { return !ugt(RHS); } + [[nodiscard]] bool ule(uint64_t RHS) const { return !ugt(RHS); } /// Signed less or equal comparison /// @@ -1163,7 +1171,9 @@ class [[nodiscard]] APInt { /// validity of the less-or-equal relationship. /// /// \returns true if *this <= RHS when both are considered signed. - bool sle(const APInt &RHS) const { return compareSigned(RHS) <= 0; } + [[nodiscard]] bool sle(const APInt &RHS) const { + return compareSigned(RHS) <= 0; + } /// Signed less or equal comparison /// @@ -1171,7 +1181,7 @@ class [[nodiscard]] APInt { /// validity of the less-or-equal relationship. /// /// \returns true if *this <= RHS when considered signed. - bool sle(uint64_t RHS) const { return !sgt(RHS); } + [[nodiscard]] bool sle(uint64_t RHS) const { return !sgt(RHS); } /// Unsigned greater than comparison /// @@ -1179,7 +1189,7 @@ class [[nodiscard]] APInt { /// the validity of the greater-than relationship. /// /// \returns true if *this > RHS when both are considered unsigned. - bool ugt(const APInt &RHS) const { return !ule(RHS); } + [[nodiscard]] bool ugt(const APInt &RHS) const { return !ule(RHS); } /// Unsigned greater than comparison /// @@ -1187,7 +1197,7 @@ class [[nodiscard]] APInt { /// the validity of the greater-than relationship. /// /// \returns true if *this > RHS when considered unsigned. - bool ugt(uint64_t RHS) const { + [[nodiscard]] bool ugt(uint64_t RHS) const { // Only need to check active bits if not a single word. return (!isSingleWord() && getActiveBits() > 64) || getZExtValue() > RHS; } @@ -1198,7 +1208,7 @@ class [[nodiscard]] APInt { /// validity of the greater-than relationship. /// /// \returns true if *this > RHS when both are considered signed. - bool sgt(const APInt &RHS) const { return !sle(RHS); } + [[nodiscard]] bool sgt(const APInt &RHS) const { return !sle(RHS); } /// Signed greater than comparison /// @@ -1206,7 +1216,7 @@ class [[nodiscard]] APInt { /// the validity of the greater-than relationship. /// /// \returns true if *this > RHS when considered signed. - bool sgt(int64_t RHS) const { + [[nodiscard]] bool sgt(int64_t RHS) const { return (!isSingleWord() && getSignificantBits() > 64) ? !isNegative() : getSExtValue() > RHS; @@ -1218,7 +1228,7 @@ class [[nodiscard]] APInt { /// validity of the greater-or-equal relationship. /// /// \returns true if *this >= RHS when both are considered unsigned. - bool uge(const APInt &RHS) const { return !ult(RHS); } + [[nodiscard]] bool uge(const APInt &RHS) const { return !ult(RHS); } /// Unsigned greater or equal comparison /// @@ -1226,7 +1236,7 @@ class [[nodiscard]] APInt { /// the validity of the greater-or-equal relationship. /// /// \returns true if *this >= RHS when considered unsigned. - bool uge(uint64_t RHS) const { return !ult(RHS); } + [[nodiscard]] bool uge(uint64_t RHS) const { return !ult(RHS); } /// Signed greater or equal comparison /// @@ -1234,7 +1244,7 @@ class [[nodiscard]] APInt { /// validity of the greater-or-equal relationship. /// /// \returns true if *this >= RHS when both are considered signed. - bool sge(const APInt &RHS) const { return !slt(RHS); } + [[nodiscard]] bool sge(const APInt &RHS) const { return !slt(RHS); } /// Signed greater or equal comparison /// @@ -1242,11 +1252,11 @@ class [[nodiscard]] APInt { /// the validity of the greater-or-equal relationship. /// /// \returns true if *this >= RHS when considered signed. - bool sge(int64_t RHS) const { return !slt(RHS); } + [[nodiscard]] bool sge(int64_t RHS) const { return !slt(RHS); } /// This operation tests if there are any pairs of corresponding bits /// between this APInt and RHS that are both set. - bool intersects(const APInt &RHS) const { + [[nodiscard]] bool intersects(const APInt &RHS) const { assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); if (isSingleWord()) return (U.VAL & RHS.U.VAL) != 0; @@ -1254,7 +1264,7 @@ class [[nodiscard]] APInt { } /// This operation checks that all bits set in this APInt are also set in RHS. - bool isSubsetOf(const APInt &RHS) const { + [[nodiscard]] bool isSubsetOf(const APInt &RHS) const { assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); if (isSingleWord()) return (U.VAL & ~RHS.U.VAL) == 0; @@ -1477,22 +1487,22 @@ class [[nodiscard]] APInt { /// Return an APInt with the extracted bits [bitPosition,bitPosition+numBits). LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const; - LLVM_ABI uint64_t extractBitsAsZExtValue(unsigned numBits, - unsigned bitPosition) const; + [[nodiscard]] LLVM_ABI uint64_t + extractBitsAsZExtValue(unsigned numBits, unsigned bitPosition) const; /// @} /// \name Value Characterization Functions /// @{ /// Return the number of bits in the APInt. - unsigned getBitWidth() const { return BitWidth; } + [[nodiscard]] unsigned getBitWidth() const { return BitWidth; } /// Get the number of words. /// /// Here one word's bitwidth equals to that of uint64_t. /// /// \returns the number of words to hold the integer value of this APInt. - unsigned getNumWords() const { return getNumWords(BitWidth); } + [[nodiscard]] unsigned getNumWords() const { return getNumWords(BitWidth); } /// Get the number of words. /// @@ -1509,13 +1519,15 @@ class [[nodiscard]] APInt { /// This function returns the number of active bits which is defined as the /// bit width minus the number of leading zeros. This is used in several /// computations to see how "wide" the value is. - unsigned getActiveBits() const { return BitWidth - countl_zero(); } + [[nodiscard]] unsigned getActiveBits() const { + return BitWidth - countl_zero(); + } /// Compute the number of active words in the value of this APInt. /// /// This is used in conjunction with getActiveData to extract the raw value of /// the APInt. - unsigned getActiveWords() const { + [[nodiscard]] unsigned getActiveWords() const { unsigned numActiveBits = getActiveBits(); return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1; } @@ -1528,7 +1540,7 @@ class [[nodiscard]] APInt { /// returns the smallest bit width that will retain the negative value. For /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so /// for -1, this function will always return 1. - unsigned getSignificantBits() const { + [[nodiscard]] unsigned getSignificantBits() const { return BitWidth - getNumSignBits() + 1; } @@ -1537,7 +1549,7 @@ class [[nodiscard]] APInt { /// 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 an assertion will result. - uint64_t getZExtValue() const { + [[nodiscard]] uint64_t getZExtValue() const { if (isSingleWord()) return U.VAL; assert(getActiveBits() <= 64 && "Too many bits for uint64_t"); @@ -1549,7 +1561,7 @@ class [[nodiscard]] APInt { /// 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. - std::optional tryZExtValue() const { + [[nodiscard]] std::optional tryZExtValue() const { return (getActiveBits() <= 64) ? std::optional(getZExtValue()) : std::nullopt; }; @@ -1559,7 +1571,7 @@ class [[nodiscard]] APInt { /// This method attempts to return the value of this APInt as a sign extended /// int64_t. The bit width must be <= 64 or the value must fit within an /// int64_t. Otherwise an assertion will result. - int64_t getSExtValue() const { + [[nodiscard]] int64_t getSExtValue() const { if (isSingleWord()) return SignExtend64(U.VAL, BitWidth); assert(getSignificantBits() <= 64 && "Too many bits for int64_t"); @@ -1571,7 +1583,7 @@ class [[nodiscard]] APInt { /// This method attempts to return the value of this APInt as a sign extended /// int64_t. The bitwidth must be <= 64 or the value must fit within an /// int64_t. Otherwise no value is returned. - std::optional trySExtValue() const { + [[nodiscard]] std::optional trySExtValue() const { return (getSignificantBits() <= 64) ? std::optional(getSExtValue()) : std::nullopt; }; @@ -1595,7 +1607,7 @@ class [[nodiscard]] APInt { /// /// \returns BitWidth if the value is zero, otherwise returns the number of /// zeros from the most significant bit to the first one bits. - unsigned countl_zero() const { + [[nodiscard]] unsigned countl_zero() const { if (isSingleWord()) { unsigned unusedBits = APINT_BITS_PER_WORD - BitWidth; return llvm::countl_zero(U.VAL) - unusedBits; @@ -1603,7 +1615,7 @@ class [[nodiscard]] APInt { return countLeadingZerosSlowCase(); } - unsigned countLeadingZeros() const { return countl_zero(); } + [[nodiscard]] unsigned countLeadingZeros() const { return countl_zero(); } /// Count the number of leading one bits. /// @@ -1612,7 +1624,7 @@ class [[nodiscard]] APInt { /// /// \returns 0 if the high order bit is not set, otherwise returns the number /// of 1 bits from the most significant to the least - unsigned countl_one() const { + [[nodiscard]] unsigned countl_one() const { if (isSingleWord()) { if (LLVM_UNLIKELY(BitWidth == 0)) return 0; @@ -1621,11 +1633,11 @@ class [[nodiscard]] APInt { return countLeadingOnesSlowCase(); } - unsigned countLeadingOnes() const { return countl_one(); } + [[nodiscard]] unsigned countLeadingOnes() const { return countl_one(); } /// Computes the number of leading bits of this APInt that are equal to its /// sign bit. - unsigned getNumSignBits() const { + [[nodiscard]] unsigned getNumSignBits() const { return isNegative() ? countl_one() : countl_zero(); } @@ -1636,7 +1648,7 @@ class [[nodiscard]] APInt { /// /// \returns BitWidth if the value is zero, otherwise returns the number of /// zeros from the least significant bit to the first one bit. - unsigned countr_zero() const { + [[nodiscard]] unsigned countr_zero() const { if (isSingleWord()) { unsigned TrailingZeros = llvm::countr_zero(U.VAL); return (TrailingZeros > BitWidth ? BitWidth : TrailingZeros); @@ -1644,7 +1656,7 @@ class [[nodiscard]] APInt { return countTrailingZerosSlowCase(); } - unsigned countTrailingZeros() const { return countr_zero(); } + [[nodiscard]] unsigned countTrailingZeros() const { return countr_zero(); } /// Count the number of trailing one bits. /// @@ -1653,13 +1665,13 @@ class [[nodiscard]] APInt { /// /// \returns BitWidth if the value is all ones, otherwise returns the number /// of ones from the least significant bit to the first zero bit. - unsigned countr_one() const { + [[nodiscard]] unsigned countr_one() const { if (isSingleWord()) return llvm::countr_one(U.VAL); return countTrailingOnesSlowCase(); } - unsigned countTrailingOnes() const { return countr_one(); } + [[nodiscard]] unsigned countTrailingOnes() const { return countr_one(); } /// Count the number of bits set. /// @@ -1667,7 +1679,7 @@ class [[nodiscard]] APInt { /// of 1 bits in the APInt value. /// /// \returns 0 if the value is zero, otherwise returns the number of set bits. - unsigned popcount() const { + [[nodiscard]] unsigned popcount() const { if (isSingleWord()) return llvm::popcount(U.VAL); return countPopulationSlowCase(); @@ -1706,23 +1718,27 @@ class [[nodiscard]] APInt { LLVM_ABI APInt reverseBits() const; /// Converts this APInt to a double value. - LLVM_ABI double roundToDouble(bool isSigned) const; + [[nodiscard]] LLVM_ABI double roundToDouble(bool isSigned) const; /// Converts this unsigned APInt to a double value. - double roundToDouble() const { return roundToDouble(false); } + [[nodiscard]] double roundToDouble() const { return roundToDouble(false); } /// Converts this signed APInt to a double value. - double signedRoundToDouble() const { return roundToDouble(true); } + [[nodiscard]] double signedRoundToDouble() const { + return roundToDouble(true); + } /// Converts APInt bits to a double /// /// The conversion does not do a translation from integer to double, it just /// re-interprets the bits as a double. Note that it is valid to do this on /// any bit width. Exactly 64 bits will be translated. - double bitsToDouble() const { return llvm::bit_cast(getWord(0)); } + [[nodiscard]] double bitsToDouble() const { + return llvm::bit_cast(getWord(0)); + } #ifdef HAS_IEE754_FLOAT128 - float128 bitsToQuad() const { + [[nodiscard]] float128 bitsToQuad() const { __uint128_t ul = ((__uint128_t)U.pVal[1] << 64) + U.pVal[0]; return llvm::bit_cast(ul); } @@ -1733,7 +1749,7 @@ class [[nodiscard]] APInt { /// The conversion does not do a translation from integer to float, it just /// re-interprets the bits as a float. Note that it is valid to do this on /// any bit width. Exactly 32 bits will be translated. - float bitsToFloat() const { + [[nodiscard]] float bitsToFloat() const { return llvm::bit_cast(static_cast(getWord(0))); } @@ -1758,10 +1774,10 @@ class [[nodiscard]] APInt { /// @{ /// \returns the floor log base 2 of this APInt. - unsigned logBase2() const { return getActiveBits() - 1; } + [[nodiscard]] unsigned logBase2() const { return getActiveBits() - 1; } /// \returns the ceil log base 2 of this APInt. - unsigned ceilLogBase2() const { + [[nodiscard]] unsigned ceilLogBase2() const { APInt temp(*this); --temp; return temp.getActiveBits(); @@ -1776,11 +1792,11 @@ class [[nodiscard]] APInt { /// /// to get around any mathematical concerns resulting from /// referencing 2 in a space where 2 does no exist. - LLVM_ABI unsigned nearestLogBase2() const; + [[nodiscard]] LLVM_ABI unsigned nearestLogBase2() const; /// \returns the log base 2 of this APInt if its an exact power of two, -1 /// otherwise - int32_t exactLogBase2() const { + [[nodiscard]] int32_t exactLogBase2() const { if (!isPowerOf2()) return -1; return logBase2(); @@ -1929,7 +1945,7 @@ class [[nodiscard]] APInt { #endif /// Returns whether this instance allocated memory. - bool needsCleanup() const { return !isSingleWord(); } + [[nodiscard]] bool needsCleanup() const { return !isSingleWord(); } private: /// This union is used to store the integer value. When the @@ -1998,7 +2014,7 @@ class [[nodiscard]] APInt { /// Get the word corresponding to a bit position /// \returns the corresponding word for the specified bit position. - uint64_t getWord(unsigned bitPosition) const { + [[nodiscard]] uint64_t getWord(unsigned bitPosition) const { return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)]; } @@ -2053,28 +2069,35 @@ class [[nodiscard]] APInt { LLVM_ABI void assignSlowCase(const APInt &RHS); /// out-of-line slow case for operator== - LLVM_ABI bool equalSlowCase(const APInt &RHS) const LLVM_READONLY; + [[nodiscard]] LLVM_ABI bool + equalSlowCase(const APInt &RHS) const LLVM_READONLY; /// out-of-line slow case for countLeadingZeros - LLVM_ABI unsigned countLeadingZerosSlowCase() const LLVM_READONLY; + [[nodiscard]] LLVM_ABI unsigned + countLeadingZerosSlowCase() const LLVM_READONLY; /// out-of-line slow case for countLeadingOnes. - LLVM_ABI unsigned countLeadingOnesSlowCase() const LLVM_READONLY; + [[nodiscard]] LLVM_ABI unsigned + countLeadingOnesSlowCase() const LLVM_READONLY; /// out-of-line slow case for countTrailingZeros. - LLVM_ABI unsigned countTrailingZerosSlowCase() const LLVM_READONLY; + [[nodiscard]] LLVM_ABI unsigned + countTrailingZerosSlowCase() const LLVM_READONLY; /// out-of-line slow case for countTrailingOnes - LLVM_ABI unsigned countTrailingOnesSlowCase() const LLVM_READONLY; + [[nodiscard]] LLVM_ABI unsigned + countTrailingOnesSlowCase() const LLVM_READONLY; /// out-of-line slow case for countPopulation - LLVM_ABI unsigned countPopulationSlowCase() const LLVM_READONLY; + [[nodiscard]] LLVM_ABI unsigned countPopulationSlowCase() const LLVM_READONLY; /// out-of-line slow case for intersects. - LLVM_ABI bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY; + [[nodiscard]] LLVM_ABI bool + intersectsSlowCase(const APInt &RHS) const LLVM_READONLY; /// out-of-line slow case for isSubsetOf. - LLVM_ABI bool isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY; + [[nodiscard]] LLVM_ABI bool + isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY; /// out-of-line slow case for setBits. LLVM_ABI void setBitsSlowCase(unsigned loBit, unsigned hiBit); @@ -2099,11 +2122,12 @@ class [[nodiscard]] APInt { /// Unsigned comparison. Returns -1, 0, or 1 if this APInt is less than, equal /// to, or greater than RHS. - LLVM_ABI int compare(const APInt &RHS) const LLVM_READONLY; + [[nodiscard]] LLVM_ABI int compare(const APInt &RHS) const LLVM_READONLY; /// Signed comparison. Returns -1, 0, or 1 if this APInt is less than, equal /// to, or greater than RHS. - LLVM_ABI int compareSigned(const APInt &RHS) const LLVM_READONLY; + [[nodiscard]] LLVM_ABI int + compareSigned(const APInt &RHS) const LLVM_READONLY; /// @} }; diff --git a/llvm/include/llvm/ADT/APSInt.h b/llvm/include/llvm/ADT/APSInt.h index 88a7a6e71c817..f1f6c4145ff41 100644 --- a/llvm/include/llvm/ADT/APSInt.h +++ b/llvm/include/llvm/ADT/APSInt.h @@ -47,12 +47,14 @@ class [[nodiscard]] APSInt : public APInt { /// Determine sign of this APSInt. /// /// \returns true if this APSInt is negative, false otherwise - bool isNegative() const { return isSigned() && APInt::isNegative(); } + [[nodiscard]] bool isNegative() const { + return isSigned() && APInt::isNegative(); + } /// Determine if this APSInt Value is non-negative (>= 0) /// /// \returns true if this APSInt is non-negative, false otherwise - bool isNonNegative() const { return !isNegative(); } + [[nodiscard]] bool isNonNegative() const { return !isNegative(); } /// Determine if this APSInt Value is positive. /// @@ -60,7 +62,9 @@ class [[nodiscard]] APSInt : public APInt { /// that 0 is not a positive value. /// /// \returns true if this APSInt is positive. - bool isStrictlyPositive() const { return isNonNegative() && !isZero(); } + [[nodiscard]] bool isStrictlyPositive() const { + return isNonNegative() && !isZero(); + } APSInt &operator=(APInt RHS) { // Retain our current sign. @@ -75,8 +79,8 @@ class [[nodiscard]] APSInt : public APInt { } // Query sign information. - bool isSigned() const { return !IsUnsigned; } - bool isUnsigned() const { return IsUnsigned; } + [[nodiscard]] bool isSigned() const { return !IsUnsigned; } + [[nodiscard]] bool isUnsigned() const { return IsUnsigned; } void setIsUnsigned(bool Val) { IsUnsigned = Val; } void setIsSigned(bool Val) { IsUnsigned = !Val; } @@ -87,7 +91,7 @@ class [[nodiscard]] APSInt : public APInt { using APInt::toString; /// If this int is representable using an int64_t. - bool isRepresentableByInt64() const { + [[nodiscard]] bool isRepresentableByInt64() const { // For unsigned values with 64 active bits, they technically fit into a // int64_t, but the user may get negative numbers and has to manually cast // them to unsigned. Let's not bet the user has the sanity to do that and @@ -96,12 +100,12 @@ class [[nodiscard]] APSInt : public APInt { } /// Get the correctly-extended \c int64_t value. - int64_t getExtValue() const { + [[nodiscard]] int64_t getExtValue() const { assert(isRepresentableByInt64() && "Too many bits for int64_t"); return isSigned() ? getSExtValue() : getZExtValue(); } - std::optional tryExtValue() const { + [[nodiscard]] std::optional tryExtValue() const { return isRepresentableByInt64() ? std::optional(getExtValue()) : std::nullopt; } diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp index 30f0a8e5089ef..13d67b92f1f10 100644 --- a/llvm/unittests/ADT/APFloatTest.cpp +++ b/llvm/unittests/ADT/APFloatTest.cpp @@ -1816,9 +1816,9 @@ TEST(APFloatTest, makeNaN) { #ifdef GTEST_HAS_DEATH_TEST #ifndef NDEBUG TEST(APFloatTest, SemanticsDeath) { - EXPECT_DEATH(APFloat(APFloat::IEEEquad(), 0).convertToDouble(), + EXPECT_DEATH((void)APFloat(APFloat::IEEEquad(), 0).convertToDouble(), "Float semantics is not representable by IEEEdouble"); - EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), 0).convertToFloat(), + EXPECT_DEATH((void)APFloat(APFloat::IEEEdouble(), 0).convertToFloat(), "Float semantics is not representable by IEEEsingle"); } #endif