From fa05109170f38aa8257f77952f2c7e15cb4c8df7 Mon Sep 17 00:00:00 2001 From: OverMighty Date: Fri, 7 Jun 2024 18:27:28 +0200 Subject: [PATCH] [libc][math][c23] Add nanf16 C23 math function --- libc/config/linux/aarch64/entrypoints.txt | 1 + libc/config/linux/x86_64/entrypoints.txt | 1 + libc/docs/math/index.rst | 2 +- libc/include/llvm-libc-types/CMakeLists.txt | 2 +- libc/spec/stdc.td | 1 + libc/src/math/CMakeLists.txt | 1 + libc/src/math/generic/CMakeLists.txt | 13 ++++++ libc/src/math/generic/nanf16.cpp | 23 ++++++++++ libc/src/math/nanf16.h | 20 ++++++++ libc/test/src/math/smoke/CMakeLists.txt | 16 +++++++ libc/test/src/math/smoke/nanf16_test.cpp | 51 +++++++++++++++++++++ 11 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 libc/src/math/generic/nanf16.cpp create mode 100644 libc/src/math/nanf16.h create mode 100644 libc/test/src/math/smoke/nanf16_test.cpp diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 33ecff813a1fb..6a82f5c3a8f88 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -521,6 +521,7 @@ if(LIBC_TYPES_HAS_FLOAT16) libc.src.math.llroundf16 libc.src.math.lrintf16 libc.src.math.lroundf16 + libc.src.math.nanf16 libc.src.math.nearbyintf16 libc.src.math.nextafterf16 libc.src.math.nextdownf16 diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index e3ca544ae0185..d8e4e40e8b3a0 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -553,6 +553,7 @@ if(LIBC_TYPES_HAS_FLOAT16) libc.src.math.llroundf16 libc.src.math.lrintf16 libc.src.math.lroundf16 + libc.src.math.nanf16 libc.src.math.nearbyintf16 libc.src.math.nextafterf16 libc.src.math.nextdownf16 diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst index b9507f0887cd7..8d011edaae254 100644 --- a/libc/docs/math/index.rst +++ b/libc/docs/math/index.rst @@ -186,7 +186,7 @@ Basic Operations +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | modf | |check| | |check| | |check| | | |check| | 7.12.6.18 | F.10.3.18 | +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| nan | |check| | |check| | |check| | | |check| | 7.12.11.2 | F.10.8.2 | +| nan | |check| | |check| | |check| | |check| | |check| | 7.12.11.2 | F.10.8.2 | +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | nearbyint | |check| | |check| | |check| | |check| | |check| | 7.12.9.3 | F.10.6.3 | +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index ee2c910b85b00..356ac037770d2 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -58,7 +58,7 @@ add_header(pthread_rwlockattr_t HDR pthread_rwlockattr_t.h) add_header(pthread_t HDR pthread_t.h DEPENDS .__thread_type) add_header(rlim_t HDR rlim_t.h) add_header(time_t HDR time_t.h) -add_header(stack_t HDR stack_t.h) +add_header(stack_t HDR stack_t.h DEPENDS .size_t) add_header(suseconds_t HDR suseconds_t.h) add_header(struct_flock HDR struct_flock.h DEPENDS .off_t .pid_t) add_header(struct_flock64 HDR struct_flock64.h DEPENDS .off64_t .pid_t) diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index 9a436c8ae38d2..d56bb898aa9c2 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -690,6 +690,7 @@ def StdC : StandardSpec<"stdc"> { FunctionSpec<"nanf", RetValSpec, [ArgSpec]>, FunctionSpec<"nan", RetValSpec, [ArgSpec]>, FunctionSpec<"nanl", RetValSpec, [ArgSpec]>, + GuardedFunctionSpec<"nanf16", RetValSpec, [ArgSpec], "LIBC_TYPES_HAS_FLOAT16">, GuardedFunctionSpec<"nanf128", RetValSpec, [ArgSpec], "LIBC_TYPES_HAS_FLOAT128">, FunctionSpec<"canonicalize", RetValSpec, [ArgSpec, ArgSpec]>, diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index 7a349ddc53724..a5a64d414ad09 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -269,6 +269,7 @@ add_math_entrypoint_object(modff128) add_math_entrypoint_object(nan) add_math_entrypoint_object(nanf) add_math_entrypoint_object(nanl) +add_math_entrypoint_object(nanf16) add_math_entrypoint_object(nanf128) add_math_entrypoint_object(nearbyint) diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index b1d786fc6b29f..81ce626bb1f50 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -2603,6 +2603,19 @@ add_entrypoint_object( -O3 ) +add_entrypoint_object( + nanf16 + SRCS + nanf16.cpp + HDRS + ../nanf16.h + DEPENDS + libc.src.__support.str_to_float + libc.src.errno.errno + COMPILE_OPTIONS + -O3 +) + add_entrypoint_object( nanf128 SRCS diff --git a/libc/src/math/generic/nanf16.cpp b/libc/src/math/generic/nanf16.cpp new file mode 100644 index 0000000000000..c42cd25fe3ef0 --- /dev/null +++ b/libc/src/math/generic/nanf16.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of nanf16 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/nanf16.h" +#include "src/__support/common.h" +#include "src/__support/str_to_float.h" +#include "src/errno/libc_errno.h" + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(float16, nanf16, (const char *arg)) { + auto result = internal::strtonan(arg); + if (result.has_error()) + libc_errno = result.error; + return result.value; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/math/nanf16.h b/libc/src/math/nanf16.h new file mode 100644 index 0000000000000..c2db4bac0a155 --- /dev/null +++ b/libc/src/math/nanf16.h @@ -0,0 +1,20 @@ +//===-- Implementation header for nanf16 ------------------------*- 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_NANF16_H +#define LLVM_LIBC_SRC_MATH_NANF16_H + +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE { + +float16 nanf16(const char *arg); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_MATH_NANF16_H diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index 110fa1de97d6d..c2e464198fd9c 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -2609,6 +2609,22 @@ add_fp_unittest( UNIT_TEST_ONLY ) +add_fp_unittest( + nanf16_test + SUITE + libc-math-smoke-tests + SRCS + nanf16_test.cpp + DEPENDS + libc.include.signal + libc.src.math.nanf16 + libc.src.__support.FPUtil.fp_bits + libc.src.__support.macros.sanitizer + # FIXME: The nan tests currently have death tests, which aren't supported for + # hermetic tests. + UNIT_TEST_ONLY +) + add_fp_unittest( nanf128_test SUITE diff --git a/libc/test/src/math/smoke/nanf16_test.cpp b/libc/test/src/math/smoke/nanf16_test.cpp new file mode 100644 index 0000000000000..ec17a73d881aa --- /dev/null +++ b/libc/test/src/math/smoke/nanf16_test.cpp @@ -0,0 +1,51 @@ +//===-- Unittests for nanf16 ----------------------------------------------===// +// +// 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/__support/FPUtil/FPBits.h" +#include "src/__support/macros/sanitizer.h" +#include "src/math/nanf16.h" +#include "test/UnitTest/FEnvSafeTest.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" + +#include + +class LlvmLibcNanf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest { +public: + using StorageType = LIBC_NAMESPACE::fputil::FPBits::StorageType; + + void run_test(const char *input_str, StorageType bits) { + float16 result = LIBC_NAMESPACE::nanf16(input_str); + auto actual_fp = LIBC_NAMESPACE::fputil::FPBits(result); + auto expected_fp = LIBC_NAMESPACE::fputil::FPBits(bits); + EXPECT_EQ(actual_fp.uintval(), expected_fp.uintval()); + }; +}; + +TEST_F(LlvmLibcNanf16Test, NCharSeq) { + run_test("", 0x7e00); + run_test("123", 0x7e7b); + run_test("0x123", 0x7f23); + run_test("1a", 0x7e00); + run_test("1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_", + 0x7e00); + run_test("10000000000000000000000000000000000000000000000000", 0x7e00); +} + +TEST_F(LlvmLibcNanf16Test, RandomString) { + run_test(" 1234", 0x7e00); + run_test("-1234", 0x7e00); + run_test("asd&f", 0x7e00); + run_test("123 ", 0x7e00); +} + +#ifndef LIBC_HAVE_ADDRESS_SANITIZER +TEST_F(LlvmLibcNanf16Test, InvalidInput) { + EXPECT_DEATH([] { LIBC_NAMESPACE::nanf16(nullptr); }, WITH_SIGNAL(SIGSEGV)); +} +#endif // LIBC_HAVE_ADDRESS_SANITIZER