[llvm] [llvm] `APFloat`: Add helpers to query NaN/inf semantics (PR #116315)

Matthias Springer via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 14 17:59:29 PST 2024


https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/116315

None

>From 64568e53598b93407864583d0713376a61801312 Mon Sep 17 00:00:00 2001
From: Matthias Springer <mspringer at nvidia.com>
Date: Fri, 15 Nov 2024 02:58:43 +0100
Subject: [PATCH] [llvm] `APFloat`: Add helpers to query NaN/inf semantics

---
 llvm/include/llvm/ADT/APFloat.h    |  3 ++-
 llvm/lib/Support/APFloat.cpp       |  7 ++++++-
 llvm/unittests/ADT/APFloatTest.cpp | 22 ++++++++++++++++++++--
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index 4b5a85945ec17c..4ca928bf4f49e3 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -311,7 +311,8 @@ struct APFloatBase {
   static unsigned int semanticsIntSizeInBits(const fltSemantics&, bool);
   static bool semanticsHasZero(const fltSemantics &);
   static bool semanticsHasSignedRepr(const fltSemantics &);
-  static bool semanticsHasNanOrInf(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.
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 58bf002e0fed2e..c6334031235d4a 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -375,7 +375,12 @@ bool APFloatBase::semanticsHasSignedRepr(const fltSemantics &semantics) {
   return semantics.hasSignedRepr;
 }
 
-bool APFloatBase::semanticsHasNanOrInf(const fltSemantics &semantics) {
+bool APFloatBase::semanticsHasInf(const fltSemantics &semantics) {
+  return semantics.nonFiniteBehavior != fltNonfiniteBehavior::NanOnly
+      && semantics.nonFiniteBehavior != fltNonfiniteBehavior::FiniteOnly;
+}
+
+bool APFloatBase::semanticsHasNaN(const fltSemantics &semantics) {
   return semantics.nonFiniteBehavior != fltNonfiniteBehavior::FiniteOnly;
 }
 
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index ab9db8ed0fa85c..d818b13e2a7e07 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -832,8 +832,9 @@ TEST(APFloatTest, IsSmallestNormalized) {
     EXPECT_FALSE(APFloat::getZero(Semantics, false).isSmallestNormalized());
     EXPECT_FALSE(APFloat::getZero(Semantics, true).isSmallestNormalized());
 
-    if (APFloat::semanticsHasNanOrInf(Semantics)) {
+    if (APFloat::semanticsHasNaN(Semantics)) {
       // 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());
       EXPECT_FALSE(APFloat::getInf(Semantics, true).isSmallestNormalized());
 
@@ -2557,6 +2558,14 @@ TEST(APFloatTest, isInfinity) {
   EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isInfinity());
   EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isInfinity());
   EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isInfinity());
+
+  for (unsigned I = 0; I != APFloat::S_MaxSemantics + 1; ++I) {
+    const fltSemantics &Semantics =
+        APFloat::EnumToSemantics(static_cast<APFloat::Semantics>(I));
+    if (APFloat::semanticsHasInf(fltSemantics)) {
+      EXPECT_TRUE(APFloat::getInf(fltSemantics).isInfinity());
+    }
+  }
 }
 
 TEST(APFloatTest, isNaN) {
@@ -2567,6 +2576,14 @@ TEST(APFloatTest, isNaN) {
   EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNaN());
   EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNaN());
   EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isNaN());
+
+  for (unsigned I = 0; I != APFloat::S_MaxSemantics + 1; ++I) {
+    const fltSemantics &Semantics =
+        APFloat::EnumToSemantics(static_cast<APFloat::Semantics>(I));
+    if (APFloat::semanticsHasNaN(fltSemantics)) {
+      EXPECT_TRUE(APFloat::getNaN(fltSemantics).isNaN());
+    }
+  }
 }
 
 TEST(APFloatTest, isFiniteNonZero) {
@@ -7345,8 +7362,9 @@ TEST(APFloatTest, getExactLog2) {
     EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, false).getExactLog2Abs());
     EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, true).getExactLog2Abs());
 
-    if (APFloat::semanticsHasNanOrInf(Semantics)) {
+    if (APFloat::semanticsHasNaN(Semantics)) {
       // 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());
       EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics, true).getExactLog2());
       EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, false).getExactLog2());



More information about the llvm-commits mailing list