[libc-commits] [libc] [llvm] [libc][math] Implement nan(f|l) functions (PR #76690)

via libc-commits libc-commits at lists.llvm.org
Mon Jan 1 12:20:53 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Nishant Mittal (nishantwrp)

<details>
<summary>Changes</summary>



---

Patch is 21.78 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/76690.diff


23 Files Affected:

- (modified) libc/config/darwin/arm/entrypoints.txt (+3) 
- (modified) libc/config/darwin/x86_64/entrypoints.txt (+3) 
- (modified) libc/config/gpu/entrypoints.txt (+2) 
- (modified) libc/config/linux/aarch64/entrypoints.txt (+3) 
- (modified) libc/config/linux/riscv/entrypoints.txt (+3) 
- (modified) libc/config/linux/x86_64/entrypoints.txt (+3) 
- (modified) libc/config/windows/entrypoints.txt (+3) 
- (modified) libc/docs/math/index.rst (+3-3) 
- (modified) libc/spec/stdc.td (+4) 
- (modified) libc/src/__support/str_to_float.h (+28) 
- (modified) libc/src/math/CMakeLists.txt (+4) 
- (modified) libc/src/math/generic/CMakeLists.txt (+39) 
- (added) libc/src/math/generic/nan.cpp (+26) 
- (added) libc/src/math/generic/nanf.cpp (+26) 
- (added) libc/src/math/generic/nanl.cpp (+26) 
- (added) libc/src/math/nan.h (+18) 
- (added) libc/src/math/nanf.h (+18) 
- (added) libc/src/math/nanl.h (+18) 
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+36) 
- (added) libc/test/src/math/smoke/nan_test.cpp (+40) 
- (added) libc/test/src/math/smoke/nanf_test.cpp (+40) 
- (added) libc/test/src/math/smoke/nanl_test.cpp (+64) 
- (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+6) 


``````````diff
diff --git a/libc/config/darwin/arm/entrypoints.txt b/libc/config/darwin/arm/entrypoints.txt
index da4a2345f389c4..02a09256606956 100644
--- a/libc/config/darwin/arm/entrypoints.txt
+++ b/libc/config/darwin/arm/entrypoints.txt
@@ -193,6 +193,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.modf
     libc.src.math.modff
     libc.src.math.modfl
+    libc.src.math.nan
+    libc.src.math.nanf
+    libc.src.math.nanl
     libc.src.math.nearbyint
     libc.src.math.nearbyintf
     libc.src.math.nearbyintl
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index e29e75ec92dadc..91493cb77b1d86 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -172,6 +172,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     #libc.src.math.modf
     #libc.src.math.modff
     #libc.src.math.modfl
+    #libc.src.math.nan
+    #libc.src.math.nanf
+    #libc.src.math.nanl
     #libc.src.math.nearbyint
     #libc.src.math.nearbyintf
     #libc.src.math.nearbyintl
diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index ba86e31ee0adcd..b333c6be144627 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -215,6 +215,8 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.lroundf
     libc.src.math.modf
     libc.src.math.modff
+    libc.src.math.nan
+    libc.src.math.nanf
     libc.src.math.nearbyint
     libc.src.math.nearbyintf
     libc.src.math.nextafter
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 77c9a50b8b7e5d..ce3f5eb40e38aa 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -313,6 +313,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.modf
     libc.src.math.modff
     libc.src.math.modfl
+    libc.src.math.nan
+    libc.src.math.nanf
+    libc.src.math.nanl
     libc.src.math.nearbyint
     libc.src.math.nearbyintf
     libc.src.math.nearbyintl
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index e389936ffca1ef..ec2a16f5cf473b 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -322,6 +322,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.modf
     libc.src.math.modff
     libc.src.math.modfl
+    libc.src.math.nan
+    libc.src.math.nanf
+    libc.src.math.nanl
     libc.src.math.nearbyint
     libc.src.math.nearbyintf
     libc.src.math.nearbyintl
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 3adcd57d0c0849..30900de365bf95 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -323,6 +323,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.modf
     libc.src.math.modff
     libc.src.math.modfl
+    libc.src.math.nan
+    libc.src.math.nanf
+    libc.src.math.nanl
     libc.src.math.nearbyint
     libc.src.math.nearbyintf
     libc.src.math.nearbyintl
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 4c0a6ec37fe4cc..5c3a2e287b9529 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -192,6 +192,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.modf
     libc.src.math.modff
     libc.src.math.modfl
