[Lldb-commits] [clang] [clang-tools-extra] [flang] [lldb] [llvm] [mlir] [experiment] Make `fltSemantics` public (PR #123374)

Matthias Springer via lldb-commits lldb-commits at lists.llvm.org
Fri Jan 17 09:08:49 PST 2025


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 <mspringer at 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;
 }
 
 //===----------------------------------------------------------------------===//



More information about the lldb-commits mailing list