[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