+    libc.src.math.nan
+    libc.src.math.nanf
+    libc.src.math.nanl
     libc.src.math.nearbyint
     libc.src.math.nearbyintf
     libc.src.math.nearbyintl
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index eaa7a40a29ae73..3668524af03c27 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -212,11 +212,11 @@ Basic Operations
 +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
 | modfl        | |check| | |check| |         | |check| | |check| |         |         | |check| |         |         |         |         |
 +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
-| nan          |         |         |         |         |         |         |         |         |         |         |         |         |
+| nan          | |check| | |check| |         | |check| | |check| |         |         | |check| |         |         |         |         |
 +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
-| nanf         |         |         |         |         |         |         |         |         |         |         |         |         |
+| nanf         | |check| | |check| |         | |check| | |check| |         |         | |check| |         |         |         |         |
 +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
-| nanl         |         |         |         |         |         |         |         |         |         |         |         |         |
+| nanl         | |check| | |check| |         | |check| | |check| |         |         | |check| |         |         |         |         |
 +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
 | nearbyint    | |check| | |check| |         | |check| | |check| |         |         | |check| |         |         |         |         |
 +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 58c95b856535a1..78095eb23f0711 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -515,6 +515,10 @@ def StdC : StandardSpec<"stdc"> {
           FunctionSpec<"scalbn", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>]>,
           FunctionSpec<"scalbnf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>]>,
           FunctionSpec<"scalbnl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>]>,
+
+          FunctionSpec<"nanf", RetValSpec<FloatType>, [ArgSpec<ConstCharPtr>]>,
+          FunctionSpec<"nan", RetValSpec<DoubleType>, [ArgSpec<ConstCharPtr>]>,
+          FunctionSpec<"nanl", RetValSpec<LongDoubleType>, [ArgSpec<ConstCharPtr>]>,
       ]
   >;
 
diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h
index 36b512d6972a93..555f65707b4e41 100644
--- a/libc/src/__support/str_to_float.h
+++ b/libc/src/__support/str_to_float.h
@@ -1206,6 +1206,34 @@ LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) {
   return {T(result), index, error};
 }
 
+LIBC_INLINE const char *nan_str_to_floatingpoint_str(const char *arg) {
+  ptrdiff_t index = 0;
+  while (isalnum(arg[index]) || arg[index] == '_')
+    ++index;
+
+  if (arg[index] == '\0') {
+    // 5 is the number of characters in string "NAN()".
+    ptrdiff_t size = 5 + index;
+    char *output_str = new char[size + 1];
+
+    output_str[0] = 'N';
+    output_str[1] = 'A';
+    output_str[2] = 'N';
+    output_str[3] = '(';
+
+    for (ptrdiff_t i = 0; i < index; ++i) {
+      output_str[4 + i] = arg[i];
+    }
+
+    output_str[size - 1] = ')';
+    output_str[size] = '\0';
+
+    return output_str;
+  }
+
+  return "NAN";
+}
+
 } // namespace internal
 } // namespace LIBC_NAMESPACE
 
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index ffabc27bc00abc..e2b1026fcad7e5 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -179,6 +179,10 @@ add_math_entrypoint_object(modf)
 add_math_entrypoint_object(modff)
 add_math_entrypoint_object(modfl)
 
+add_math_entrypoint_object(nan)
+add_math_entrypoint_object(nanf)
+add_math_entrypoint_object(nanl)
+
 add_math_entrypoint_object(nearbyint)
 add_math_entrypoint_object(nearbyintf)
 add_math_entrypoint_object(nearbyintl)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 214d57842d93b5..eeb09652961fd5 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1437,6 +1437,45 @@ add_entrypoint_object(
     -O3
 )
 
