17 #ifndef LLVM_ADT_APFLOAT_H 18 #define LLVM_ADT_APFLOAT_H 25 #define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \ 27 if (usesLayout<IEEEFloat>(getSemantics())) \ 28 return U.IEEE.METHOD_CALL; \ 29 if (usesLayout<DoubleAPFloat>(getSemantics())) \ 30 return U.Double.METHOD_CALL; \ 31 llvm_unreachable("Unexpected semantics"); \ 288 APInt bitcastToAPInt()
const;
289 double convertToDouble()
const;
290 float convertToFloat()
const;
304 bool bitwiseIsEqual(
const IEEEFloat &)
const;
309 unsigned int convertToHexString(
char *dst,
unsigned int hexDigits,
325 bool isNormal()
const {
return !isDenormal() && isFiniteNonZero(); }
331 bool isFinite()
const {
return !isNaN() && !isInfinity(); }
338 bool isDenormal()
const;
347 bool isSignaling()
const;
363 bool isSmallest()
const;
367 bool isLargest()
const;
370 bool isInteger()
const;
415 unsigned FormatMaxPadding = 3,
bool TruncateZero =
true)
const;
419 bool getExactInverse(
APFloat *inv)
const;
440 void makeLargest(
bool Neg =
false);
441 void makeSmallest(
bool Neg =
false);
442 void makeNaN(
bool SNaN =
false,
bool Neg =
false,
443 const APInt *fill =
nullptr);
444 void makeInf(
bool Neg =
false);
445 void makeZero(
bool Neg =
false);
452 void makeSmallestNormalized(
bool Negative =
false);
464 unsigned int partCount()
const;
476 void incrementSignificand();
478 void shiftSignificandLeft(
unsigned int);
480 unsigned int significandLSB()
const;
481 unsigned int significandMSB()
const;
482 void zeroSignificand();
484 bool isSignificandAllOnes()
const;
486 bool isSignificandAllZeros()
const;
503 bool convertFromStringSpecials(
StringRef str);
515 char *convertNormalToHexString(
char *,
unsigned int,
bool,
522 APInt convertHalfAPFloatToAPInt()
const;
523 APInt convertFloatAPFloatToAPInt()
const;
524 APInt convertDoubleAPFloatToAPInt()
const;
525 APInt convertQuadrupleAPFloatToAPInt()
const;
526 APInt convertF80LongDoubleAPFloatToAPInt()
const;
527 APInt convertPPCDoubleDoubleAPFloatToAPInt()
const;
529 void initFromHalfAPInt(
const APInt &api);
530 void initFromFloatAPInt(
const APInt &api);
531 void initFromDoubleAPInt(
const APInt &api);
532 void initFromQuadrupleAPInt(
const APInt &api);
533 void initFromF80LongDoubleAPInt(
const APInt &api);
534 void initFromPPCDoubleDoubleAPInt(
const APInt &api);
538 void freeSignificand();
562 unsigned int sign : 1;
577 std::unique_ptr<APFloat[]> Floats;
624 bool isNegative()
const;
626 void makeInf(
bool Neg);
627 void makeZero(
bool Neg);
628 void makeLargest(
bool Neg);
629 void makeSmallest(
bool Neg);
630 void makeSmallestNormalized(
bool Neg);
631 void makeNaN(
bool SNaN,
bool Neg,
const APInt *fill);
635 APInt bitcastToAPInt()
const;
641 bool *IsExact)
const;
644 unsigned int InputSize,
bool IsSigned,
647 unsigned int InputSize,
bool IsSigned,
649 unsigned int convertToHexString(
char *DST,
unsigned int HexDigits,
652 bool isDenormal()
const;
653 bool isSmallest()
const;
654 bool isLargest()
const;
655 bool isInteger()
const;
658 unsigned FormatMaxPadding,
bool TruncateZero =
true)
const;
660 bool getExactInverse(
APFloat *inv)
const;
678 static_assert(std::is_standard_layout<IEEEFloat>::value,
"");
683 DoubleAPFloat Double;
686 explicit Storage(DoubleAPFloat F,
const fltSemantics &S)
687 : Double(std::move(F)) {
691 template <
typename... ArgTypes>
693 if (usesLayout<IEEEFloat>(Semantics)) {
694 new (&
IEEE) IEEEFloat(Semantics, std::forward<ArgTypes>(
Args)...);
697 if (usesLayout<DoubleAPFloat>(Semantics)) {
698 new (&Double) DoubleAPFloat(Semantics, std::forward<ArgTypes>(
Args)...);
705 if (usesLayout<IEEEFloat>(*semantics)) {
709 if (usesLayout<DoubleAPFloat>(*semantics)) {
710 Double.~DoubleAPFloat();
716 Storage(
const Storage &RHS) {
717 if (usesLayout<IEEEFloat>(*RHS.semantics)) {
718 new (
this) IEEEFloat(RHS.IEEE);
721 if (usesLayout<DoubleAPFloat>(*RHS.semantics)) {
722 new (
this) DoubleAPFloat(RHS.Double);
728 Storage(Storage &&RHS) {
729 if (usesLayout<IEEEFloat>(*RHS.semantics)) {
730 new (
this) IEEEFloat(std::move(RHS.IEEE));
733 if (usesLayout<DoubleAPFloat>(*RHS.semantics)) {
734 new (
this) DoubleAPFloat(std::move(RHS.Double));
740 Storage &operator=(
const Storage &RHS) {
741 if (usesLayout<IEEEFloat>(*semantics) &&
742 usesLayout<IEEEFloat>(*RHS.semantics)) {
744 }
else if (usesLayout<DoubleAPFloat>(*semantics) &&
745 usesLayout<DoubleAPFloat>(*RHS.semantics)) {
747 }
else if (
this != &RHS) {
749 new (
this) Storage(RHS);
754 Storage &operator=(Storage &&RHS) {
755 if (usesLayout<IEEEFloat>(*semantics) &&
756 usesLayout<IEEEFloat>(*RHS.semantics)) {
757 IEEE = std::move(RHS.IEEE);
758 }
else if (usesLayout<DoubleAPFloat>(*semantics) &&
759 usesLayout<DoubleAPFloat>(*RHS.semantics)) {
760 Double = std::move(RHS.Double);
761 }
else if (
this != &RHS) {
763 new (
this) Storage(std::move(RHS));
769 template <
typename T>
static bool usesLayout(
const fltSemantics &Semantics) {
770 static_assert(std::is_same<T, IEEEFloat>::value ||
771 std::is_same<T, DoubleAPFloat>::value,
"");
772 if (std::is_same<T, DoubleAPFloat>::value) {
778 IEEEFloat &getIEEE() {
779 if (usesLayout<IEEEFloat>(*U.semantics))
781 if (usesLayout<DoubleAPFloat>(*U.semantics))
782 return U.Double.getFirst().U.IEEE;
786 const IEEEFloat &getIEEE()
const {
787 if (usesLayout<IEEEFloat>(*U.semantics))
789 if (usesLayout<DoubleAPFloat>(*U.semantics))
790 return U.Double.getFirst().U.IEEE;
798 void makeNaN(
bool SNaN,
bool Neg,
const APInt *fill) {
802 void makeLargest(
bool Neg) {
806 void makeSmallest(
bool Neg) {
810 void makeSmallestNormalized(
bool Neg) {
823 : U(std::move(F), S) {}
827 "Should only compare APFloats with the same semantics");
828 if (usesLayout<IEEEFloat>(getSemantics()))
829 return U.IEEE.compareAbsoluteValue(RHS.U.IEEE);
830 if (usesLayout<DoubleAPFloat>(getSemantics()))
831 return U.Double.compareAbsoluteValue(RHS.U.Double);
857 Val.makeZero(Negative);
866 Val.makeInf(Negative);
876 uint64_t payload = 0) {
878 APInt intPayload(64, payload);
879 return getQNaN(Sem, Negative, &intPayload);
881 return getQNaN(Sem, Negative,
nullptr);
887 const APInt *payload =
nullptr) {
889 Val.makeNaN(
false, Negative, payload);
895 const APInt *payload =
nullptr) {
897 Val.makeNaN(
true, Negative, payload);
906 Val.makeLargest(Negative);
916 Val.makeSmallest(Negative);
925 bool Negative =
false) {
927 Val.makeSmallestNormalized(Negative);
935 static APFloat getAllOnesValue(
unsigned BitWidth,
bool isIEEE =
false);
943 "Should only call on two APFloats with the same semantics");
944 if (usesLayout<IEEEFloat>(getSemantics()))
945 return U.IEEE.add(RHS.U.IEEE, RM);
946 if (usesLayout<DoubleAPFloat>(getSemantics()))
947 return U.Double.add(RHS.U.Double, RM);
952 "Should only call on two APFloats with the same semantics");
953 if (usesLayout<IEEEFloat>(getSemantics()))
954 return U.IEEE.subtract(RHS.U.IEEE, RM);
955 if (usesLayout<DoubleAPFloat>(getSemantics()))
956 return U.Double.subtract(RHS.U.Double, RM);
961 "Should only call on two APFloats with the same semantics");
962 if (usesLayout<IEEEFloat>(getSemantics()))
963 return U.IEEE.multiply(RHS.U.IEEE, RM);
964 if (usesLayout<DoubleAPFloat>(getSemantics()))
965 return U.Double.multiply(RHS.U.Double, RM);
970 "Should only call on two APFloats with the same semantics");
971 if (usesLayout<IEEEFloat>(getSemantics()))
972 return U.IEEE.divide(RHS.U.IEEE, RM);
973 if (usesLayout<DoubleAPFloat>(getSemantics()))
974 return U.Double.divide(RHS.U.Double, RM);
979 "Should only call on two APFloats with the same semantics");
980 if (usesLayout<IEEEFloat>(getSemantics()))
981 return U.IEEE.remainder(RHS.U.IEEE);
982 if (usesLayout<DoubleAPFloat>(getSemantics()))
983 return U.Double.remainder(RHS.U.Double);
988 "Should only call on two APFloats with the same semantics");
989 if (usesLayout<IEEEFloat>(getSemantics()))
990 return U.IEEE.mod(RHS.U.IEEE);
991 if (usesLayout<DoubleAPFloat>(getSemantics()))
992 return U.Double.mod(RHS.U.Double);
998 "Should only call on APFloats with the same semantics");
1000 "Should only call on APFloats with the same semantics");
1001 if (usesLayout<IEEEFloat>(getSemantics()))
1002 return U.IEEE.fusedMultiplyAdd(Multiplicand.U.IEEE, Addend.U.IEEE, RM);
1003 if (usesLayout<DoubleAPFloat>(getSemantics()))
1004 return U.Double.fusedMultiplyAdd(Multiplicand.U.Double, Addend.U.Double,
1071 bool *IsExact)
const {
1073 convertToInteger(Input, Width, IsSigned, RM, IsExact));
1076 bool *IsExact)
const;
1082 unsigned int InputSize,
bool IsSigned,
1085 convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM));
1088 unsigned int InputSize,
bool IsSigned,
1091 convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM));
1104 "Should only compare APFloats with the same semantics");
1105 if (usesLayout<IEEEFloat>(getSemantics()))
1106 return U.IEEE.compare(RHS.U.IEEE);
1107 if (usesLayout<DoubleAPFloat>(getSemantics()))
1108 return U.Double.compare(RHS.U.Double);
1115 if (usesLayout<IEEEFloat>(getSemantics()))
1116 return U.IEEE.bitwiseIsEqual(RHS.U.IEEE);
1117 if (usesLayout<DoubleAPFloat>(getSemantics()))
1118 return U.Double.bitwiseIsEqual(RHS.U.Double);
1134 return bitwiseIsEqual(Tmp);
1140 convertToHexString(DST, HexDigits, UpperCase, RM));
1151 bool isNormal()
const {
return !isDenormal() && isFiniteNonZero(); }
1152 bool isFinite()
const {
return !isNaN() && !isInfinity(); }
1168 unsigned FormatMaxPadding = 3,
bool TruncateZero =
true)
const {
1170 toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero));
1194 if (APFloat::usesLayout<detail::IEEEFloat>(X.
getSemantics()))
1196 if (APFloat::usesLayout<detail::DoubleAPFloat>(X.
getSemantics()))
1206 if (APFloat::usesLayout<detail::IEEEFloat>(X.
getSemantics()))
1208 if (APFloat::usesLayout<detail::DoubleAPFloat>(X.
getSemantics()))
1274 #undef APFLOAT_DISPATCH_ON_SEMANTICS 1275 #endif // LLVM_ADT_APFLOAT_H friend int ilogb(const APFloat &Arg)
opStatus roundToIntegral(roundingMode RM)
static APFloat getNaN(const fltSemantics &Sem, bool Negative=false, uint64_t payload=0)
Factory for NaN values.
static const fltSemantics & IEEEquad() LLVM_READNONE
fltCategory
Category of internally-represented number.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM)
APFloat(const fltSemantics &Semantics)
This class represents lattice values for constants.
fltCategory getCategory() const
float convertToFloat() const
static unsigned getSizeInBits(const fltSemantics &Sem)
Returns the size of the floating point number (in bits) in the given semantics.
const fltSemantics & getSemantics() const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
LLVM_READONLY APFloat maximum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2018 maximum semantics.
opStatus next(bool nextDown)
APFloat(const fltSemantics &Semantics, const APInt &I)
bool isNegative() const
IEEE-754R isSignMinus: Returns true if and only if the current value is negative. ...
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
opStatus convertFromSignExtendedInteger(const integerPart *Input, unsigned int InputSize, bool IsSigned, roundingMode RM)
opStatus divide(const APFloat &RHS, roundingMode RM)
static APFloat getSmallest(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) finite number in the given semantics.
std::string toString(Error E)
Write all error messages (if any) in E to a string.
roundingMode
IEEE-754R 4.3: Rounding-direction attributes.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
APFloat operator*(const APFloat &RHS) const
Multiply two APFloats, rounding ties to the nearest even.
LLVM_READONLY APFloat minimum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2018 minimum semantics.
APFloat operator-(const APFloat &RHS) const
Subtract two APFloats, rounding ties to the nearest even.
static ExponentType semanticsMaxExponent(const fltSemantics &)
This file implements a class to represent arbitrary precision integral constant values and operations...
div rem Hoist decompose integer division and remainder
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
static unsigned int semanticsSizeInBits(const fltSemantics &)
void toString(SmallVectorImpl< char > &Str, unsigned FormatPrecision=0, unsigned FormatMaxPadding=3, bool TruncateZero=true) const
bool isNaN() const
Returns true if and only if the float is a quiet or signaling NaN.
hash_code hash_value(const APFloat &Arg)
See friend declarations above.
opStatus subtract(const APFloat &RHS, roundingMode RM)
cmpResult
IEEE-754R 5.11: Floating Point Comparison Relations.
static const fltSemantics & IEEEdouble() LLVM_READNONE
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
static ExponentType semanticsMinExponent(const fltSemantics &)
uninitializedTag
Convenience enum used to construct an uninitialized APFloat.
static const unsigned integerPartWidth
IlogbErrorKinds
Enumeration of ilogb error results.
static APFloat copySign(APFloat Value, const APFloat &Sign)
A static helper to produce a copy of an APFloat value with its sign copied from some other APFloat...
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
fltCategory getCategory() const
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
double convertToDouble() const
APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)
bool isExactlyValue(double V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
opStatus multiply(const APFloat &RHS, roundingMode RM)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
APFloat operator+(const APFloat &RHS) const
Add two APFloats, rounding ties to the nearest even.
static const fltSemantics & x87DoubleExtended() LLVM_READNONE
APFloat operator/(const APFloat &RHS) const
Divide the first APFloat by the second, rounding ties to the nearest even.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void copySign(const APFloat &RHS)
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE maxNum semantics.
signed short ExponentType
A signed type to represent a floating point numbers unbiased exponent.
bool needsCleanup() const
static const fltSemantics & IEEEsingle() LLVM_READNONE
DoubleAPFloat & operator=(DoubleAPFloat &&RHS)
static const fltSemantics & IEEEhalf() LLVM_READNONE
bool isFiniteNonZero() const
lostFraction
Enum that represents what fraction of the LSB truncated bits of an fp number represent.
bool isFinite() const
Returns true if and only if the current value is zero, subnormal, or normal.
bool isFiniteNonZero() const
#define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL)
APFloat neg(APFloat X)
Returns the negated value of the argument.
APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM)
Equivalent of C standard library function.
bool needsCleanup() const
static unsigned int semanticsPrecision(const fltSemantics &)
const fltSemantics & getSemantics() const
APInt::WordType integerPart
bool getExactInverse(APFloat *inv) const
Class for arbitrary precision integers.
static APFloat getSNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)
Factory for SNaN values.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringRef > StandardNames)
Initialize the set of available library functions based on the specified target triple.
const APFloat & getFirst() const
bool isZero() const
Returns true if and only if the float is plus or minus zero.
opStatus mod(const APFloat &RHS)
An opaque object representing a hash code.
unsigned int convertToHexString(char *DST, unsigned int HexDigits, bool UpperCase, roundingMode RM) const
amdgpu Simplify well known AMD library false Value Value * Arg
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
opStatus add(const APFloat &RHS, roundingMode RM)
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
opStatus
IEEE-754R 7: Default exception handling.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
static const fltSemantics & Bogus() LLVM_READNONE
A Pseudo fltsemantic used to construct APFloats that cannot conflict with anything real...
static APFloat getLargest(const fltSemantics &Sem, bool Negative=false)
Returns the largest finite number in the given semantics.
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
const APFloat & getSecond() const
int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale)
Compare two scaled numbers.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
opStatus fusedMultiplyAdd(const APFloat &Multiplicand, const APFloat &Addend, roundingMode RM)
opStatus remainder(const APFloat &RHS)
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
LLVM Value Representation.
bool needsCleanup() const
Returns whether this instance allocated memory.
bool bitwiseIsEqual(const APFloat &RHS) const
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
opStatus convertFromZeroExtendedInteger(const integerPart *Input, unsigned int InputSize, bool IsSigned, roundingMode RM)
APInt bitcastToAPInt() const
bool operator==(uint64_t V1, const APInt &V2)
APFloat(const fltSemantics &Semantics, integerPart I)
bool isInfinity() const
IEEE-754R isInfinite(): Returns true if and only if the float is infinity.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
static APFloat getQNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)
Factory for QNaN values.
APFloat(const fltSemantics &Semantics, uninitializedTag)
LLVM_READONLY APFloat minnum(const APFloat &A, const APFloat &B)
Implements IEEE minNum semantics.
int ilogb(const IEEEFloat &Arg)
cmpResult compare(const APFloat &RHS) const
bool isNormal() const
IEEE-754R isNormal: Returns true if and only if the current value is normal.