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

Petr Hosek via libc-commits libc-commits at lists.llvm.org
Wed Jul 3 01:40:00 PDT 2024


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

>From 85363400d5c2ceedf9931e8473b56fd7f9df6933 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 1/2] [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 b8e97783c77237..fdc65a6c745d13 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -273,6 +273,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 c9070c2691b192..c58996c250af47 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -268,6 +268,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 47838969d59aed..30e826e7693060 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 454b8f29805145..3ec52e77856d45 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 50ca8b919ff2c5..4d33313521735e 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 711cbf8bbfdca6..7fbf056430ace0 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -223,6 +223,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 5fe3b8f7b4ad3c..18ca87b2c0ade2 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -2791,6 +2791,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 00000000000000..5406a69f682171
--- /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 00000000000000..2d9339360713bd
--- /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 00000000000000..a700b636d01498
--- /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 00000000000000..eda8e7eb30f39b
--- /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 00000000000000..a12d39ee5af971
--- /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 00000000000000..9fbfca03cb15e6
--- /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

>From a5fcc6be13f04fbb774ea75ef27249cc1a871cad Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Wed, 3 Jul 2024 01:27:15 -0700
Subject: [PATCH 2/2] Address review feedback

---
 libc/config/linux/aarch64/entrypoints.txt        |  3 +++
 libc/config/linux/riscv/entrypoints.txt          |  3 +++
 libc/config/linux/x86_64/entrypoints.txt         |  3 +++
 .../llvm-libc-macros/math-function-macros.h      | 16 ++++++++++++++++
 libc/include/llvm-libc-macros/math-macros.h      |  4 ----
 libc/include/math.h.def                          |  3 ++-
 6 files changed, 27 insertions(+), 5 deletions(-)
 create mode 100644 libc/include/llvm-libc-macros/math-function-macros.h

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index f23b3da06308cd..77c02d4a9adbf5 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -414,6 +414,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.llogb
     libc.src.math.llogbf
     libc.src.math.llogbl
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 7ef5ed899e83ff..2c9828cc72e9b9 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -422,6 +422,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/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index bea2eb32eccd94..e9440c040d21c9 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -440,6 +440,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-function-macros.h b/libc/include/llvm-libc-macros/math-function-macros.h
new file mode 100644
index 00000000000000..551719af2b4ddf
--- /dev/null
+++ b/libc/include/llvm-libc-macros/math-function-macros.h
@@ -0,0 +1,16 @@
+//===-- Definition of function macros from math.h -------------------------===//
+//
+// 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_MACROS_MATH_FUNCTION_MACROS_H
+#define LLVM_LIBC_MACROS_MATH_FUNCTION_MACROS_H
+
+#define isfinite(x) __builtin_isfinite(x)
+#define isinf(x) __builtin_isinf(x)
+#define isnan(x) __builtin_isnan(x)
+
+#endif // LLVM_LIBC_MACROS_MATH_FUNCTION_MACROS_H
diff --git a/libc/include/llvm-libc-macros/math-macros.h b/libc/include/llvm-libc-macros/math-macros.h
index 30e826e7693060..bcda32a615b628 100644
--- a/libc/include/llvm-libc-macros/math-macros.h
+++ b/libc/include/llvm-libc-macros/math-macros.h
@@ -51,8 +51,4 @@
 #define math_errhandling (MATH_ERRNO | MATH_ERREXCEPT)
 #endif
 
-// TODO: Move generic functional math macros to a separate header file.
-#define isfinite(x) __builtin_isfinite(x)
-#define isinf(x) __builtin_isinf(x)
-
 #endif // LLVM_LIBC_MACROS_MATH_MACROS_H
diff --git a/libc/include/math.h.def b/libc/include/math.h.def
index 3ec52e77856d45..9822d8bd7ba173 100644
--- a/libc/include/math.h.def
+++ b/libc/include/math.h.def
@@ -17,6 +17,7 @@
 
 %%public_api()
 
-#define isnan(x) __builtin_isnan(x)
+
+#include "llvm-libc-macros/math-function-macros.h"
 
 #endif // LLVM_LIBC_MATH_H



More information about the libc-commits mailing list