https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/123374
None >From f595dfc75253a3ca80196f6e7f5fb38ca6d82376 Mon Sep 17 00:00:00 2001 From: Matthias Springer <msprin...@nvidia.com> Date: Fri, 17 Jan 2025 18:08:14 +0100 Subject: [PATCH] [experiment] Make `fltSemantics` public --- .../bugprone/NarrowingConversionsCheck.cpp | 4 +- clang/include/clang/AST/OptionalDiagnostic.h | 2 +- .../CIR/Interfaces/CIRFPTypeInterface.td | 4 +- clang/lib/AST/ByteCode/Floating.h | 6 +- clang/lib/CodeGen/CGExprComplex.cpp | 4 +- clang/lib/CodeGen/PatternInit.cpp | 4 +- clang/lib/Sema/SemaChecking.cpp | 6 +- clang/lib/Sema/SemaExpr.cpp | 8 +- .../Checkers/ConversionChecker.cpp | 2 +- flang/lib/Optimizer/Dialect/FIRAttr.cpp | 2 +- .../TypeSystem/Clang/TypeSystemClang.cpp | 3 +- llvm/include/llvm/ADT/APFloat.h | 126 +++- llvm/lib/Analysis/ValueTracking.cpp | 2 +- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 10 +- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 12 +- llvm/lib/Support/APFloat.cpp | 538 +++++++----------- llvm/lib/Support/Z3Solver.cpp | 14 +- .../Target/AArch64/AArch64ISelLowering.cpp | 2 +- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 6 +- llvm/lib/Target/X86/X86ISelLowering.cpp | 2 +- .../InstCombine/InstCombineCasts.cpp | 2 +- .../InstCombine/InstructionCombining.cpp | 2 +- llvm/lib/Transforms/Scalar/Float2Int.cpp | 4 +- .../Transforms/Utils/FunctionComparator.cpp | 12 +- llvm/unittests/ADT/APFloatTest.cpp | 20 +- llvm/unittests/IR/ConstantFPRangeTest.cpp | 10 +- mlir/lib/AsmParser/Parser.cpp | 2 +- .../Conversion/TosaToLinalg/TosaToLinalg.cpp | 2 +- mlir/lib/IR/BuiltinTypeInterfaces.cpp | 4 +- 29 files changed, 399 insertions(+), 416 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp index bafcd402ca8510..aa868cfe68c1ae 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp @@ -244,8 +244,8 @@ struct IntegerRange { static IntegerRange createFromType(const ASTContext &Context, const BuiltinType &T) { if (T.isFloatingPoint()) { - unsigned PrecisionBits = llvm::APFloatBase::semanticsPrecision( - Context.getFloatTypeSemantics(T.desugar())); + unsigned PrecisionBits = + Context.getFloatTypeSemantics(T.desugar()).precision; // Contrary to two's complement integer, floating point values are // symmetric and have the same number of positive and negative values. // The range of valid integers for a floating point value is: diff --git a/clang/include/clang/AST/OptionalDiagnostic.h b/clang/include/clang/AST/OptionalDiagnostic.h index c9a2d19f4ebce0..784a006072be37 100644 --- a/clang/include/clang/AST/OptionalDiagnostic.h +++ b/clang/include/clang/AST/OptionalDiagnostic.h @@ -54,7 +54,7 @@ class OptionalDiagnostic { // APFloat::toString would automatically print the shortest // representation which rounds to the correct value, but it's a bit // tricky to implement. Could use std::to_chars. - unsigned precision = llvm::APFloat::semanticsPrecision(F.getSemantics()); + unsigned precision = F.getSemantics().precision; precision = (precision * 59 + 195) / 196; SmallVector<char, 32> Buffer; F.toString(Buffer, precision); diff --git a/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td index 973851b61444f0..cec3dc615d1d43 100644 --- a/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td +++ b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td @@ -30,7 +30,7 @@ def CIRFPTypeInterface : TypeInterface<"CIRFPTypeInterface"> { /*args=*/(ins), /*methodBody=*/"", /*defaultImplementation=*/[{ - return llvm::APFloat::semanticsSizeInBits($_type.getFloatSemantics()); + return $_type.getFloatSemantics().sizeInBits; }] >, InterfaceMethod<[{ @@ -41,7 +41,7 @@ def CIRFPTypeInterface : TypeInterface<"CIRFPTypeInterface"> { /*args=*/(ins), /*methodBody=*/"", /*defaultImplementation=*/[{ - return llvm::APFloat::semanticsPrecision($_type.getFloatSemantics()); + return $_type.getFloatSemantics().precision; }] >, InterfaceMethod<[{ diff --git a/clang/lib/AST/ByteCode/Floating.h b/clang/lib/AST/ByteCode/Floating.h index 3a874fc6f0b412..123d546c5fdbd9 100644 --- a/clang/lib/AST/ByteCode/Floating.h +++ b/clang/lib/AST/ByteCode/Floating.h @@ -83,7 +83,7 @@ class Floating final { return NameStr; } - unsigned bitWidth() const { return F.semanticsSizeInBits(F.getSemantics()); } + unsigned bitWidth() const { return F.getSemantics().sizeInBits; } bool isSigned() const { return true; } bool isNegative() const { return F.isNegative(); } @@ -128,7 +128,7 @@ class Floating final { static Floating bitcastFromMemory(const std::byte *Buff, const llvm::fltSemantics &Sem) { - size_t Size = APFloat::semanticsSizeInBits(Sem); + size_t Size = Sem.sizeInBits; llvm::APInt API(Size, true); llvm::LoadIntFromMemory(API, (const uint8_t *)Buff, Size / 8); @@ -143,7 +143,7 @@ class Floating final { // === Serialization support === size_t bytesToSerialize() const { return sizeof(llvm::fltSemantics *) + - (APFloat::semanticsSizeInBits(F.getSemantics()) / 8); + (F.getSemantics().sizeInBits / 8); } void serialize(std::byte *Buff) const { diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index ac31dff11b585e..0f0bba6fe46f3e 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -302,8 +302,8 @@ class ComplexExprEmitter // In terms of exponent it gives this formula: // (SmallerType.LargestFiniteVal * SmallerType.LargestFiniteVal // doubles the exponent of SmallerType.LargestFiniteVal) - if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <= - llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) { + if (ElementTypeSemantics.maxExponent * 2 + 1 <= + HigherElementTypeSemantics.maxExponent) { FPHasBeenPromoted = true; return Ctx.getComplexType(HigherElementType); } else { diff --git a/clang/lib/CodeGen/PatternInit.cpp b/clang/lib/CodeGen/PatternInit.cpp index 4400bc4436882f..d8e8c4d62425fb 100644 --- a/clang/lib/CodeGen/PatternInit.cpp +++ b/clang/lib/CodeGen/PatternInit.cpp @@ -52,8 +52,8 @@ llvm::Constant *clang::CodeGen::initializationPatternFor(CodeGenModule &CGM, return llvm::ConstantExpr::getIntToPtr(Int, PtrTy); } if (Ty->isFPOrFPVectorTy()) { - unsigned BitWidth = llvm::APFloat::semanticsSizeInBits( - Ty->getScalarType()->getFltSemantics()); + unsigned BitWidth = + Ty->getScalarType()->getFltSemantics().sizeInBits; llvm::APInt Payload(64, NaNPayload); if (BitWidth >= 64) Payload = llvm::APInt::getSplat(BitWidth, Payload); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 881907ac311a30..42e397a51ca4f5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -10772,7 +10772,7 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, // would automatically print the shortest representation, but it's a bit // tricky to implement. SmallString<16> PrettySourceValue; - unsigned precision = llvm::APFloat::semanticsPrecision(Value.getSemantics()); + unsigned precision = Value.getSemantics().precision; precision = (precision * 59 + 195) / 196; Value.toString(PrettySourceValue, precision); @@ -11350,8 +11350,8 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, // Determine the number of precision bits in the // target floating point type. - unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision( - Context.getFloatTypeSemantics(QualType(TargetBT, 0))); + unsigned int TargetPrecision = + Context.getFloatTypeSemantics(QualType(TargetBT, 0)).precision; if (SourcePrecision > 0 && TargetPrecision > 0 && SourcePrecision > TargetPrecision) { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ae40895980d90a..a7db950644c2bf 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -10035,8 +10035,8 @@ static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int, // Reject types that cannot be fully encoded into the mantissa of // the float. Bits = S.Context.getTypeSize(IntTy); - unsigned FloatPrec = llvm::APFloat::semanticsPrecision( - S.Context.getFloatTypeSemantics(FloatTy)); + unsigned FloatPrec = + S.Context.getFloatTypeSemantics(FloatTy).precision; if (Bits > FloatPrec) return true; } @@ -15250,8 +15250,8 @@ static void DetectPrecisionLossInComplexDivision(Sema &S, SourceLocation OpLoc, Ctx.getFloatTypeSemantics(ElementType); const llvm::fltSemantics &HigherElementTypeSemantics = Ctx.getFloatTypeSemantics(HigherElementType); - if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 > - llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) { + if (ElementTypeSemantics.maxExponent * 2 + 1 > + HigherElementTypeSemantics.maxExponent) { // Retain the location of the first use of higher precision type. if (!S.LocationOfExcessPrecisionNotSatisfied.isValid()) S.LocationOfExcessPrecisionNotSatisfied = OpLoc; diff --git a/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp index eca8d3cc072292..dcbe0c57e58be5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp @@ -154,7 +154,7 @@ bool ConversionChecker::isLossOfPrecision(const ImplicitCastExpr *Cast, if (isFloat) { const llvm::fltSemantics &Sema = AC.getFloatTypeSemantics(DestType); - RepresentsUntilExp = llvm::APFloat::semanticsPrecision(Sema); + RepresentsUntilExp = Sema.precision; } else { RepresentsUntilExp = AC.getIntWidth(DestType); if (RepresentsUntilExp == 1) { diff --git a/flang/lib/Optimizer/Dialect/FIRAttr.cpp b/flang/lib/Optimizer/Dialect/FIRAttr.cpp index 4c78e223b41785..65d491c25cb0b4 100644 --- a/flang/lib/Optimizer/Dialect/FIRAttr.cpp +++ b/flang/lib/Optimizer/Dialect/FIRAttr.cpp @@ -171,7 +171,7 @@ static mlir::Attribute parseFirRealAttr(FIROpsDialect *dialect, return {}; } const llvm::fltSemantics &sem = kindMap.getFloatSemantics(kind); - unsigned int numBits = llvm::APFloat::semanticsSizeInBits(sem); + unsigned int numBits = sem.sizeInBits; auto bits = llvm::APInt(numBits, hex.drop_front(), 16); value = llvm::APFloat(sem, bits); } diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 47051f2e68090f..d906940bce9312 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -4745,8 +4745,7 @@ TypeSystemClang::GetFloatTypeSemantics(size_t byte_size) { else if (bit_size == ast.getTypeSize(ast.DoubleTy)) return ast.getFloatTypeSemantics(ast.DoubleTy); else if (bit_size == ast.getTypeSize(ast.LongDoubleTy) || - bit_size == llvm::APFloat::semanticsSizeInBits( - ast.getFloatTypeSemantics(ast.LongDoubleTy))) + bit_size == ast.getFloatTypeSemantics(ast.LongDoubleTy).sizeInBits) return ast.getFloatTypeSemantics(ast.LongDoubleTy); else if (bit_size == ast.getTypeSize(ast.HalfTy)) return ast.getFloatTypeSemantics(ast.HalfTy); diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h index 9792749230cbf9..f907f3342a13a9 100644 --- a/llvm/include/llvm/ADT/APFloat.h +++ b/llvm/include/llvm/ADT/APFloat.h @@ -39,6 +39,10 @@ class StringRef; class APFloat; class raw_ostream; +namespace detail { +class IEEEFloat; +} // namespace detail + template <typename T> class Expected; template <typename T> class SmallVectorImpl; @@ -344,16 +348,6 @@ struct APFloatBase { IEK_Inf = INT_MAX }; - static unsigned int semanticsPrecision(const fltSemantics &); - static ExponentType semanticsMinExponent(const fltSemantics &); - static ExponentType semanticsMaxExponent(const fltSemantics &); - static unsigned int semanticsSizeInBits(const fltSemantics &); - static unsigned int semanticsIntSizeInBits(const fltSemantics&, bool); - static bool semanticsHasZero(const fltSemantics &); - static bool semanticsHasSignedRepr(const fltSemantics &); - static bool semanticsHasInf(const fltSemantics &); - static bool semanticsHasNaN(const fltSemantics &); - // Returns true if any number described by \p Src can be precisely represented // by a normal (not subnormal) value in \p Dst. static bool isRepresentableAsNormalIn(const fltSemantics &Src, @@ -364,6 +358,118 @@ struct APFloatBase { static unsigned getSizeInBits(const fltSemantics &Sem); }; +// How the nonfinite values Inf and NaN are represented. +enum class fltNonfiniteBehavior { + // Represents standard IEEE 754 behavior. A value is nonfinite if the + // exponent field is all 1s. In such cases, a value is Inf if the + // significand bits are all zero, and NaN otherwise + IEEE754, + + // This behavior is present in the Float8ExMyFN* types (Float8E4M3FN, + // Float8E5M2FNUZ, Float8E4M3FNUZ, and Float8E4M3B11FNUZ). There is no + // representation for Inf, and operations that would ordinarily produce Inf + // produce NaN instead. + // The details of the NaN representation(s) in this form are determined by the + // `fltNanEncoding` enum. We treat all NaNs as quiet, as the available + // encodings do not distinguish between signalling and quiet NaN. + NanOnly, + + // This behavior is present in Float6E3M2FN, Float6E2M3FN, and + // Float4E2M1FN types, which do not support Inf or NaN values. + FiniteOnly, +}; + +// How NaN values are represented. This is curently only used in combination +// with fltNonfiniteBehavior::NanOnly, and using a variant other than IEEE +// while having IEEE non-finite behavior is liable to lead to unexpected +// results. +enum class fltNanEncoding { + // Represents the standard IEEE behavior where a value is NaN if its + // exponent is all 1s and the significand is non-zero. + IEEE, + + // Represents the behavior in the Float8E4M3FN floating point type where NaN + // is represented by having the exponent and mantissa set to all 1s. + // This behavior matches the FP8 E4M3 type described in + // https://arxiv.org/abs/2209.05433. We treat both signed and unsigned NaNs + // as non-signalling, although the paper does not state whether the NaN + // values are signalling or not. + AllOnes, + + // Represents the behavior in Float8E{5,4}E{2,3}FNUZ floating point types + // where NaN is represented by a sign bit of 1 and all 0s in the exponent + // and mantissa (i.e. the negative zero encoding in a IEEE float). Since + // there is only one NaN value, it is treated as quiet NaN. This matches the + // behavior described in https://arxiv.org/abs/2206.02915 . + NegativeZero, +}; + +struct SupportedFltSemantics; + +/* Represents floating point arithmetic semantics. */ +struct fltSemantics { + private: + friend struct SupportedFltSemantics; + friend struct APFloatBase; + friend class detail::IEEEFloat; + + constexpr fltSemantics(APFloatBase::ExponentType maxExponent, APFloatBase::ExponentType minExponent, + unsigned int precision, unsigned int sizeInBits, + fltNonfiniteBehavior nonFiniteBehavior = fltNonfiniteBehavior::IEEE754, + fltNanEncoding nanEncoding = fltNanEncoding::IEEE, + bool hasZero = false, bool hasSignedRepr = true) + : maxExponent(maxExponent), minExponent(minExponent), + precision(precision), sizeInBits(sizeInBits), + nonFiniteBehavior(nonFiniteBehavior), nanEncoding(nanEncoding), + hasZero(hasZero), hasSignedRepr(hasSignedRepr) {} + + fltSemantics() {} + + public: + constexpr bool hasInf() const { + return nonFiniteBehavior == fltNonfiniteBehavior::IEEE754; + } + + constexpr unsigned int intSizeInBits(bool isSigned) const { + // The max FP value is pow(2, MaxExponent) * (1 + MaxFraction), so we need + // at least one more bit than the MaxExponent to hold the max FP value. + unsigned int MinBitWidth = maxExponent + 1; + // Extra sign bit needed. + if (isSigned) + ++MinBitWidth; + return MinBitWidth; + } + + constexpr bool hasNaN() const { + return nonFiniteBehavior != fltNonfiniteBehavior::FiniteOnly; + } + + /* The largest E such that 2^E is representable; this matches the + definition of IEEE 754. */ + APFloatBase::ExponentType maxExponent; + + /* The smallest E such that 2^E is a normalized number; this + matches the definition of IEEE 754. */ + APFloatBase::ExponentType minExponent; + + /* Number of bits in the significand. This includes the integer + bit. */ + unsigned int precision; + + /* Number of bits actually used in the semantics. */ + unsigned int sizeInBits; + + fltNonfiniteBehavior nonFiniteBehavior = fltNonfiniteBehavior::IEEE754; + + fltNanEncoding nanEncoding = fltNanEncoding::IEEE; + + /* Whether this semantics has an encoding for Zero */ + bool hasZero = true; + + /* Whether this semantics can represent signed values */ + bool hasSignedRepr = true; +}; + namespace detail { using integerPart = APFloatBase::integerPart; diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 6e2f0ebde9bb6c..c5610d8573af10 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -5591,7 +5591,7 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, const fltSemantics &Flt = II->getType()->getScalarType()->getFltSemantics(); - unsigned Precision = APFloat::semanticsPrecision(Flt); + unsigned Precision = Flt.precision; const Value *ExpArg = II->getArgOperand(1); ConstantRange ExpRange = computeConstantRange( ExpArg, true, Q.IIQ.UseInstrInfo, Q.AC, Q.CxtI, Q.DT, Depth + 1); diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index de7fb21f5903e3..ffedf359446c5a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -5690,7 +5690,7 @@ static SDValue isSaturatingMinMax(SDValue N0, SDValue N1, SDValue N2, Type *InputTy = FPVT.getTypeForEVT(*DAG.getContext()); const fltSemantics &Semantics = InputTy->getFltSemantics(); uint32_t MinBitWidth = - APFloatBase::semanticsIntSizeInBits(Semantics, /*isSigned*/ true); + Semantics.intSizeInBits(/*isSigned*/ true); if (IntVT.getSizeInBits() >= MinBitWidth) { Unsigned = true; BW = PowerOf2Ceil(MinBitWidth); @@ -17319,12 +17319,12 @@ SDValue DAGCombiner::combineFMulOrFDivWithIntPow2(SDNode *N) { // FDiv by pow2 will only decrease exponent. int MaxExp = N->getOpcode() == ISD::FDIV ? CurExp : (CurExp + MaxExpChange); - if (MinExp <= APFloat::semanticsMinExponent(APF.getSemantics()) || - MaxExp >= APFloat::semanticsMaxExponent(APF.getSemantics())) + if (MinExp <= APF.getSemantics().minExponent || + MaxExp >= APF.getSemantics().maxExponent) return false; // Finally make sure we actually know the mantissa for the float type. - int ThisMantissa = APFloat::semanticsPrecision(APF.getSemantics()) - 1; + int ThisMantissa = APF.getSemantics().precision - 1; if (!Mantissa) Mantissa = ThisMantissa; @@ -18254,7 +18254,7 @@ static SDValue FoldIntToFPToInt(SDNode *N, const SDLoc &DL, SelectionDAG &DAG) { // We can only fold away the float conversion if the input range can be // represented exactly in the float range. - if (APFloat::semanticsPrecision(Sem) >= ActualSize) { + if (Sem.precision >= ActualSize) { if (VT.getScalarSizeInBits() > SrcVT.getScalarSizeInBits()) { unsigned ExtOp = IsInputSigned && IsOutputSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index c6475f02199033..ab5ac7cf8b8b7e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2327,9 +2327,9 @@ SDValue SelectionDAGLegalize::expandLdexp(SDNode *Node) const { TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), ExpVT); const fltSemantics &FltSem = VT.getFltSemantics(); - const APFloat::ExponentType MaxExpVal = APFloat::semanticsMaxExponent(FltSem); - const APFloat::ExponentType MinExpVal = APFloat::semanticsMinExponent(FltSem); - const int Precision = APFloat::semanticsPrecision(FltSem); + const APFloat::ExponentType MaxExpVal = FltSem.maxExponent; + const APFloat::ExponentType MinExpVal = FltSem.minExponent; + const int Precision = FltSem.precision; const SDValue MaxExp = DAG.getSignedConstant(MaxExpVal, dl, ExpVT); const SDValue MinExp = DAG.getSignedConstant(MinExpVal, dl, ExpVT); @@ -2426,8 +2426,8 @@ SDValue SelectionDAGLegalize::expandFrexp(SDNode *Node) const { return SDValue(); const fltSemantics &FltSem = VT.getFltSemantics(); - const APFloat::ExponentType MinExpVal = APFloat::semanticsMinExponent(FltSem); - const unsigned Precision = APFloat::semanticsPrecision(FltSem); + const APFloat::ExponentType MinExpVal = FltSem.minExponent; + const unsigned Precision = FltSem.precision; const unsigned BitSize = VT.getScalarSizeInBits(); // TODO: Could introduce control flow and skip over the denormal handling. @@ -2687,7 +2687,7 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(SDNode *Node, // The following optimization is valid only if every value in SrcVT (when // treated as signed) is representable in DestVT. Check that the mantissa // size of DestVT is >= than the number of bits in SrcVT -1. - assert(APFloat::semanticsPrecision(DestVT.getFltSemantics()) >= + assert(DestVT.getFltSemantics().precision >= SrcVT.getSizeInBits() - 1 && "Cannot perform lossless SINT_TO_FP!"); diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp index b0d92ae37fe8f6..8888827513d884 100644 --- a/llvm/lib/Support/APFloat.cpp +++ b/llvm/lib/Support/APFloat.cpp @@ -53,80 +53,7 @@ static_assert(APFloatBase::integerPartWidth % 4 == 0, "Part width must be divisi namespace llvm { -// How the nonfinite values Inf and NaN are represented. -enum class fltNonfiniteBehavior { - // Represents standard IEEE 754 behavior. A value is nonfinite if the - // exponent field is all 1s. In such cases, a value is Inf if the - // significand bits are all zero, and NaN otherwise - IEEE754, - - // This behavior is present in the Float8ExMyFN* types (Float8E4M3FN, - // Float8E5M2FNUZ, Float8E4M3FNUZ, and Float8E4M3B11FNUZ). There is no - // representation for Inf, and operations that would ordinarily produce Inf - // produce NaN instead. - // The details of the NaN representation(s) in this form are determined by the - // `fltNanEncoding` enum. We treat all NaNs as quiet, as the available - // encodings do not distinguish between signalling and quiet NaN. - NanOnly, - - // This behavior is present in Float6E3M2FN, Float6E2M3FN, and - // Float4E2M1FN types, which do not support Inf or NaN values. - FiniteOnly, -}; - -// How NaN values are represented. This is curently only used in combination -// with fltNonfiniteBehavior::NanOnly, and using a variant other than IEEE -// while having IEEE non-finite behavior is liable to lead to unexpected -// results. -enum class fltNanEncoding { - // Represents the standard IEEE behavior where a value is NaN if its - // exponent is all 1s and the significand is non-zero. - IEEE, - - // Represents the behavior in the Float8E4M3FN floating point type where NaN - // is represented by having the exponent and mantissa set to all 1s. - // This behavior matches the FP8 E4M3 type described in - // https://arxiv.org/abs/2209.05433. We treat both signed and unsigned NaNs - // as non-signalling, although the paper does not state whether the NaN - // values are signalling or not. - AllOnes, - - // Represents the behavior in Float8E{5,4}E{2,3}FNUZ floating point types - // where NaN is represented by a sign bit of 1 and all 0s in the exponent - // and mantissa (i.e. the negative zero encoding in a IEEE float). Since - // there is only one NaN value, it is treated as quiet NaN. This matches the - // behavior described in https://arxiv.org/abs/2206.02915 . - NegativeZero, -}; - -/* Represents floating point arithmetic semantics. */ -struct fltSemantics { - /* The largest E such that 2^E is representable; this matches the - definition of IEEE 754. */ - APFloatBase::ExponentType maxExponent; - - /* The smallest E such that 2^E is a normalized number; this - matches the definition of IEEE 754. */ - APFloatBase::ExponentType minExponent; - - /* Number of bits in the significand. This includes the integer - bit. */ - unsigned int precision; - - /* Number of bits actually used in the semantics. */ - unsigned int sizeInBits; - - fltNonfiniteBehavior nonFiniteBehavior = fltNonfiniteBehavior::IEEE754; - - fltNanEncoding nanEncoding = fltNanEncoding::IEEE; - - /* Whether this semantics has an encoding for Zero */ - bool hasZero = true; - - /* Whether this semantics can represent signed values */ - bool hasSignedRepr = true; -}; - +struct SupportedFltSemantics { static constexpr fltSemantics semIEEEhalf = {15, -14, 11, 16}; static constexpr fltSemantics semBFloat = {127, -126, 8, 16}; static constexpr fltSemantics semIEEEsingle = {127, -126, 24, 32}; @@ -159,6 +86,7 @@ static constexpr fltSemantics semBogus = {0, 0, 0, 0}; static constexpr fltSemantics semPPCDoubleDouble = {-1, 0, 0, 128}; static constexpr fltSemantics semPPCDoubleDoubleLegacy = {1023, -1022 + 53, 53 + 53, 128}; +}; const llvm::fltSemantics &APFloatBase::EnumToSemantics(Semantics S) { switch (S) { @@ -252,35 +180,35 @@ APFloatBase::SemanticsToEnum(const llvm::fltSemantics &Sem) { llvm_unreachable("Unknown floating semantics"); } -const fltSemantics &APFloatBase::IEEEhalf() { return semIEEEhalf; } -const fltSemantics &APFloatBase::BFloat() { return semBFloat; } -const fltSemantics &APFloatBase::IEEEsingle() { return semIEEEsingle; } -const fltSemantics &APFloatBase::IEEEdouble() { return semIEEEdouble; } -const fltSemantics &APFloatBase::IEEEquad() { return semIEEEquad; } +const fltSemantics &APFloatBase::IEEEhalf() { return SupportedFltSemantics::semIEEEhalf; } +const fltSemantics &APFloatBase::BFloat() { return SupportedFltSemantics::semBFloat; } +const fltSemantics &APFloatBase::IEEEsingle() { return SupportedFltSemantics::semIEEEsingle; } +const fltSemantics &APFloatBase::IEEEdouble() { return SupportedFltSemantics::semIEEEdouble; } +const fltSemantics &APFloatBase::IEEEquad() { return SupportedFltSemantics::semIEEEquad; } const fltSemantics &APFloatBase::PPCDoubleDouble() { - return semPPCDoubleDouble; + return SupportedFltSemantics::semPPCDoubleDouble; } const fltSemantics &APFloatBase::PPCDoubleDoubleLegacy() { - return semPPCDoubleDoubleLegacy; + return SupportedFltSemantics::semPPCDoubleDoubleLegacy; } -const fltSemantics &APFloatBase::Float8E5M2() { return semFloat8E5M2; } -const fltSemantics &APFloatBase::Float8E5M2FNUZ() { return semFloat8E5M2FNUZ; } -const fltSemantics &APFloatBase::Float8E4M3() { return semFloat8E4M3; } -const fltSemantics &APFloatBase::Float8E4M3FN() { return semFloat8E4M3FN; } -const fltSemantics &APFloatBase::Float8E4M3FNUZ() { return semFloat8E4M3FNUZ; } +const fltSemantics &APFloatBase::Float8E5M2() { return SupportedFltSemantics::semFloat8E5M2; } +const fltSemantics &APFloatBase::Float8E5M2FNUZ() { return SupportedFltSemantics::semFloat8E5M2FNUZ; } +const fltSemantics &APFloatBase::Float8E4M3() { return SupportedFltSemantics::semFloat8E4M3; } +const fltSemantics &APFloatBase::Float8E4M3FN() { return SupportedFltSemantics::semFloat8E4M3FN; } +const fltSemantics &APFloatBase::Float8E4M3FNUZ() { return SupportedFltSemantics::semFloat8E4M3FNUZ; } const fltSemantics &APFloatBase::Float8E4M3B11FNUZ() { - return semFloat8E4M3B11FNUZ; -} -const fltSemantics &APFloatBase::Float8E3M4() { return semFloat8E3M4; } -const fltSemantics &APFloatBase::FloatTF32() { return semFloatTF32; } -const fltSemantics &APFloatBase::Float8E8M0FNU() { return semFloat8E8M0FNU; } -const fltSemantics &APFloatBase::Float6E3M2FN() { return semFloat6E3M2FN; } -const fltSemantics &APFloatBase::Float6E2M3FN() { return semFloat6E2M3FN; } -const fltSemantics &APFloatBase::Float4E2M1FN() { return semFloat4E2M1FN; } + return SupportedFltSemantics::semFloat8E4M3B11FNUZ; +} +const fltSemantics &APFloatBase::Float8E3M4() { return SupportedFltSemantics::semFloat8E3M4; } +const fltSemantics &APFloatBase::FloatTF32() { return SupportedFltSemantics::semFloatTF32; } +const fltSemantics &APFloatBase::Float8E8M0FNU() { return SupportedFltSemantics::semFloat8E8M0FNU; } +const fltSemantics &APFloatBase::Float6E3M2FN() { return SupportedFltSemantics::semFloat6E3M2FN; } +const fltSemantics &APFloatBase::Float6E2M3FN() { return SupportedFltSemantics::semFloat6E2M3FN; } +const fltSemantics &APFloatBase::Float4E2M1FN() { return SupportedFltSemantics::semFloat4E2M1FN; } const fltSemantics &APFloatBase::x87DoubleExtended() { - return semX87DoubleExtended; + return SupportedFltSemantics::semX87DoubleExtended; } -const fltSemantics &APFloatBase::Bogus() { return semBogus; } +const fltSemantics &APFloatBase::Bogus() { return SupportedFltSemantics::semBogus; } bool APFloatBase::isRepresentableBy(const fltSemantics &A, const fltSemantics &B) { @@ -312,47 +240,6 @@ const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 815) / (351 * APFloatBase::integerPartWidth)); -unsigned int APFloatBase::semanticsPrecision(const fltSemantics &semantics) { - return semantics.precision; -} -APFloatBase::ExponentType -APFloatBase::semanticsMaxExponent(const fltSemantics &semantics) { - return semantics.maxExponent; -} -APFloatBase::ExponentType -APFloatBase::semanticsMinExponent(const fltSemantics &semantics) { - return semantics.minExponent; -} -unsigned int APFloatBase::semanticsSizeInBits(const fltSemantics &semantics) { - return semantics.sizeInBits; -} -unsigned int APFloatBase::semanticsIntSizeInBits(const fltSemantics &semantics, - bool isSigned) { - // The max FP value is pow(2, MaxExponent) * (1 + MaxFraction), so we need - // at least one more bit than the MaxExponent to hold the max FP value. - unsigned int MinBitWidth = semanticsMaxExponent(semantics) + 1; - // Extra sign bit needed. - if (isSigned) - ++MinBitWidth; - return MinBitWidth; -} - -bool APFloatBase::semanticsHasZero(const fltSemantics &semantics) { - return semantics.hasZero; -} - -bool APFloatBase::semanticsHasSignedRepr(const fltSemantics &semantics) { - return semantics.hasSignedRepr; -} - -bool APFloatBase::semanticsHasInf(const fltSemantics &semantics) { - return semantics.nonFiniteBehavior == fltNonfiniteBehavior::IEEE754; -} - -bool APFloatBase::semanticsHasNaN(const fltSemantics &semantics) { - return semantics.nonFiniteBehavior != fltNonfiniteBehavior::FiniteOnly; -} - bool APFloatBase::isRepresentableAsNormalIn(const fltSemantics &Src, const fltSemantics &Dst) { // Exponent range must be larger. @@ -986,7 +873,7 @@ void IEEEFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill) { // For x87 extended precision, we want to make a NaN, not a // pseudo-NaN. Maybe we should expose the ability to make // pseudo-NaNs? - if (semantics == &semX87DoubleExtended) + if (semantics == &SupportedFltSemantics::semX87DoubleExtended) APInt::tcSetBit(significand, QNaNBit + 1); } @@ -1011,7 +898,7 @@ IEEEFloat &IEEEFloat::operator=(IEEEFloat &&rhs) { category = rhs.category; sign = rhs.sign; - rhs.semantics = &semBogus; + rhs.semantics = &SupportedFltSemantics::semBogus; return *this; } @@ -1204,7 +1091,7 @@ IEEEFloat::IEEEFloat(const IEEEFloat &rhs) { assign(rhs); } -IEEEFloat::IEEEFloat(IEEEFloat &&rhs) : semantics(&semBogus) { +IEEEFloat::IEEEFloat(IEEEFloat &&rhs) : semantics(&SupportedFltSemantics::semBogus) { *this = std::move(rhs); } @@ -2415,7 +2302,7 @@ APFloat::opStatus IEEEFloat::roundToIntegral(roundingMode rounding_mode) { // If the exponent is large enough, we know that this value is already // integral, and the arithmetic below would potentially cause it to saturate // to +/-Inf. Bail out early instead. - if (exponent + 1 >= (int)APFloat::semanticsPrecision(*semantics)) + if (exponent + 1 >= (int)semantics->precision) return opOK; // The algorithm here is quite simple: we add 2^(p-1), where p is the @@ -2424,9 +2311,8 @@ APFloat::opStatus IEEEFloat::roundToIntegral(roundingMode rounding_mode) { // for our integral rounding as well. // NOTE: When the input value is negative, we do subtraction followed by // addition instead. - APInt IntegerConstant(NextPowerOf2(APFloat::semanticsPrecision(*semantics)), - 1); - IntegerConstant <<= APFloat::semanticsPrecision(*semantics) - 1; + APInt IntegerConstant(NextPowerOf2(semantics->precision), 1); + IntegerConstant <<= semantics->precision - 1; IEEEFloat MagicConstant(*semantics); fs = MagicConstant.convertFromAPInt(IntegerConstant, false, rmNearestTiesToEven); @@ -2544,8 +2430,8 @@ APFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics, shift = toSemantics.precision - fromSemantics.precision; bool X86SpecialNan = false; - if (&fromSemantics == &semX87DoubleExtended && - &toSemantics != &semX87DoubleExtended && category == fcNaN && + if (&fromSemantics == &SupportedFltSemantics::semX87DoubleExtended && + &toSemantics != &SupportedFltSemantics::semX87DoubleExtended && category == fcNaN && (!(*significandParts() & 0x8000000000000000ULL) || !(*significandParts() & 0x4000000000000000ULL))) { // x86 has some unusual NaNs which cannot be represented in any other @@ -2631,7 +2517,7 @@ APFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics, // For x87 extended precision, we want to make a NaN, not a special NaN if // the input wasn't special either. - if (!X86SpecialNan && semantics == &semX87DoubleExtended) + if (!X86SpecialNan && semantics == &SupportedFltSemantics::semX87DoubleExtended) APInt::tcSetBit(significandParts(), semantics->precision - 1); // Convert of sNaN creates qNaN and raises an exception (invalid op). @@ -3515,7 +3401,7 @@ hash_code hash_value(const IEEEFloat &Arg) { // the actual IEEE respresentations. We compensate for that here. APInt IEEEFloat::convertF80LongDoubleAPFloatToAPInt() const { - assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended); + assert(semantics == (const llvm::fltSemantics*)&SupportedFltSemantics::semX87DoubleExtended); assert(partCount()==2); uint64_t myexponent, mysignificand; @@ -3545,7 +3431,7 @@ APInt IEEEFloat::convertF80LongDoubleAPFloatToAPInt() const { } APInt IEEEFloat::convertPPCDoubleDoubleLegacyAPFloatToAPInt() const { - assert(semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy); + assert(semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semPPCDoubleDoubleLegacy); assert(partCount()==2); uint64_t words[2]; @@ -3559,14 +3445,14 @@ APInt IEEEFloat::convertPPCDoubleDoubleLegacyAPFloatToAPInt() const { // Declare fltSemantics before APFloat that uses it (and // saves pointer to it) to ensure correct destruction order. fltSemantics extendedSemantics = *semantics; - extendedSemantics.minExponent = semIEEEdouble.minExponent; + extendedSemantics.minExponent = SupportedFltSemantics::semIEEEdouble.minExponent; IEEEFloat extended(*this); fs = extended.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo); assert(fs == opOK && !losesInfo); (void)fs; IEEEFloat u(extended); - fs = u.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo); + fs = u.convert(SupportedFltSemantics::semIEEEdouble, rmNearestTiesToEven, &losesInfo); assert(fs == opOK || fs == opInexact); (void)fs; words[0] = *u.convertDoubleAPFloatToAPInt().getRawData(); @@ -3582,7 +3468,7 @@ APInt IEEEFloat::convertPPCDoubleDoubleLegacyAPFloatToAPInt() const { IEEEFloat v(extended); v.subtract(u, rmNearestTiesToEven); - fs = v.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo); + fs = v.convert(SupportedFltSemantics::semIEEEdouble, rmNearestTiesToEven, &losesInfo); assert(fs == opOK && !losesInfo); (void)fs; words[1] = *v.convertDoubleAPFloatToAPInt().getRawData(); @@ -3597,7 +3483,7 @@ template <const fltSemantics &S> APInt IEEEFloat::convertIEEEFloatToAPInt() const { assert(semantics == &S); const int bias = - (semantics == &semFloat8E8M0FNU) ? -S.minExponent : -(S.minExponent - 1); + (semantics == &SupportedFltSemantics::semFloat8E8M0FNU) ? -S.minExponent : -(S.minExponent - 1); constexpr unsigned int trailing_significand_bits = S.precision - 1; constexpr int integer_bit_part = trailing_significand_bits / integerPartWidth; constexpr integerPart integer_bit = @@ -3662,87 +3548,87 @@ APInt IEEEFloat::convertIEEEFloatToAPInt() const { APInt IEEEFloat::convertQuadrupleAPFloatToAPInt() const { assert(partCount() == 2); - return convertIEEEFloatToAPInt<semIEEEquad>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semIEEEquad>(); } APInt IEEEFloat::convertDoubleAPFloatToAPInt() const { assert(partCount()==1); - return convertIEEEFloatToAPInt<semIEEEdouble>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semIEEEdouble>(); } APInt IEEEFloat::convertFloatAPFloatToAPInt() const { assert(partCount()==1); - return convertIEEEFloatToAPInt<semIEEEsingle>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semIEEEsingle>(); } APInt IEEEFloat::convertBFloatAPFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semBFloat>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semBFloat>(); } APInt IEEEFloat::convertHalfAPFloatToAPInt() const { assert(partCount()==1); - return convertIEEEFloatToAPInt<semIEEEhalf>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semIEEEhalf>(); } APInt IEEEFloat::convertFloat8E5M2APFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloat8E5M2>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloat8E5M2>(); } APInt IEEEFloat::convertFloat8E5M2FNUZAPFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloat8E5M2FNUZ>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloat8E5M2FNUZ>(); } APInt IEEEFloat::convertFloat8E4M3APFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloat8E4M3>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloat8E4M3>(); } APInt IEEEFloat::convertFloat8E4M3FNAPFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloat8E4M3FN>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloat8E4M3FN>(); } APInt IEEEFloat::convertFloat8E4M3FNUZAPFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloat8E4M3FNUZ>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloat8E4M3FNUZ>(); } APInt IEEEFloat::convertFloat8E4M3B11FNUZAPFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloat8E4M3B11FNUZ>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloat8E4M3B11FNUZ>(); } APInt IEEEFloat::convertFloat8E3M4APFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloat8E3M4>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloat8E3M4>(); } APInt IEEEFloat::convertFloatTF32APFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloatTF32>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloatTF32>(); } APInt IEEEFloat::convertFloat8E8M0FNUAPFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloat8E8M0FNU>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloat8E8M0FNU>(); } APInt IEEEFloat::convertFloat6E3M2FNAPFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloat6E3M2FN>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloat6E3M2FN>(); } APInt IEEEFloat::convertFloat6E2M3FNAPFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloat6E2M3FN>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloat6E2M3FN>(); } APInt IEEEFloat::convertFloat4E2M1FNAPFloatToAPInt() const { assert(partCount() == 1); - return convertIEEEFloatToAPInt<semFloat4E2M1FN>(); + return convertIEEEFloatToAPInt<SupportedFltSemantics::semFloat4E2M1FN>(); } // This function creates an APInt that is just a bit map of the floating @@ -3750,74 +3636,74 @@ APInt IEEEFloat::convertFloat4E2M1FNAPFloatToAPInt() const { // and treating the result as a normal integer is unlikely to be useful. APInt IEEEFloat::bitcastToAPInt() const { - if (semantics == (const llvm::fltSemantics*)&semIEEEhalf) + if (semantics == (const llvm::fltSemantics*)&SupportedFltSemantics::semIEEEhalf) return convertHalfAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semBFloat) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semBFloat) return convertBFloatAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics*)&semIEEEsingle) + if (semantics == (const llvm::fltSemantics*)&SupportedFltSemantics::semIEEEsingle) return convertFloatAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics*)&semIEEEdouble) + if (semantics == (const llvm::fltSemantics*)&SupportedFltSemantics::semIEEEdouble) return convertDoubleAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics*)&semIEEEquad) + if (semantics == (const llvm::fltSemantics*)&SupportedFltSemantics::semIEEEquad) return convertQuadrupleAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semPPCDoubleDoubleLegacy) return convertPPCDoubleDoubleLegacyAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloat8E5M2) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloat8E5M2) return convertFloat8E5M2APFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloat8E5M2FNUZ) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloat8E5M2FNUZ) return convertFloat8E5M2FNUZAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloat8E4M3) return convertFloat8E4M3APFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3FN) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloat8E4M3FN) return convertFloat8E4M3FNAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3FNUZ) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloat8E4M3FNUZ) return convertFloat8E4M3FNUZAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloat8E4M3B11FNUZ) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloat8E4M3B11FNUZ) return convertFloat8E4M3B11FNUZAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloat8E3M4) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloat8E3M4) return convertFloat8E3M4APFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloatTF32) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloatTF32) return convertFloatTF32APFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloat8E8M0FNU) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloat8E8M0FNU) return convertFloat8E8M0FNUAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloat6E3M2FN) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloat6E3M2FN) return convertFloat6E3M2FNAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloat6E2M3FN) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloat6E2M3FN) return convertFloat6E2M3FNAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics *)&semFloat4E2M1FN) + if (semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semFloat4E2M1FN) return convertFloat4E2M1FNAPFloatToAPInt(); - assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended && + assert(semantics == (const llvm::fltSemantics*)&SupportedFltSemantics::semX87DoubleExtended && "unknown format!"); return convertF80LongDoubleAPFloatToAPInt(); } float IEEEFloat::convertToFloat() const { - assert(semantics == (const llvm::fltSemantics*)&semIEEEsingle && + assert(semantics == (const llvm::fltSemantics*)&SupportedFltSemantics::semIEEEsingle && "Float semantics are not IEEEsingle"); APInt api = bitcastToAPInt(); return api.bitsToFloat(); } double IEEEFloat::convertToDouble() const { - assert(semantics == (const llvm::fltSemantics*)&semIEEEdouble && + assert(semantics == (const llvm::fltSemantics*)&SupportedFltSemantics::semIEEEdouble && "Float semantics are not IEEEdouble"); APInt api = bitcastToAPInt(); return api.bitsToDouble(); @@ -3825,7 +3711,7 @@ double IEEEFloat::convertToDouble() const { #ifdef HAS_IEE754_FLOAT128 float128 IEEEFloat::convertToQuad() const { - assert(semantics == (const llvm::fltSemantics *)&semIEEEquad && + assert(semantics == (const llvm::fltSemantics *)&SupportedFltSemantics::semIEEEquad && "Float semantics are not IEEEquads"); APInt api = bitcastToAPInt(); return api.bitsToQuad(); @@ -3846,7 +3732,7 @@ void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) { uint64_t mysignificand = i1; uint8_t myintegerbit = mysignificand >> 63; - initialize(&semX87DoubleExtended); + initialize(&SupportedFltSemantics::semX87DoubleExtended); assert(partCount()==2); sign = static_cast<unsigned int>(i2>>15); @@ -3878,14 +3764,14 @@ void IEEEFloat::initFromPPCDoubleDoubleLegacyAPInt(const APInt &api) { // Get the first double and convert to our format. initFromDoubleAPInt(APInt(64, i1)); - fs = convert(semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo); + fs = convert(SupportedFltSemantics::semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo); assert(fs == opOK && !losesInfo); (void)fs; // Unless we have a special case, add in second double. if (isFiniteNonZero()) { - IEEEFloat v(semIEEEdouble, APInt(64, i2)); - fs = v.convert(semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo); + IEEEFloat v(SupportedFltSemantics::semIEEEdouble, APInt(64, i2)); + fs = v.convert(SupportedFltSemantics::semPPCDoubleDoubleLegacy, rmNearestTiesToEven, &losesInfo); assert(fs == opOK && !losesInfo); (void)fs; @@ -3903,7 +3789,7 @@ void IEEEFloat::initFromFloat8E8M0FNUAPInt(const APInt &api) { uint64_t val = api.getRawData()[0]; uint64_t myexponent = (val & exponent_mask); - initialize(&semFloat8E8M0FNU); + initialize(&SupportedFltSemantics::semFloat8E8M0FNU); assert(partCount() == 1); // This format has unsigned representation only @@ -4010,109 +3896,109 @@ void IEEEFloat::initFromIEEEAPInt(const APInt &api) { } void IEEEFloat::initFromQuadrupleAPInt(const APInt &api) { - initFromIEEEAPInt<semIEEEquad>(api); + initFromIEEEAPInt<SupportedFltSemantics::semIEEEquad>(api); } void IEEEFloat::initFromDoubleAPInt(const APInt &api) { - initFromIEEEAPInt<semIEEEdouble>(api); + initFromIEEEAPInt<SupportedFltSemantics::semIEEEdouble>(api); } void IEEEFloat::initFromFloatAPInt(const APInt &api) { - initFromIEEEAPInt<semIEEEsingle>(api); + initFromIEEEAPInt<SupportedFltSemantics::semIEEEsingle>(api); } void IEEEFloat::initFromBFloatAPInt(const APInt &api) { - initFromIEEEAPInt<semBFloat>(api); + initFromIEEEAPInt<SupportedFltSemantics::semBFloat>(api); } void IEEEFloat::initFromHalfAPInt(const APInt &api) { - initFromIEEEAPInt<semIEEEhalf>(api); + initFromIEEEAPInt<SupportedFltSemantics::semIEEEhalf>(api); } void IEEEFloat::initFromFloat8E5M2APInt(const APInt &api) { - initFromIEEEAPInt<semFloat8E5M2>(api); + initFromIEEEAPInt<SupportedFltSemantics::semFloat8E5M2>(api); } void IEEEFloat::initFromFloat8E5M2FNUZAPInt(const APInt &api) { - initFromIEEEAPInt<semFloat8E5M2FNUZ>(api); + initFromIEEEAPInt<SupportedFltSemantics::semFloat8E5M2FNUZ>(api); } void IEEEFloat::initFromFloat8E4M3APInt(const APInt &api) { - initFromIEEEAPInt<semFloat8E4M3>(api); + initFromIEEEAPInt<SupportedFltSemantics::semFloat8E4M3>(api); } void IEEEFloat::initFromFloat8E4M3FNAPInt(const APInt &api) { - initFromIEEEAPInt<semFloat8E4M3FN>(api); + initFromIEEEAPInt<SupportedFltSemantics::semFloat8E4M3FN>(api); } void IEEEFloat::initFromFloat8E4M3FNUZAPInt(const APInt &api) { - initFromIEEEAPInt<semFloat8E4M3FNUZ>(api); + initFromIEEEAPInt<SupportedFltSemantics::semFloat8E4M3FNUZ>(api); } void IEEEFloat::initFromFloat8E4M3B11FNUZAPInt(const APInt &api) { - initFromIEEEAPInt<semFloat8E4M3B11FNUZ>(api); + initFromIEEEAPInt<SupportedFltSemantics::semFloat8E4M3B11FNUZ>(api); } void IEEEFloat::initFromFloat8E3M4APInt(const APInt &api) { - initFromIEEEAPInt<semFloat8E3M4>(api); + initFromIEEEAPInt<SupportedFltSemantics::semFloat8E3M4>(api); } void IEEEFloat::initFromFloatTF32APInt(const APInt &api) { - initFromIEEEAPInt<semFloatTF32>(api); + initFromIEEEAPInt<SupportedFltSemantics::semFloatTF32>(api); } void IEEEFloat::initFromFloat6E3M2FNAPInt(const APInt &api) { - initFromIEEEAPInt<semFloat6E3M2FN>(api); + initFromIEEEAPInt<SupportedFltSemantics::semFloat6E3M2FN>(api); } void IEEEFloat::initFromFloat6E2M3FNAPInt(const APInt &api) { - initFromIEEEAPInt<semFloat6E2M3FN>(api); + initFromIEEEAPInt<SupportedFltSemantics::semFloat6E2M3FN>(api); } void IEEEFloat::initFromFloat4E2M1FNAPInt(const APInt &api) { - initFromIEEEAPInt<semFloat4E2M1FN>(api); + initFromIEEEAPInt<SupportedFltSemantics::semFloat4E2M1FN>(api); } /// Treat api as containing the bits of a floating point number. void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) { assert(api.getBitWidth() == Sem->sizeInBits); - if (Sem == &semIEEEhalf) + if (Sem == &SupportedFltSemantics::semIEEEhalf) return initFromHalfAPInt(api); - if (Sem == &semBFloat) + if (Sem == &SupportedFltSemantics::semBFloat) return initFromBFloatAPInt(api); - if (Sem == &semIEEEsingle) + if (Sem == &SupportedFltSemantics::semIEEEsingle) return initFromFloatAPInt(api); - if (Sem == &semIEEEdouble) + if (Sem == &SupportedFltSemantics::semIEEEdouble) return initFromDoubleAPInt(api); - if (Sem == &semX87DoubleExtended) + if (Sem == &SupportedFltSemantics::semX87DoubleExtended) return initFromF80LongDoubleAPInt(api); - if (Sem == &semIEEEquad) + if (Sem == &SupportedFltSemantics::semIEEEquad) return initFromQuadrupleAPInt(api); - if (Sem == &semPPCDoubleDoubleLegacy) + if (Sem == &SupportedFltSemantics::semPPCDoubleDoubleLegacy) return initFromPPCDoubleDoubleLegacyAPInt(api); - if (Sem == &semFloat8E5M2) + if (Sem == &SupportedFltSemantics::semFloat8E5M2) return initFromFloat8E5M2APInt(api); - if (Sem == &semFloat8E5M2FNUZ) + if (Sem == &SupportedFltSemantics::semFloat8E5M2FNUZ) return initFromFloat8E5M2FNUZAPInt(api); - if (Sem == &semFloat8E4M3) + if (Sem == &SupportedFltSemantics::semFloat8E4M3) return initFromFloat8E4M3APInt(api); - if (Sem == &semFloat8E4M3FN) + if (Sem == &SupportedFltSemantics::semFloat8E4M3FN) return initFromFloat8E4M3FNAPInt(api); - if (Sem == &semFloat8E4M3FNUZ) + if (Sem == &SupportedFltSemantics::semFloat8E4M3FNUZ) return initFromFloat8E4M3FNUZAPInt(api); - if (Sem == &semFloat8E4M3B11FNUZ) + if (Sem == &SupportedFltSemantics::semFloat8E4M3B11FNUZ) return initFromFloat8E4M3B11FNUZAPInt(api); - if (Sem == &semFloat8E3M4) + if (Sem == &SupportedFltSemantics::semFloat8E3M4) return initFromFloat8E3M4APInt(api); - if (Sem == &semFloatTF32) + if (Sem == &SupportedFltSemantics::semFloatTF32) return initFromFloatTF32APInt(api); - if (Sem == &semFloat8E8M0FNU) + if (Sem == &SupportedFltSemantics::semFloat8E8M0FNU) return initFromFloat8E8M0FNUAPInt(api); - if (Sem == &semFloat6E3M2FN) + if (Sem == &SupportedFltSemantics::semFloat6E3M2FN) return initFromFloat6E3M2FNAPInt(api); - if (Sem == &semFloat6E2M3FN) + if (Sem == &SupportedFltSemantics::semFloat6E2M3FN) return initFromFloat6E2M3FNAPInt(api); - if (Sem == &semFloat4E2M1FN) + if (Sem == &SupportedFltSemantics::semFloat4E2M1FN) return initFromFloat4E2M1FNAPInt(api); llvm_unreachable("unsupported semantics"); @@ -4187,11 +4073,11 @@ IEEEFloat::IEEEFloat(const fltSemantics &Sem, const APInt &API) { } IEEEFloat::IEEEFloat(float f) { - initFromAPInt(&semIEEEsingle, APInt::floatToBits(f)); + initFromAPInt(&SupportedFltSemantics::semIEEEsingle, APInt::floatToBits(f)); } IEEEFloat::IEEEFloat(double d) { - initFromAPInt(&semIEEEdouble, APInt::doubleToBits(d)); + initFromAPInt(&SupportedFltSemantics::semIEEEdouble, APInt::doubleToBits(d)); } namespace { @@ -4828,38 +4714,38 @@ IEEEFloat frexp(const IEEEFloat &Val, int &Exp, roundingMode RM) { DoubleAPFloat::DoubleAPFloat(const fltSemantics &S) : Semantics(&S), - Floats(new APFloat[2]{APFloat(semIEEEdouble), APFloat(semIEEEdouble)}) { - assert(Semantics == &semPPCDoubleDouble); + Floats(new APFloat[2]{APFloat(SupportedFltSemantics::semIEEEdouble), APFloat(SupportedFltSemantics::semIEEEdouble)}) { + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble); } DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, uninitializedTag) : Semantics(&S), - Floats(new APFloat[2]{APFloat(semIEEEdouble, uninitialized), - APFloat(semIEEEdouble, uninitialized)}) { - assert(Semantics == &semPPCDoubleDouble); + Floats(new APFloat[2]{APFloat(SupportedFltSemantics::semIEEEdouble, uninitialized), + APFloat(SupportedFltSemantics::semIEEEdouble, uninitialized)}) { + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble); } DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, integerPart I) - : Semantics(&S), Floats(new APFloat[2]{APFloat(semIEEEdouble, I), - APFloat(semIEEEdouble)}) { - assert(Semantics == &semPPCDoubleDouble); + : Semantics(&S), Floats(new APFloat[2]{APFloat(SupportedFltSemantics::semIEEEdouble, I), + APFloat(SupportedFltSemantics::semIEEEdouble)}) { + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble); } DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, const APInt &I) : Semantics(&S), Floats(new APFloat[2]{ - APFloat(semIEEEdouble, APInt(64, I.getRawData()[0])), - APFloat(semIEEEdouble, APInt(64, I.getRawData()[1]))}) { - assert(Semantics == &semPPCDoubleDouble); + APFloat(SupportedFltSemantics::semIEEEdouble, APInt(64, I.getRawData()[0])), + APFloat(SupportedFltSemantics::semIEEEdouble, APInt(64, I.getRawData()[1]))}) { + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble); } DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, APFloat &&First, APFloat &&Second) : Semantics(&S), Floats(new APFloat[2]{std::move(First), std::move(Second)}) { - assert(Semantics == &semPPCDoubleDouble); - assert(&Floats[0].getSemantics() == &semIEEEdouble); - assert(&Floats[1].getSemantics() == &semIEEEdouble); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble); + assert(&Floats[0].getSemantics() == &SupportedFltSemantics::semIEEEdouble); + assert(&Floats[1].getSemantics() == &SupportedFltSemantics::semIEEEdouble); } DoubleAPFloat::DoubleAPFloat(const DoubleAPFloat &RHS) @@ -4867,13 +4753,13 @@ DoubleAPFloat::DoubleAPFloat(const DoubleAPFloat &RHS) Floats(RHS.Floats ? new APFloat[2]{APFloat(RHS.Floats[0]), APFloat(RHS.Floats[1])} : nullptr) { - assert(Semantics == &semPPCDoubleDouble); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble); } DoubleAPFloat::DoubleAPFloat(DoubleAPFloat &&RHS) : Semantics(RHS.Semantics), Floats(std::move(RHS.Floats)) { - RHS.Semantics = &semBogus; - assert(Semantics == &semPPCDoubleDouble); + RHS.Semantics = &SupportedFltSemantics::semBogus; + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble); } DoubleAPFloat &DoubleAPFloat::operator=(const DoubleAPFloat &RHS) { @@ -5006,12 +4892,12 @@ APFloat::opStatus DoubleAPFloat::addWithSpecial(const DoubleAPFloat &LHS, APFloat A(LHS.Floats[0]), AA(LHS.Floats[1]), C(RHS.Floats[0]), CC(RHS.Floats[1]); - assert(&A.getSemantics() == &semIEEEdouble); - assert(&AA.getSemantics() == &semIEEEdouble); - assert(&C.getSemantics() == &semIEEEdouble); - assert(&CC.getSemantics() == &semIEEEdouble); - assert(&Out.Floats[0].getSemantics() == &semIEEEdouble); - assert(&Out.Floats[1].getSemantics() == &semIEEEdouble); + assert(&A.getSemantics() == &SupportedFltSemantics::semIEEEdouble); + assert(&AA.getSemantics() == &SupportedFltSemantics::semIEEEdouble); + assert(&C.getSemantics() == &SupportedFltSemantics::semIEEEdouble); + assert(&CC.getSemantics() == &SupportedFltSemantics::semIEEEdouble); + assert(&Out.Floats[0].getSemantics() == &SupportedFltSemantics::semIEEEdouble); + assert(&Out.Floats[1].getSemantics() == &SupportedFltSemantics::semIEEEdouble); return Out.addImpl(A, AA, C, CC, RM); } @@ -5116,28 +5002,28 @@ APFloat::opStatus DoubleAPFloat::multiply(const DoubleAPFloat &RHS, APFloat::opStatus DoubleAPFloat::divide(const DoubleAPFloat &RHS, APFloat::roundingMode RM) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat Tmp(SupportedFltSemantics::semPPCDoubleDoubleLegacy, bitcastToAPInt()); auto Ret = - Tmp.divide(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()), RM); - *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); + Tmp.divide(APFloat(SupportedFltSemantics::semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt()), RM); + *this = DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, Tmp.bitcastToAPInt()); return Ret; } APFloat::opStatus DoubleAPFloat::remainder(const DoubleAPFloat &RHS) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat Tmp(SupportedFltSemantics::semPPCDoubleDoubleLegacy, bitcastToAPInt()); auto Ret = - Tmp.remainder(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt())); - *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); + Tmp.remainder(APFloat(SupportedFltSemantics::semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt())); + *this = DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, Tmp.bitcastToAPInt()); return Ret; } APFloat::opStatus DoubleAPFloat::mod(const DoubleAPFloat &RHS) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); - auto Ret = Tmp.mod(APFloat(semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt())); - *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat Tmp(SupportedFltSemantics::semPPCDoubleDoubleLegacy, bitcastToAPInt()); + auto Ret = Tmp.mod(APFloat(SupportedFltSemantics::semPPCDoubleDoubleLegacy, RHS.bitcastToAPInt())); + *this = DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, Tmp.bitcastToAPInt()); return Ret; } @@ -5145,20 +5031,20 @@ APFloat::opStatus DoubleAPFloat::fusedMultiplyAdd(const DoubleAPFloat &Multiplicand, const DoubleAPFloat &Addend, APFloat::roundingMode RM) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat Tmp(SupportedFltSemantics::semPPCDoubleDoubleLegacy, bitcastToAPInt()); auto Ret = Tmp.fusedMultiplyAdd( - APFloat(semPPCDoubleDoubleLegacy, Multiplicand.bitcastToAPInt()), - APFloat(semPPCDoubleDoubleLegacy, Addend.bitcastToAPInt()), RM); - *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); + APFloat(SupportedFltSemantics::semPPCDoubleDoubleLegacy, Multiplicand.bitcastToAPInt()), + APFloat(SupportedFltSemantics::semPPCDoubleDoubleLegacy, Addend.bitcastToAPInt()), RM); + *this = DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, Tmp.bitcastToAPInt()); return Ret; } APFloat::opStatus DoubleAPFloat::roundToIntegral(APFloat::roundingMode RM) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat Tmp(SupportedFltSemantics::semPPCDoubleDoubleLegacy, bitcastToAPInt()); auto Ret = Tmp.roundToIntegral(RM); - *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); + *this = DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, Tmp.bitcastToAPInt()); return Ret; } @@ -5205,22 +5091,22 @@ void DoubleAPFloat::makeZero(bool Neg) { } void DoubleAPFloat::makeLargest(bool Neg) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - Floats[0] = APFloat(semIEEEdouble, APInt(64, 0x7fefffffffffffffull)); - Floats[1] = APFloat(semIEEEdouble, APInt(64, 0x7c8ffffffffffffeull)); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + Floats[0] = APFloat(SupportedFltSemantics::semIEEEdouble, APInt(64, 0x7fefffffffffffffull)); + Floats[1] = APFloat(SupportedFltSemantics::semIEEEdouble, APInt(64, 0x7c8ffffffffffffeull)); if (Neg) changeSign(); } void DoubleAPFloat::makeSmallest(bool Neg) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); Floats[0].makeSmallest(Neg); Floats[1].makeZero(/* Neg = */ false); } void DoubleAPFloat::makeSmallestNormalized(bool Neg) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - Floats[0] = APFloat(semIEEEdouble, APInt(64, 0x0360000000000000ull)); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + Floats[0] = APFloat(SupportedFltSemantics::semIEEEdouble, APInt(64, 0x0360000000000000ull)); if (Neg) Floats[0].changeSign(); Floats[1].makeZero(/* Neg = */ false); @@ -5251,7 +5137,7 @@ hash_code hash_value(const DoubleAPFloat &Arg) { } APInt DoubleAPFloat::bitcastToAPInt() const { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); uint64_t Data[] = { Floats[0].bitcastToAPInt().getRawData()[0], Floats[1].bitcastToAPInt().getRawData()[0], @@ -5261,18 +5147,18 @@ APInt DoubleAPFloat::bitcastToAPInt() const { Expected<APFloat::opStatus> DoubleAPFloat::convertFromString(StringRef S, roundingMode RM) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat Tmp(SupportedFltSemantics::semPPCDoubleDoubleLegacy); auto Ret = Tmp.convertFromString(S, RM); - *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); + *this = DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, Tmp.bitcastToAPInt()); return Ret; } APFloat::opStatus DoubleAPFloat::next(bool nextDown) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat Tmp(SupportedFltSemantics::semPPCDoubleDoubleLegacy, bitcastToAPInt()); auto Ret = Tmp.next(nextDown); - *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); + *this = DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, Tmp.bitcastToAPInt()); return Ret; } @@ -5280,18 +5166,18 @@ APFloat::opStatus DoubleAPFloat::convertToInteger(MutableArrayRef<integerPart> Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt()) + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + return APFloat(SupportedFltSemantics::semPPCDoubleDoubleLegacy, bitcastToAPInt()) .convertToInteger(Input, Width, IsSigned, RM, IsExact); } APFloat::opStatus DoubleAPFloat::convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat Tmp(SupportedFltSemantics::semPPCDoubleDoubleLegacy); auto Ret = Tmp.convertFromAPInt(Input, IsSigned, RM); - *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); + *this = DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, Tmp.bitcastToAPInt()); return Ret; } @@ -5299,10 +5185,10 @@ APFloat::opStatus DoubleAPFloat::convertFromSignExtendedInteger(const integerPart *Input, unsigned int InputSize, bool IsSigned, roundingMode RM) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat Tmp(SupportedFltSemantics::semPPCDoubleDoubleLegacy); auto Ret = Tmp.convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM); - *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); + *this = DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, Tmp.bitcastToAPInt()); return Ret; } @@ -5310,10 +5196,10 @@ APFloat::opStatus DoubleAPFloat::convertFromZeroExtendedInteger(const integerPart *Input, unsigned int InputSize, bool IsSigned, roundingMode RM) { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat Tmp(SupportedFltSemantics::semPPCDoubleDoubleLegacy); auto Ret = Tmp.convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM); - *this = DoubleAPFloat(semPPCDoubleDouble, Tmp.bitcastToAPInt()); + *this = DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, Tmp.bitcastToAPInt()); return Ret; } @@ -5321,8 +5207,8 @@ unsigned int DoubleAPFloat::convertToHexString(char *DST, unsigned int HexDigits, bool UpperCase, roundingMode RM) const { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt()) + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + return APFloat(SupportedFltSemantics::semPPCDoubleDoubleLegacy, bitcastToAPInt()) .convertToHexString(DST, HexDigits, UpperCase, RM); } @@ -5359,7 +5245,7 @@ bool DoubleAPFloat::isLargest() const { } bool DoubleAPFloat::isInteger() const { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); return Floats[0].isInteger() && Floats[1].isInteger(); } @@ -5367,19 +5253,19 @@ void DoubleAPFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision, unsigned FormatMaxPadding, bool TruncateZero) const { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt()) + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat(SupportedFltSemantics::semPPCDoubleDoubleLegacy, bitcastToAPInt()) .toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero); } bool DoubleAPFloat::getExactInverse(APFloat *inv) const { - assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - APFloat Tmp(semPPCDoubleDoubleLegacy, bitcastToAPInt()); + assert(Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + APFloat Tmp(SupportedFltSemantics::semPPCDoubleDoubleLegacy, bitcastToAPInt()); if (!inv) return Tmp.getExactInverse(nullptr); - APFloat Inv(semPPCDoubleDoubleLegacy); + APFloat Inv(SupportedFltSemantics::semPPCDoubleDoubleLegacy); auto Ret = Tmp.getExactInverse(&Inv); - *inv = APFloat(semPPCDoubleDouble, Inv.bitcastToAPInt()); + *inv = APFloat(SupportedFltSemantics::semPPCDoubleDouble, Inv.bitcastToAPInt()); return Ret; } @@ -5395,19 +5281,19 @@ int DoubleAPFloat::getExactLog2Abs() const { DoubleAPFloat scalbn(const DoubleAPFloat &Arg, int Exp, APFloat::roundingMode RM) { - assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); - return DoubleAPFloat(semPPCDoubleDouble, scalbn(Arg.Floats[0], Exp, RM), + assert(Arg.Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); + return DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, scalbn(Arg.Floats[0], Exp, RM), scalbn(Arg.Floats[1], Exp, RM)); } DoubleAPFloat frexp(const DoubleAPFloat &Arg, int &Exp, APFloat::roundingMode RM) { - assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); + assert(Arg.Semantics == &SupportedFltSemantics::semPPCDoubleDouble && "Unexpected Semantics"); APFloat First = frexp(Arg.Floats[0], Exp, RM); APFloat Second = Arg.Floats[1]; if (Arg.getCategory() == APFloat::fcNormal) Second = scalbn(Second, -Exp, RM); - return DoubleAPFloat(semPPCDoubleDouble, std::move(First), std::move(Second)); + return DoubleAPFloat(SupportedFltSemantics::semPPCDoubleDouble, std::move(First), std::move(Second)); } } // namespace detail @@ -5421,7 +5307,7 @@ APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) { const fltSemantics& S = F.getSemantics(); new (&Double) DoubleAPFloat(Semantics, APFloat(std::move(F), S), - APFloat(semIEEEdouble)); + APFloat(SupportedFltSemantics::semIEEEdouble)); return; } llvm_unreachable("Unexpected semantics"); @@ -5471,8 +5357,8 @@ APFloat::opStatus APFloat::convert(const fltSemantics &ToSemantics, return U.IEEE.convert(ToSemantics, RM, losesInfo); if (usesLayout<IEEEFloat>(getSemantics()) && usesLayout<DoubleAPFloat>(ToSemantics)) { - assert(&ToSemantics == &semPPCDoubleDouble); - auto Ret = U.IEEE.convert(semPPCDoubleDoubleLegacy, RM, losesInfo); + assert(&ToSemantics == &SupportedFltSemantics::semPPCDoubleDouble); + auto Ret = U.IEEE.convert(SupportedFltSemantics::semPPCDoubleDoubleLegacy, RM, losesInfo); *this = APFloat(ToSemantics, U.IEEE.bitcastToAPInt()); return Ret; } @@ -5523,13 +5409,13 @@ APFloat::opStatus APFloat::convertToInteger(APSInt &result, } double APFloat::convertToDouble() const { - if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEdouble) + if (&getSemantics() == (const llvm::fltSemantics *)&SupportedFltSemantics::semIEEEdouble) return getIEEE().convertToDouble(); - assert(isRepresentableBy(getSemantics(), semIEEEdouble) && + assert(isRepresentableBy(getSemantics(), SupportedFltSemantics::semIEEEdouble) && "Float semantics is not representable by IEEEdouble"); APFloat Temp = *this; bool LosesInfo; - opStatus St = Temp.convert(semIEEEdouble, rmNearestTiesToEven, &LosesInfo); + opStatus St = Temp.convert(SupportedFltSemantics::semIEEEdouble, rmNearestTiesToEven, &LosesInfo); assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision"); (void)St; return Temp.getIEEE().convertToDouble(); @@ -5537,13 +5423,13 @@ double APFloat::convertToDouble() const { #ifdef HAS_IEE754_FLOAT128 float128 APFloat::convertToQuad() const { - if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEquad) + if (&getSemantics() == (const llvm::fltSemantics *)&SupportedFltSemantics::semIEEEquad) return getIEEE().convertToQuad(); - assert(isRepresentableBy(getSemantics(), semIEEEquad) && + assert(isRepresentableBy(getSemantics(), SupportedFltSemantics::semIEEEquad) && "Float semantics is not representable by IEEEquad"); APFloat Temp = *this; bool LosesInfo; - opStatus St = Temp.convert(semIEEEquad, rmNearestTiesToEven, &LosesInfo); + opStatus St = Temp.convert(SupportedFltSemantics::semIEEEquad, rmNearestTiesToEven, &LosesInfo); assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision"); (void)St; return Temp.getIEEE().convertToQuad(); @@ -5551,13 +5437,13 @@ float128 APFloat::convertToQuad() const { #endif float APFloat::convertToFloat() const { - if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) + if (&getSemantics() == (const llvm::fltSemantics *)&SupportedFltSemantics::semIEEEsingle) return getIEEE().convertToFloat(); - assert(isRepresentableBy(getSemantics(), semIEEEsingle) && + assert(isRepresentableBy(getSemantics(), SupportedFltSemantics::semIEEEsingle) && "Float semantics is not representable by IEEEsingle"); APFloat Temp = *this; bool LosesInfo; - opStatus St = Temp.convert(semIEEEsingle, rmNearestTiesToEven, &LosesInfo); + opStatus St = Temp.convert(SupportedFltSemantics::semIEEEsingle, rmNearestTiesToEven, &LosesInfo); assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision"); (void)St; return Temp.getIEEE().convertToFloat(); diff --git a/llvm/lib/Support/Z3Solver.cpp b/llvm/lib/Support/Z3Solver.cpp index 9aece099b06295..f901c7605e08ce 100644 --- a/llvm/lib/Support/Z3Solver.cpp +++ b/llvm/lib/Support/Z3Solver.cpp @@ -252,14 +252,10 @@ static const llvm::fltSemantics &getFloatSemantics(unsigned BitWidth) { // Determine whether two float semantics are equivalent static bool areEquivalent(const llvm::fltSemantics &LHS, const llvm::fltSemantics &RHS) { - return (llvm::APFloat::semanticsPrecision(LHS) == - llvm::APFloat::semanticsPrecision(RHS)) && - (llvm::APFloat::semanticsMinExponent(LHS) == - llvm::APFloat::semanticsMinExponent(RHS)) && - (llvm::APFloat::semanticsMaxExponent(LHS) == - llvm::APFloat::semanticsMaxExponent(RHS)) && - (llvm::APFloat::semanticsSizeInBits(LHS) == - llvm::APFloat::semanticsSizeInBits(RHS)); + return (LHS.precision == RHS.precision) && + (LHS.minExponent == RHS.minExponent) && + (LHS.maxExponent == RHS.maxExponent) && + (LSH.sizeInBits == RHS.sizeInBits); } class Z3Solver : public SMTSolver { @@ -761,7 +757,7 @@ class Z3Solver : public SMTSolver { SMTExprRef mkFloat(const llvm::APFloat Float) override { SMTSortRef Sort = - getFloatSort(llvm::APFloat::semanticsSizeInBits(Float.getSemantics())); + getFloatSort(Float.getSemantics().sizeInBits); llvm::APSInt Int = llvm::APSInt(Float.bitcastToAPInt(), false); SMTExprRef Z3Int = mkBitvector(Int, Int.getBitWidth()); diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 7d3ca46204b673..1dd62db2a59485 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -12040,7 +12040,7 @@ static SDValue getEstimate(const AArch64Subtarget *ST, unsigned Opcode, // the result for float (23 mantissa bits) is 2 and for double (52 // mantissa bits) is 3. constexpr unsigned AccurateBits = 8; - unsigned DesiredBits = APFloat::semanticsPrecision(VT.getFltSemantics()); + unsigned DesiredBits = VT.getFltSemantics().precision; ExtraSteps = DesiredBits <= AccurateBits ? 0 : Log2_64_Ceil(DesiredBits) - Log2_64_Ceil(AccurateBits); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index de100c683a94ff..b2c9adffb12802 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -3105,7 +3105,7 @@ lowerVectorFTRUNC_FCEIL_FFLOOR_FROUND(SDValue Op, SelectionDAG &DAG, // values larger than it don't have any fractional bits so don't need to // be converted. const fltSemantics &FltSem = ContainerVT.getFltSemantics(); - unsigned Precision = APFloat::semanticsPrecision(FltSem); + unsigned Precision = FltSem.precision; APFloat MaxVal = APFloat(FltSem); MaxVal.convertFromAPInt(APInt::getOneBitSet(Precision, Precision - 1), /*IsSigned*/ false, APFloat::rmNearestTiesToEven); @@ -3213,7 +3213,7 @@ lowerVectorStrictFTRUNC_FCEIL_FFLOOR_FROUND(SDValue Op, SelectionDAG &DAG, // values larger than it don't have any fractional bits so don't need to // be converted. const fltSemantics &FltSem = ContainerVT.getFltSemantics(); - unsigned Precision = APFloat::semanticsPrecision(FltSem); + unsigned Precision = FltSem.precision; APFloat MaxVal = APFloat(FltSem); MaxVal.convertFromAPInt(APInt::getOneBitSet(Precision, Precision - 1), /*IsSigned*/ false, APFloat::rmNearestTiesToEven); @@ -3293,7 +3293,7 @@ lowerFTRUNC_FCEIL_FFLOOR_FROUND(SDValue Op, SelectionDAG &DAG, // values larger than it don't have any fractional bits so don't need to be // converted. const fltSemantics &FltSem = VT.getFltSemantics(); - unsigned Precision = APFloat::semanticsPrecision(FltSem); + unsigned Precision = FltSem.precision; APFloat MaxVal = APFloat(FltSem); MaxVal.convertFromAPInt(APInt::getOneBitSet(Precision, Precision - 1), /*IsSigned*/ false, APFloat::rmNearestTiesToEven); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 90e3e15b1fb46c..9ea6f2fb444894 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -57312,7 +57312,7 @@ CastIntSETCCtoFP(MVT VT, ISD::CondCode CC, unsigned NumSignificantBitsLHS, // For cvt + signed compare we need lhs and rhs to be exactly representable as // a fp value. - unsigned FPPrec = APFloat::semanticsPrecision(Sem); + unsigned FPPrec = Sem.precision; if (FPPrec >= NumSignificantBitsLHS && FPPrec >= NumSignificantBitsRHS) return ISD::SINT_TO_FP; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 4ec1af394464bb..903c58fc6771bc 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -377,7 +377,7 @@ static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombinerImpl &IC, Type *InputTy = I->getOperand(0)->getType()->getScalarType(); const fltSemantics &Semantics = InputTy->getFltSemantics(); uint32_t MinBitWidth = - APFloatBase::semanticsIntSizeInBits(Semantics, + Semantics.intSizeInBits( I->getOpcode() == Instruction::FPToSI); return Ty->getScalarSizeInBits() >= MinBitWidth; } diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index fb21576722461e..b3c757cb61f980 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1453,7 +1453,7 @@ Instruction *InstCombinerImpl::foldFBinOpOfIntCastsFromSign( // This is the maximum number of inuse bits by the integer where the int -> fp // casts are exact. unsigned MaxRepresentableBits = - APFloat::semanticsPrecision(FPTy->getScalarType()->getFltSemantics()); + FPTy->getScalarType()->getFltSemantics().precision; // Preserve known number of leading bits. This can allow us to trivial nsw/nuw // checks later on. diff --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp index 9d23c899430095..932f6311dc445d 100644 --- a/llvm/lib/Transforms/Scalar/Float2Int.cpp +++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp @@ -362,10 +362,10 @@ bool Float2IntPass::validateAndTransform(const DataLayout &DL) { // the floating point result will differ from an integer approximation. // Do we need more bits than are in the mantissa of the type we converted - // to? semanticsPrecision returns the number of mantissa bits plus one + // to? semantics.precision returns the number of mantissa bits plus one // for the sign bit. unsigned MaxRepresentableBits - = APFloat::semanticsPrecision(ConvertedToTy->getFltSemantics()) - 1; + = ConvertedToTy->getFltSemantics().precision - 1; if (MinBW > MaxRepresentableBits) { LLVM_DEBUG(dbgs() << "F2I: Value not guaranteed to be representable!\n"); continue; diff --git a/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/llvm/lib/Transforms/Utils/FunctionComparator.cpp index 6d4026e8209de2..0a19295ebb4451 100644 --- a/llvm/lib/Transforms/Utils/FunctionComparator.cpp +++ b/llvm/lib/Transforms/Utils/FunctionComparator.cpp @@ -94,17 +94,13 @@ int FunctionComparator::cmpAPFloats(const APFloat &L, const APFloat &R) const { // Floats are ordered first by semantics (i.e. float, double, half, etc.), // then by value interpreted as a bitstring (aka APInt). const fltSemantics &SL = L.getSemantics(), &SR = R.getSemantics(); - if (int Res = cmpNumbers(APFloat::semanticsPrecision(SL), - APFloat::semanticsPrecision(SR))) + if (int Res = cmpNumbers(SL.precision, SR.precision)) return Res; - if (int Res = cmpNumbers(APFloat::semanticsMaxExponent(SL), - APFloat::semanticsMaxExponent(SR))) + if (int Res = cmpNumbers(SL.maxExponent, SR.maxExponent)) return Res; - if (int Res = cmpNumbers(APFloat::semanticsMinExponent(SL), - APFloat::semanticsMinExponent(SR))) + if (int Res = cmpNumbers(SL.minExponent, SR.minExponent)) return Res; - if (int Res = cmpNumbers(APFloat::semanticsSizeInBits(SL), - APFloat::semanticsSizeInBits(SR))) + if (int Res = cmpNumbers(SL.sizeInBits, SR.sizeInBits)) return Res; return cmpAPInts(L.bitcastToAPInt(), R.bitcastToAPInt()); } diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp index f291c814886d35..3cee777814e332 100644 --- a/llvm/unittests/ADT/APFloatTest.cpp +++ b/llvm/unittests/ADT/APFloatTest.cpp @@ -832,7 +832,7 @@ TEST(APFloatTest, IsSmallestNormalized) { EXPECT_FALSE(APFloat::getZero(Semantics, false).isSmallestNormalized()); EXPECT_FALSE(APFloat::getZero(Semantics, true).isSmallestNormalized()); - if (APFloat::semanticsHasNaN(Semantics)) { + if (Semantics.hasNaN()) { // Types that do not support Inf will return NaN when asked for Inf. // (But only if they support NaN.) EXPECT_FALSE(APFloat::getInf(Semantics, false).isSmallestNormalized()); @@ -2562,7 +2562,7 @@ TEST(APFloatTest, isInfinity) { for (unsigned I = 0; I != APFloat::S_MaxSemantics + 1; ++I) { const fltSemantics &Semantics = APFloat::EnumToSemantics(static_cast<APFloat::Semantics>(I)); - if (APFloat::semanticsHasInf(Semantics)) { + if (Semantics.hasInf()) { EXPECT_TRUE(APFloat::getInf(Semantics).isInfinity()); } } @@ -2580,7 +2580,7 @@ TEST(APFloatTest, isNaN) { for (unsigned I = 0; I != APFloat::S_MaxSemantics + 1; ++I) { const fltSemantics &Semantics = APFloat::EnumToSemantics(static_cast<APFloat::Semantics>(I)); - if (APFloat::semanticsHasNaN(Semantics)) { + if (Semantics.hasNaN()) { EXPECT_TRUE(APFloat::getNaN(Semantics).isNaN()); } } @@ -7331,9 +7331,9 @@ TEST(APFloatTest, getExactLog2) { continue; } - int MinExp = APFloat::semanticsMinExponent(Semantics); - int MaxExp = APFloat::semanticsMaxExponent(Semantics); - int Precision = APFloat::semanticsPrecision(Semantics); + int MinExp = Semantics.minExponent; + int MaxExp = Semantics.maxExponent; + int Precision = Semantics.precision; EXPECT_EQ(0, One.getExactLog2()); EXPECT_EQ(INT_MIN, APFloat(Semantics, "3.0").getExactLog2()); @@ -7362,7 +7362,7 @@ TEST(APFloatTest, getExactLog2) { EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, false).getExactLog2Abs()); EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, true).getExactLog2Abs()); - if (APFloat::semanticsHasNaN(Semantics)) { + if (Semantics.hasNaN()) { // Types that do not support Inf will return NaN when asked for Inf. // (But only if they support NaN.) EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics).getExactLog2()); @@ -7487,9 +7487,9 @@ TEST(APFloatTest, Float8E8M0FNUGetExactLog2) { EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2()); EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2Abs()); - int MinExp = APFloat::semanticsMinExponent(Semantics); - int MaxExp = APFloat::semanticsMaxExponent(Semantics); - int Precision = APFloat::semanticsPrecision(Semantics); + int MinExp = Semantics.minExponent;; + int MaxExp = Semantics.maxExponent; + int Precision = Semantics.precision; // Values below the minExp getting capped to minExp. EXPECT_EQ(-127, diff --git a/llvm/unittests/IR/ConstantFPRangeTest.cpp b/llvm/unittests/IR/ConstantFPRangeTest.cpp index 255f62d77b748d..cb22abaf56a318 100644 --- a/llvm/unittests/IR/ConstantFPRangeTest.cpp +++ b/llvm/unittests/IR/ConstantFPRangeTest.cpp @@ -90,9 +90,9 @@ static void EnumerateConstantFPRangesImpl(Fn TestFn, bool Exhaustive, SmallVector<APFloat, 36> Values; Values.push_back(APFloat::getInf(Sem, /*Negative=*/true)); Values.push_back(APFloat::getLargest(Sem, /*Negative=*/true)); - unsigned BitWidth = APFloat::semanticsSizeInBits(Sem); - unsigned Exponents = APFloat::semanticsMaxExponent(Sem) - - APFloat::semanticsMinExponent(Sem) + 3; + unsigned BitWidth = Sem.sizeInBits; + unsigned Exponents = Sem.maxExponent - + Sem.minExponent + 3; unsigned MantissaBits = APFloat::semanticsPrecision(Sem) - 1; // Add -2^(max exponent), -2^(max exponent-1), ..., -2^(min exponent) for (unsigned M = Exponents - 2; M != 0; --M) @@ -175,7 +175,7 @@ static void EnumerateValuesInConstantFPRange(const ConstantFPRange &CR, TestFn(Lower); while (Next(Lower)); } else { - unsigned Bits = APFloat::semanticsSizeInBits(Sem); + unsigned Bits = Sem.sizeInBits; assert(Bits < 32 && "Too many bits"); for (unsigned I = 0, E = (1U << Bits) - 1; I != E; ++I) { APFloat V(Sem, APInt(Bits, I)); @@ -217,7 +217,7 @@ static bool AnyOfValueInConstantFPRange(const ConstantFPRange &CR, Fn TestFn, return true; } while (Next(Lower)); } else { - unsigned Bits = APFloat::semanticsSizeInBits(Sem); + unsigned Bits = Sem.sizeInBits; assert(Bits < 32 && "Too many bits"); for (unsigned I = 0, E = (1U << Bits) - 1; I != E; ++I) { APFloat V(Sem, APInt(Bits, I)); diff --git a/mlir/lib/AsmParser/Parser.cpp b/mlir/lib/AsmParser/Parser.cpp index eccb3241012a24..f453d179dbc6ea 100644 --- a/mlir/lib/AsmParser/Parser.cpp +++ b/mlir/lib/AsmParser/Parser.cpp @@ -390,7 +390,7 @@ Parser::parseFloatFromIntegerLiteral(std::optional<APFloat> &result, APInt intValue; tok.getSpelling().getAsInteger(isHex ? 0 : 10, intValue); - auto typeSizeInBits = APFloat::semanticsSizeInBits(semantics); + auto typeSizeInBits = semantics.sizeInBits; if (intValue.getActiveBits() > typeSizeInBits) { return emitError(tok.getLoc(), "hexadecimal float constant out of range for type"); diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp index 9295afd36e3ab1..df750e4222c21e 100644 --- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp +++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp @@ -495,7 +495,7 @@ static Value createLinalgBodyCalculationForElementwiseOp( // Check whether neither int min nor int max can be represented in the // input floating-point type due to too short exponent range. if (static_cast<int>(dstTy.getIntOrFloatBitWidth()) - 1 > - APFloat::semanticsMaxExponent(fltSemantics)) { + fltSemantics.maxExponent) { // Use cmp + select to replace infinites by int min / int max. Other // integral values can be represented in the integer space. auto conv = rewriter.create<arith::FPToSIOp>(loc, dstTy, rounded); diff --git a/mlir/lib/IR/BuiltinTypeInterfaces.cpp b/mlir/lib/IR/BuiltinTypeInterfaces.cpp index c663f6c9094604..478cdec8df437c 100644 --- a/mlir/lib/IR/BuiltinTypeInterfaces.cpp +++ b/mlir/lib/IR/BuiltinTypeInterfaces.cpp @@ -25,11 +25,11 @@ using namespace mlir::detail; //===----------------------------------------------------------------------===// unsigned FloatType::getWidth() { - return APFloat::semanticsSizeInBits(getFloatSemantics()); + return getFloatSemantics().sizeInBits; } unsigned FloatType::getFPMantissaWidth() { - return APFloat::semanticsPrecision(getFloatSemantics()); + return getFloatSemantics().precision; } //===----------------------------------------------------------------------===// _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits