[libc-commits] [libc] [libc] Provide isnan, isnanf and isnanl functions (PR #96008)

Petr Hosek via libc-commits libc-commits at lists.llvm.org
Tue Jun 18 16:45:04 PDT 2024


https://github.com/petrhosek created https://github.com/llvm/llvm-project/pull/96008

While C99 defines type generic isnan macro, BSD provided isnan, isnanf and isnanl in prior C standards and existing code still relies on these.

>From d69e5ce6c5137992560746ec57f1fc05e3e44431 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Tue, 18 Jun 2024 16:28:57 -0700
Subject: [PATCH] [libc] Provide isnan, isnanf and isnanl functions

While C99 defines type generic isnan macro, BSD provided isnan, isnanf
and isnanl in prior C standards and existing code still relies on these.
---
 libc/config/baremetal/arm/entrypoints.txt   |  3 +++
 libc/config/baremetal/riscv/entrypoints.txt |  3 +++
 libc/include/llvm-libc-macros/math-macros.h |  1 -
 libc/include/math.h.def                     |  2 ++
 libc/spec/bsd_ext.td                        | 13 +++++++++
 libc/src/math/CMakeLists.txt                |  4 +++
 libc/src/math/generic/CMakeLists.txt        | 30 +++++++++++++++++++++
 libc/src/math/generic/isnan.cpp             | 18 +++++++++++++
 libc/src/math/generic/isnanf.cpp            | 18 +++++++++++++
 libc/src/math/generic/isnanl.cpp            | 18 +++++++++++++
 libc/src/math/isnan.h                       | 18 +++++++++++++
 libc/src/math/isnanf.h                      | 18 +++++++++++++
 libc/src/math/isnanl.h                      | 18 +++++++++++++
 13 files changed, 163 insertions(+), 1 deletion(-)
 create mode 100644 libc/src/math/generic/isnan.cpp
 create mode 100644 libc/src/math/generic/isnanf.cpp
 create mode 100644 libc/src/math/generic/isnanl.cpp
 create mode 100644 libc/src/math/isnan.h
 create mode 100644 libc/src/math/isnanf.h
 create mode 100644 libc/src/math/isnanl.h

diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 7fb82c60a1bb8..9e6999fccc1ed 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -261,6 +261,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.ilogb
     libc.src.math.ilogbf
     libc.src.math.ilogbl
+    libc.src.math.isnan
+    libc.src.math.isnanf
+    libc.src.math.isnanl
     libc.src.math.ldexp
     libc.src.math.ldexpf
     libc.src.math.ldexpl
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index b769b43f03a2c..dffc6af88929e 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -260,6 +260,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.ilogb
     libc.src.math.ilogbf
     libc.src.math.ilogbl
+    libc.src.math.isnan
+    libc.src.math.isnanf
+    libc.src.math.isnanl
     libc.src.math.ldexp
     libc.src.math.ldexpf
     libc.src.math.ldexpl
diff --git a/libc/include/llvm-libc-macros/math-macros.h b/libc/include/llvm-libc-macros/math-macros.h
index 47838969d59ae..30e826e769306 100644
--- a/libc/include/llvm-libc-macros/math-macros.h
+++ b/libc/include/llvm-libc-macros/math-macros.h
@@ -54,6 +54,5 @@
 // TODO: Move generic functional math macros to a separate header file.
 #define isfinite(x) __builtin_isfinite(x)
 #define isinf(x) __builtin_isinf(x)
-#define isnan(x) __builtin_isnan(x)
 
 #endif // LLVM_LIBC_MACROS_MATH_MACROS_H
diff --git a/libc/include/math.h.def b/libc/include/math.h.def
index 454b8f2980514..3ec52e77856d4 100644
--- a/libc/include/math.h.def
+++ b/libc/include/math.h.def
@@ -17,4 +17,6 @@
 
 %%public_api()
 
+#define isnan(x) __builtin_isnan(x)
+
 #endif // LLVM_LIBC_MATH_H
diff --git a/libc/spec/bsd_ext.td b/libc/spec/bsd_ext.td
index 50ca8b919ff2c..4d33313521735 100644
--- a/libc/spec/bsd_ext.td
+++ b/libc/spec/bsd_ext.td
@@ -1,4 +1,16 @@
 def BsdExtensions : StandardSpec<"BSDExtensions"> {
+  HeaderSpec Math = HeaderSpec<
+      "math.h",
+      [], // Macros
+      [], // Types
+      [], // Enumerations
+      [
+          FunctionSpec<"isnan", RetValSpec<IntType>, [ArgSpec<DoubleType>]>,
+          FunctionSpec<"isnanf", RetValSpec<IntType>, [ArgSpec<FloatType>]>,
+          FunctionSpec<"isnanl", RetValSpec<IntType>, [ArgSpec<LongDoubleType>]>,
+      ]
+  >;
+
   HeaderSpec String = HeaderSpec<
       "string.h",
       [], // Macros
@@ -67,6 +79,7 @@ def BsdExtensions : StandardSpec<"BSDExtensions"> {
   >;
 
   let Headers = [
+    Math,
     String,
     Strings,
     SysWait,
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 4472367d6c073..ca833f3a872f4 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -219,6 +219,10 @@ add_math_entrypoint_object(ilogbl)
 add_math_entrypoint_object(ilogbf16)
 add_math_entrypoint_object(ilogbf128)
 
+add_math_entrypoint_object(isnan)
+add_math_entrypoint_object(isnanf)
+add_math_entrypoint_object(isnanl)
+
 add_math_entrypoint_object(llogb)
 add_math_entrypoint_object(llogbf)
 add_math_entrypoint_object(llogbl)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index aa0069d821d0d..9d99879488be5 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -2684,6 +2684,36 @@ add_entrypoint_object(
     -O3
 )
 
+add_entrypoint_object(
+  isnan
+  SRCS
+    isnan.cpp
+  HDRS
+    ../isnan.h
+  COMPILE_OPTIONS
+    -O3
+)
+
+add_entrypoint_object(
+  isnanf
+  SRCS
+    isnanf.cpp
+  HDRS
+    ../isnanf.h
+  COMPILE_OPTIONS
+    -O3
+)
+
+add_entrypoint_object(
+  isnanl
+  SRCS
+    isnanl.cpp
+  HDRS
+    ../isnanl.h
+  COMPILE_OPTIONS
+    -O3
+)
+
 add_entrypoint_object(
   nan
   SRCS
diff --git a/libc/src/math/generic/isnan.cpp b/libc/src/math/generic/isnan.cpp
new file mode 100644
index 0000000000000..5406a69f68217
--- /dev/null
+++ b/libc/src/math/generic/isnan.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of isnan function ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/isnan.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, isnan, (double x)) {
+  return __builtin_isnan(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/isnanf.cpp b/libc/src/math/generic/isnanf.cpp
new file mode 100644
index 0000000000000..2d9339360713b
--- /dev/null
+++ b/libc/src/math/generic/isnanf.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of isnanf function ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/isnanf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, isnanf, (float x)) {
+  return __builtin_isnan(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/isnanl.cpp b/libc/src/math/generic/isnanl.cpp
new file mode 100644
index 0000000000000..a700b636d0149
--- /dev/null
+++ b/libc/src/math/generic/isnanl.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of isnanl function ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/isnanl.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, isnanl, (long double x)) {
+  return __builtin_isnan(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/isnan.h b/libc/src/math/isnan.h
new file mode 100644
index 0000000000000..eda8e7eb30f39
--- /dev/null
+++ b/libc/src/math/isnan.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for isnan -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_ISNAN_H
+#define LLVM_LIBC_SRC_MATH_ISNAN_H
+
+namespace LIBC_NAMESPACE {
+
+int isnan(double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ISNAN_H
diff --git a/libc/src/math/isnanf.h b/libc/src/math/isnanf.h
new file mode 100644
index 0000000000000..a12d39ee5af97
--- /dev/null
+++ b/libc/src/math/isnanf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for isnanf ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_ISNANF_H
+#define LLVM_LIBC_SRC_MATH_ISNANF_H
+
+namespace LIBC_NAMESPACE {
+
+int isnanf(float x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ISNANF_H
diff --git a/libc/src/math/isnanl.h b/libc/src/math/isnanl.h
new file mode 100644
index 0000000000000..9fbfca03cb15e
--- /dev/null
+++ b/libc/src/math/isnanl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for isnanl ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_ISNANL_H
+#define LLVM_LIBC_SRC_MATH_ISNANL_H
+
+namespace LIBC_NAMESPACE {
+
+int isnanl(long double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ISNANL_H



More information about the libc-commits mailing list