From 85363400d5c2ceedf9931e8473b56fd7f9df6933 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Tue, 18 Jun 2024 16:28:57 -0700 Subject: [PATCH 1/4] [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 b8e97783c7723..fdc65a6c745d1 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 c9070c2691b19..c58996c250af4 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 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, [ArgSpec]>, + FunctionSpec<"isnanf", RetValSpec, [ArgSpec]>, + FunctionSpec<"isnanl", RetValSpec, [ArgSpec]>, + ] + >; + 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 711cbf8bbfdca..7fbf056430ace 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 5fe3b8f7b4ad3..18ca87b2c0ade 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 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 From a5fcc6be13f04fbb774ea75ef27249cc1a871cad Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Wed, 3 Jul 2024 01:27:15 -0700 Subject: [PATCH 2/4] 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 f23b3da06308c..77c02d4a9adbf 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 7ef5ed899e83f..2c9828cc72e9b 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 bea2eb32eccd9..e9440c040d21c 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 0000000000000..551719af2b4dd --- /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 30e826e769306..bcda32a615b62 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 3ec52e77856d4..9822d8bd7ba17 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 From 5498164cf87b44ea9883e4077002b7139d9e6d7d Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Wed, 3 Jul 2024 01:51:05 -0700 Subject: [PATCH 3/4] CMake setup for math-function-macros.h --- libc/include/CMakeLists.txt | 1 + libc/include/llvm-libc-macros/CMakeLists.txt | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index 3ab7817d8568b..3d765417d3a3c 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -113,6 +113,7 @@ add_gen_header( .llvm_libc_common_h .llvm-libc-macros.float16_macros .llvm-libc-macros.math_macros + .llvm-libc-macros.math_function_macros .llvm-libc-types.double_t .llvm-libc-types.float_t .llvm-libc-types.float128 diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt index f6af11abd4dd7..7fcf7b7593088 100644 --- a/libc/include/llvm-libc-macros/CMakeLists.txt +++ b/libc/include/llvm-libc-macros/CMakeLists.txt @@ -117,6 +117,12 @@ add_macro_header( .limits_macros ) +add_macro_header( + math_function_macros + HDR + math-function-macros.h +) + add_macro_header( offsetof_macro HDR From 285e85a1dd211ae51bc8cb82ba2471b2b64d56b2 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Tue, 9 Jul 2024 21:24:13 -0700 Subject: [PATCH 4/4] Fix formatting --- libc/src/math/generic/isnan.cpp | 4 +--- libc/src/math/generic/isnanf.cpp | 4 +--- libc/src/math/generic/isnanl.cpp | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/libc/src/math/generic/isnan.cpp b/libc/src/math/generic/isnan.cpp index 5406a69f68217..dd7eadb2a2031 100644 --- a/libc/src/math/generic/isnan.cpp +++ b/libc/src/math/generic/isnan.cpp @@ -11,8 +11,6 @@ namespace LIBC_NAMESPACE { -LLVM_LIBC_FUNCTION(int, isnan, (double x)) { - return __builtin_isnan(x); -} +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 index 2d9339360713b..98a81b03f538a 100644 --- a/libc/src/math/generic/isnanf.cpp +++ b/libc/src/math/generic/isnanf.cpp @@ -11,8 +11,6 @@ namespace LIBC_NAMESPACE { -LLVM_LIBC_FUNCTION(int, isnanf, (float x)) { - return __builtin_isnan(x); -} +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 index a700b636d0149..d61bfd52f0b7d 100644 --- a/libc/src/math/generic/isnanl.cpp +++ b/libc/src/math/generic/isnanl.cpp @@ -11,8 +11,6 @@ namespace LIBC_NAMESPACE { -LLVM_LIBC_FUNCTION(int, isnanl, (long double x)) { - return __builtin_isnan(x); -} +LLVM_LIBC_FUNCTION(int, isnanl, (long double x)) { return __builtin_isnan(x); } } // namespace LIBC_NAMESPACE