================
@@ -132,6 +133,70 @@ template <> struct 
llvm::DenseMapInfo<llvm::FoldingSetNodeID> {
     return LHS == RHS;
   }
 };
+constexpr unsigned CXX23FloatRankToIndex(clang::BuiltinType::Kind Kind) {
+  switch (Kind) {
+  case clang::BuiltinType::Float16:
+    return 0;
+  case clang::BuiltinType::BFloat16:
+    return 1;
+  case clang::BuiltinType::Float:
+    return 2;
+  case clang::BuiltinType::Double:
+    return 3;
+  case clang::BuiltinType::LongDouble:
+    return 4;
+  default:
+    // Both __float128 and __ibm128 are compiler extensions, not extended 
floating points.
+    // __float128 also predates the invention of floating-point types.
+    llvm_unreachable("Not a CXX23+ floating point builtin type");
+  }
+}
+
+// C++23 6.8.6p2 [conv.rank]
+FloatConvRankCompareResult
+CXX23CompareFpConversionRanks(BuiltinType::Kind LHSKind,
+                              BuiltinType::Kind RHSKind, QualType LHS,
+                              QualType RHS, const ASTContext &Ctx) {
+
+  // Same types.
+  if (LHSKind == RHSKind)
+    return FloatConvRankCompareResult::FRCR_Equal;
+
+  // Special case comparision between float, double and long double.
+  if (LHSKind == BuiltinType::Float && RHSKind == BuiltinType::Double)
+    return FloatConvRankCompareResult::FRCR_Lesser;
+  if (LHSKind == BuiltinType::Double && RHSKind == BuiltinType::Float)
+    return FloatConvRankCompareResult::FRCR_Greater;
+  if (LHSKind == BuiltinType::Float && RHSKind == BuiltinType::LongDouble)
+    return FloatConvRankCompareResult::FRCR_Lesser;
+  if (LHSKind == BuiltinType::LongDouble && RHSKind == BuiltinType::Float)
+    return FloatConvRankCompareResult::FRCR_Greater;
+  if (LHSKind == BuiltinType::Double && RHSKind == BuiltinType::LongDouble)
+    return FloatConvRankCompareResult::FRCR_Lesser;
+  if (LHSKind == BuiltinType::LongDouble && RHSKind == BuiltinType::Double)
+    return FloatConvRankCompareResult::FRCR_Greater;
+
+  const llvm::fltSemantics &LHSSemantics = Ctx.getFloatTypeSemantics(LHS);
+  const llvm::fltSemantics &RHSSemantics = Ctx.getFloatTypeSemantics(RHS);
+
+  bool LHSRepresentableByRHS =
+      llvm::APFloat::isRepresentableBy(LHSSemantics, RHSSemantics);
+  bool RHSRepresentableByLHS =
+      llvm::APFloat::isRepresentableBy(RHSSemantics, LHSSemantics);
----------------
jcranmer-intel wrote:

If you look at the definition of `fltSemantics::isRepresentableBy`, it doesn't 
precisely match the definition of 2.1, since that requires the set of values of 
one type to be a proper subset of the other, and the function is only checking 
finite, nonzero values. That said, the distinction is only going to be relevant 
for the weird tiny FP types, which I hope do not become extended floating-point 
types, so it probably doesn't matter.

Where it does matter is I think the `ppc_fp128` semantics return bogus values 
that don't reflect the reality, so that the conversion rank of `long double` 
and `_Float16` is going to come out wrong on systems where `long double` is 
`ppc_fp128`.

https://github.com/llvm/llvm-project/pull/78503
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to