+add_entrypoint_object(
+  nan
+  SRCS
+    nan.cpp
+  HDRS
+    ../nan.h
+  DEPENDS
+    libc.src.__support.str_to_float
+    libc.src.errno.errno
+  COMPILE_OPTIONS
+    -O3
+)
+
+add_entrypoint_object(
+  nanf
+  SRCS
+    nanf.cpp
+  HDRS
+    ../nanf.h
+  DEPENDS
+    libc.src.__support.str_to_float
+    libc.src.errno.errno
+  COMPILE_OPTIONS
+    -O3
+)
+
+add_entrypoint_object(
+  nanl
+  SRCS
+    nanl.cpp
+  HDRS
+    ../nanl.h
+  DEPENDS
+    libc.src.__support.str_to_float
+    libc.src.errno.errno
+  COMPILE_OPTIONS
+    -O3
+)
+
 add_entrypoint_object(
   nextafter
   SRCS
diff --git a/libc/src/math/generic/nan.cpp b/libc/src/math/generic/nan.cpp
new file mode 100644
index 00000000000000..9d591dcd3d091b
--- /dev/null
+++ b/libc/src/math/generic/nan.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of nan 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/nan.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(double, nan, (const char *arg)) {
+  const char *fp_str = internal::nan_str_to_floatingpoint_str(arg);
+  auto result = internal::strtofloatingpoint<double>(fp_str);
+
+  if (result.has_error())
+    libc_errno = result.error;
+
+  return result.value;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nanf.cpp b/libc/src/math/generic/nanf.cpp
new file mode 100644
index 00000000000000..b83e715485e471
--- /dev/null
+++ b/libc/src/math/generic/nanf.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of nanf 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/nanf.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(float, nanf, (const char *arg)) {
+  const char *fp_str = internal::nan_str_to_floatingpoint_str(arg);
+  auto result = internal::strtofloatingpoint<float>(fp_str);
+
+  if (result.has_error())
+    libc_errno = result.error;
+
+  return result.value;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/nanl.cpp b/libc/src/math/generic/nanl.cpp
new file mode 100644
index 00000000000000..6f70af9957b426
--- /dev/null
+++ b/libc/src/math/generic/nanl.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of nanl 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/nanl.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(long double, nanl, (const char *arg)) {
+  const char *fp_str = internal::nan_str_to_floatingpoint_str(arg);
+  auto result = internal::strtofloatingpoint<long double>(fp_str);
+
+  if (result.has_error())
+    libc_errno = result.error;
+
+  return result.value;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/nan.h b/libc/src/math/nan.h
new file mode 100644
index 00000000000000..463940b01a2720
--- /dev/null
+++ b/libc/src/math/nan.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nan ---------------------------*- 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_NAN_H
+#define LLVM_LIBC_SRC_MATH_NAN_H
+
+namespace LIBC_NAMESPACE {
+
+double nan(const char *arg);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NAN_H
diff --git a/libc/src/math/nanf.h b/libc/src/math/nanf.h
new file mode 100644
index 00000000000000..f05d60e3a96718
--- /dev/null
+++ b/libc/src/math/nanf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nanf --------------------------*- 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_NANF_H
+#define LLVM_LIBC_SRC_MATH_NANF_H
+
+namespace LIBC_NAMESPACE {
+
+float nanf(const char *arg);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NANF_H
diff --git a/libc/src/math/nanl.h b/libc/src/math/nanl.h
new file mode 100644
index 00000000000000..d8bbce7cc1bcc3
--- /dev/null
+++ b/libc/src/math/nanl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for nanl --------------------------*- 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_NANL_H
+#define LLVM_LIBC_SRC_MATH_NANL_H
+
+namespace LIBC_NAMESPACE {
+
+long double nanl(const char *arg);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_NANL_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 6ebd374d04a5ba..6488f9f86f1fd3 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1203,6 +1203,42 @@ add_fp_unittest(
     libc.src.__support.FPUtil.fp_bits
 )
 
+add_fp_unittest(
+  nanf_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    nanf_test.cpp
+  DEPENDS
+    libc.include.math
+    libc.src.math.nanf
+    libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
+  nan_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    nan_test.cpp
+  DEPENDS
+    libc.include.math
+    libc.src.math.nan
+    libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
+  nanl_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    nanl_test.cpp
+  DEPENDS
+    libc.include.math
+    libc.src.math.nanl
+    libc.src.__support.FPUtil.fp_bits
+)
+
 # FIXME: These tests are currently spurious for NVPTX.
 if(NOT LIBC_GPU_TARGET_ARCHITECTURE_IS_NVPTX)
   add_fp_unittest(
diff --git a/libc/test/src/math/smoke/nan_test.cpp b/libc/test/src/math/smoke/nan_test.cpp
new file mode 100644
index 00000000000000..6ff60be92e045b
--- /dev/null
+++ b/libc/test/src/math/smoke/nan_test.cpp
@@ -0,0 +1,40 @@
+//===-- Unittests for nan -------------------------------------------------===//
+//
+// 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/math/nan.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+class LlvmLibcNanTest : public LIBC_NAMESPACE::testing::Test {
+public:
+  using StorageType = LIBC_NAMESPACE::fputil::FPBits<double>::StorageType;
+
+  void run_test(const char *input_str, StorageType bits) {
+    double result = LIBC_NAMESPACE::nan(input_str);
+    auto actual_fp = LIBC_NAMESPACE::fputil::FPBits<double>(result);
+    auto expected_fp = LIBC_NAMESPACE::fputil::FPBits<double>(bits);
+    EXPECT_EQ(actual_fp.bits, expected_fp.bits);
+  };
+};
+
+TEST_F(LlvmLibcNanTest, NCharSeq) {
+  run_test("", 0x7ff8000000000000);
+  run_test("1234", 0x7ff80000000004d2);
+  run_test("0x1234", 0x7ff8000000001234);
+  run_test("1a", 0x7ff8000000000000);
+  run_test("1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_",
+           0x7ff8000000000000);
+}
+
+TEST_F(LlvmLibcNanTest, RandomString) {
+  run_test(" 1234", 0x7ff8000000000000);
+  run_test("-1234", 0x7ff8000000000000);
+  run_test("asd&f", 0x7ff8000000000000);
+  run_test("123 ", 0x7ff8000000000000);
+}
diff --git a/libc/test/src/math/smoke/nanf_test.cpp b/libc/test/src/math/smoke/nanf_test.cpp
new file mode 100644
index 00000000000000..a8ff2f6b019c49
--- /dev/null
+++ b/libc/test/src/math/smoke/nanf_test.cpp
@@ -0,0 +1,40 @@
+//===-- Unittests for nanf ------------------------------------------------===//
+//
+// 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/math/nanf.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+class LlvmLibcNanfTest : public LIBC_NAMESPACE::testing::Test {
+public:
+  using StorageType = LIBC_NAMESPACE::fputil::FPBits<float>::StorageType;
+
+  void run_test(const char *input_str, StorageType bits) {
+    float result = LIBC_NAMESPACE::nanf(input_str);
+    auto actual_fp = LIBC_NAMESPACE::fputil::FPBits<float>(result);
+    auto expected_fp = LIBC_NAMESPACE::fputil::FPBits<float>(bits);
+    EXPECT_EQ(actual_fp.bits, expected_fp.bits);
+  };
+};
+
+TEST_F(LlvmLibcNanfTest, NCharSeq) {
+  run_test("", 0x7fc00000);
+  run_test("1234", 0x7fc004d2);
+  run_test("0x1234", 0x7fc01234);
+  run_test("1a", 0x7fc00000);
+  run_test("1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_",
+           0x7fc00000);
+}
+
+TEST_F(LlvmLibcNanfTest, RandomString) {
+  run_test(" 1234", 0x7fc00000);
+  run_test("-1234", 0x7fc00000);
+  run_test("asd&f", 0x7fc00000);
+  run_test("123 ", 0x7fc00000);
+}
diff --git a/libc/test/src/math/smoke/nanl_test.cpp b/libc/test/src/math/smoke/nanl_test.cpp
new file mode 100644
index 00000000000000..a4283b0dcabc25
--- /dev/null
+++ b/libc/test/src/math/smoke/nanl_test.cpp
@@ -0,0 +1,64 @@
+//===-- Unittests for nanl ------------------------------------------------===//
+//
+// 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/math/nanl.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#if defined(LIBC_LONG_DOUBLE_IS_FLOAT64)
+#define SELECT_LONG_DOUBLE(val, _, __) val
+#elif defined(LIBC_LONG_DOUBLE_IS_X86_FLOAT80)
+#define SELECT_LONG_DOUBLE(_, val, __) val
+#else
+#define SELECT_LONG_DOUBLE(_, __, val) val
+#endif
+
+class LlvmLibcNanlTest : public LIBC_NAMESPACE::testing::Test {
+public:
+  using StorageType = LIBC_NAMESPACE::fputil::FPBits<long double>::StorageType;
+
+  void run_test(const char *input_str, StorageType bits) {
+    long double result = LIBC_NAMESPACE::nanl(input_str);
+    auto actual_fp = LIBC_NAMESPACE::fputil::FPBits<long double>(result);
+    auto expected_fp = LIBC_NAMESPACE::fputil::FPBits<long double>(bits);
+    EXPECT_EQ(actual_fp.bits, expected_fp.bits);
+  };
+};
+
+TEST_F(LlvmLibcNanlTest, NCharSeq) {
+  run_test("",
+           SELECT_LONG_DOUBLE(0x7ff8000000000000, (UInt128(0x7fffc00000) << 40),
+                              (UInt128(0x7fff800000000000) << 64)));
...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/76690


More information about the libc-commits mailing list