diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index adfc1d23a1e38e..ee86822d96d912 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -522,6 +522,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 e86274ac34b2fa..c4b3b1aece639f 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -555,6 +555,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 ee2e7643c34119..43f63e910750f1 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 ee2c910b85b000..356ac037770d25 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 38521f5d364b97..ac16041e44c99d 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -695,6 +695,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 e6cb8fd6159714..68b8924460bf49 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -272,6 +272,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 97740834fb0293..4f94468939ed86 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -2631,6 +2631,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 00000000000000..c42cd25fe3ef0c --- /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 00000000000000..c2db4bac0a1551 --- /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 dfda1bc2457e08..cc0e00aeb1dd25 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -2636,6 +2636,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 00000000000000..ec17a73d881aa6 --- /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