[libc-commits] [libc] [libc][math][c23] Add {getpayload, setpayload, setpayloadsig}f16 C23 math functions (PR #95159)

via libc-commits libc-commits at lists.llvm.org
Tue Jun 11 11:30:13 PDT 2024


https://github.com/overmighty created https://github.com/llvm/llvm-project/pull/95159

Part of #93566.

>From f2ccfc13dad54a69d533f89823be4bd3b7de2c7a Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Tue, 11 Jun 2024 18:26:33 +0200
Subject: [PATCH 1/3] [libc][math][c23] Add getpayloadf16 C23 math function

---
 libc/config/linux/aarch64/entrypoints.txt     |  1 +
 libc/config/linux/x86_64/entrypoints.txt      |  1 +
 libc/docs/c23.rst                             |  2 +-
 libc/docs/math/index.rst                      |  2 +
 libc/spec/stdc.td                             |  2 +
 libc/src/__support/FPUtil/BasicOperations.h   | 11 +++
 libc/src/math/CMakeLists.txt                  |  2 +
 libc/src/math/generic/CMakeLists.txt          | 12 ++++
 libc/src/math/generic/getpayloadf16.cpp       | 19 +++++
 libc/src/math/getpayloadf16.h                 | 20 ++++++
 libc/test/src/math/smoke/CMakeLists.txt       | 12 ++++
 libc/test/src/math/smoke/GetPayloadTest.h     | 70 +++++++++++++++++++
 .../src/math/smoke/getpayloadf16_test.cpp     | 13 ++++
 13 files changed, 166 insertions(+), 1 deletion(-)
 create mode 100644 libc/src/math/generic/getpayloadf16.cpp
 create mode 100644 libc/src/math/getpayloadf16.h
 create mode 100644 libc/test/src/math/smoke/GetPayloadTest.h
 create mode 100644 libc/test/src/math/smoke/getpayloadf16_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index db96a80051a8d..235844e25f83c 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -519,6 +519,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.frexpf16
     libc.src.math.fromfpf16
     libc.src.math.fromfpxf16
+    libc.src.math.getpayloadf16
     libc.src.math.ilogbf16
     libc.src.math.llogbf16
     libc.src.math.llrintf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 355eaf33ace6d..8550ef771ed65 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -552,6 +552,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.frexpf16
     libc.src.math.fromfpf16
     libc.src.math.fromfpxf16
+    libc.src.math.getpayloadf16
     libc.src.math.ilogbf16
     libc.src.math.llogbf16
     libc.src.math.llrintf16
diff --git a/libc/docs/c23.rst b/libc/docs/c23.rst
index 4134befd1ed35..bbbd8e7767034 100644
--- a/libc/docs/c23.rst
+++ b/libc/docs/c23.rst
@@ -44,7 +44,7 @@ Additions:
   * compoundn*
   * totalorder* |check|
   * totalordermag* |check|
-  * getpayload*
+  * getpayload* |check|
   * setpayload*
   * iscannonical
   * issignaling
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index d556885eda622..9ccdf0efeeb92 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -168,6 +168,8 @@ Basic Operations
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | fsub             | N/A              |                 |                        | N/A                  |                        | 7.12.14.2              | F.10.11                    |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
+| getpayload       |                  |                 |                        | |check|              |                        | F.10.13.1              | N/A                        |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | ilogb            | |check|          | |check|         | |check|                | |check|              | |check|                | 7.12.6.8               | F.10.3.8                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | ldexp            | |check|          | |check|         | |check|                |                      | |check|                | 7.12.6.9               | F.10.3.9                   |
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index b134ec00a7d7a..aef21077333d1 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -714,6 +714,8 @@ def StdC : StandardSpec<"stdc"> {
           GuardedFunctionSpec<"totalorderf16", RetValSpec<IntType>, [ArgSpec<Float16Ptr>, ArgSpec<Float16Ptr>], "LIBC_TYPES_HAS_FLOAT16">,
 
           GuardedFunctionSpec<"totalordermagf16", RetValSpec<IntType>, [ArgSpec<Float16Ptr>, ArgSpec<Float16Ptr>], "LIBC_TYPES_HAS_FLOAT16">,
+
+          GuardedFunctionSpec<"getpayloadf16", RetValSpec<Float16Type>, [ArgSpec<Float16Ptr>], "LIBC_TYPES_HAS_FLOAT16">,
       ]
   >;
 
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index beb8e48db8f51..06b139ff430be 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -265,6 +265,17 @@ totalordermag(T x, T y) {
   return FPBits<T>(x).abs().uintval() <= FPBits<T>(y).abs().uintval();
 }
 
+template <typename T>
+LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> getpayload(T x) {
+  using FPBits = FPBits<T>;
+  FPBits x_bits(x);
+
+  if (!x_bits.is_nan())
+    return T(-1.0);
+
+  return T(x_bits.uintval() & (FPBits::FRACTION_MASK >> 1));
+}
+
 } // namespace fputil
 } // namespace LIBC_NAMESPACE
 
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 2446c293b8ef5..236c5f7999f2f 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -206,6 +206,8 @@ add_math_entrypoint_object(fromfpxl)
 add_math_entrypoint_object(fromfpxf16)
 add_math_entrypoint_object(fromfpxf128)
 
+add_math_entrypoint_object(getpayloadf16)
+
 add_math_entrypoint_object(hypot)
 add_math_entrypoint_object(hypotf)
 
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 673bef516b13d..3b9aaec129573 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -3601,3 +3601,15 @@ add_entrypoint_object(
   COMPILE_OPTIONS
     -O3
 )
+
+add_entrypoint_object(
+  getpayloadf16
+  SRCS
+    getpayloadf16.cpp
+  HDRS
+    ../getpayloadf16.h
+  DEPENDS
+    libc.src.__support.FPUtil.basic_operations
+  COMPILE_OPTIONS
+    -O3
+)
diff --git a/libc/src/math/generic/getpayloadf16.cpp b/libc/src/math/generic/getpayloadf16.cpp
new file mode 100644
index 0000000000000..0923226e5c5c8
--- /dev/null
+++ b/libc/src/math/generic/getpayloadf16.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of getpayloadf16 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/getpayloadf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float16, getpayloadf16, (const float16 *x)) {
+  return fputil::getpayload(*x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/getpayloadf16.h b/libc/src/math/getpayloadf16.h
new file mode 100644
index 0000000000000..1349dfd370239
--- /dev/null
+++ b/libc/src/math/getpayloadf16.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for getpayloadf16 -----------------*- 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_GETPAYLOADF16_H
+#define LLVM_LIBC_SRC_MATH_GETPAYLOADF16_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float16 getpayloadf16(const float16 *x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_GETPAYLOADF16_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 68cd412b14e9d..1a6ab8a83b2a4 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -3543,3 +3543,15 @@ add_fp_unittest(
   DEPENDS
     libc.src.math.totalordermagf16
 )
+
+add_fp_unittest(
+  getpayloadf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    getpayloadf16_test.cpp
+  HDRS
+    GetPayloadTest.h
+  DEPENDS
+    libc.src.math.getpayloadf16
+)
diff --git a/libc/test/src/math/smoke/GetPayloadTest.h b/libc/test/src/math/smoke/GetPayloadTest.h
new file mode 100644
index 0000000000000..6e30de7643119
--- /dev/null
+++ b/libc/test/src/math/smoke/GetPayloadTest.h
@@ -0,0 +1,70 @@
+//===-- Utility class to test different flavors of getpayload ---*- 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 LIBC_TEST_SRC_MATH_SMOKE_GETPAYLOADTEST_H
+#define LIBC_TEST_SRC_MATH_SMOKE_GETPAYLOADTEST_H
+
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class GetPayloadTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+
+  DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+  typedef T (*GetPayloadFunc)(const T *);
+
+  T funcWrapper(GetPayloadFunc func, T x) { return func(&x); }
+
+  void testNonNaNs(GetPayloadFunc func) {
+    EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(0.0)));
+    EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(-0.0)));
+    EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(0.1)));
+    EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(-0.1)));
+    EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(123.38)));
+    EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(-123.38)));
+    EXPECT_FP_EQ(T(-1.0), funcWrapper(func, inf));
+    EXPECT_FP_EQ(T(-1.0), funcWrapper(func, neg_inf));
+  }
+
+  void testNaNs(GetPayloadFunc func) {
+    EXPECT_FP_EQ(T(0.0), funcWrapper(func, aNaN));
+    EXPECT_FP_EQ(T(0.0), funcWrapper(func, neg_aNaN));
+
+    T default_snan_payload = StorageType(1) << (FPBits::SIG_LEN - 2);
+    EXPECT_FP_EQ(default_snan_payload, funcWrapper(func, sNaN));
+    EXPECT_FP_EQ(default_snan_payload, funcWrapper(func, neg_sNaN));
+
+    T qnan_42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val();
+    T neg_qnan_42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val();
+    T snan_42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val();
+    T neg_snan_42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val();
+    EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, qnan_42));
+    EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_qnan_42));
+    EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, snan_42));
+    EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_snan_42));
+
+    T qnan_123 = FPBits::quiet_nan(Sign::POS, 0x123).get_val();
+    T neg_qnan_123 = FPBits::quiet_nan(Sign::NEG, 0x123).get_val();
+    T snan_123 = FPBits::signaling_nan(Sign::POS, 0x123).get_val();
+    T neg_snan_123 = FPBits::signaling_nan(Sign::NEG, 0x123).get_val();
+    EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, qnan_123));
+    EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_qnan_123));
+    EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, snan_123));
+    EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_snan_123));
+  }
+};
+
+#define LIST_GETPAYLOAD_TESTS(T, func)                                         \
+  using LlvmLibcGetPayloadTest = GetPayloadTestTemplate<T>;                    \
+  TEST_F(LlvmLibcGetPayloadTest, NonNaNs) { testNonNaNs(&func); }              \
+  TEST_F(LlvmLibcGetPayloadTest, NaNs) { testNaNs(&func); }
+
+#endif // LIBC_TEST_SRC_MATH_SMOKE_GETPAYLOADTEST_H
diff --git a/libc/test/src/math/smoke/getpayloadf16_test.cpp b/libc/test/src/math/smoke/getpayloadf16_test.cpp
new file mode 100644
index 0000000000000..385b04701b8bb
--- /dev/null
+++ b/libc/test/src/math/smoke/getpayloadf16_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for getpayloadf16 ---------------------------------------===//
+//
+// 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 "GetPayloadTest.h"
+
+#include "src/math/getpayloadf16.h"
+
+LIST_GETPAYLOAD_TESTS(float16, LIBC_NAMESPACE::getpayloadf16)

>From 846a5fbc928d11b5a5943d69e22dddbad009d06f Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Tue, 11 Jun 2024 20:03:32 +0200
Subject: [PATCH 2/3] [libc][math][c23] Add setpayloadf16 C23 math function

---
 libc/config/linux/aarch64/entrypoints.txt     |  1 +
 libc/config/linux/x86_64/entrypoints.txt      |  1 +
 libc/docs/c23.rst                             |  2 +-
 libc/docs/math/index.rst                      |  2 +
 libc/spec/stdc.td                             |  2 +
 libc/src/__support/FPUtil/BasicOperations.h   | 25 +++++++
 libc/src/math/CMakeLists.txt                  |  2 +
 libc/src/math/generic/CMakeLists.txt          | 12 ++++
 libc/src/math/generic/setpayloadf16.cpp       | 19 ++++++
 libc/src/math/setpayloadf16.h                 | 20 ++++++
 libc/test/src/math/smoke/CMakeLists.txt       | 12 ++++
 libc/test/src/math/smoke/SetPayloadTest.h     | 66 +++++++++++++++++++
 .../src/math/smoke/setpayloadf16_test.cpp     | 13 ++++
 13 files changed, 176 insertions(+), 1 deletion(-)
 create mode 100644 libc/src/math/generic/setpayloadf16.cpp
 create mode 100644 libc/src/math/setpayloadf16.h
 create mode 100644 libc/test/src/math/smoke/SetPayloadTest.h
 create mode 100644 libc/test/src/math/smoke/setpayloadf16_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 235844e25f83c..5b87d8dbdabf4 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -542,6 +542,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.rintf16
     libc.src.math.roundf16
     libc.src.math.roundevenf16
+    libc.src.math.setpayloadf16
     libc.src.math.totalorderf16
     libc.src.math.totalordermagf16
     libc.src.math.truncf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 8550ef771ed65..af3dd2d0f69f9 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -572,6 +572,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.rintf16
     libc.src.math.roundf16
     libc.src.math.roundevenf16
+    libc.src.math.setpayloadf16
     libc.src.math.totalorderf16
     libc.src.math.totalordermagf16
     libc.src.math.truncf16
diff --git a/libc/docs/c23.rst b/libc/docs/c23.rst
index bbbd8e7767034..1ac1403bbceb7 100644
--- a/libc/docs/c23.rst
+++ b/libc/docs/c23.rst
@@ -45,7 +45,7 @@ Additions:
   * totalorder* |check|
   * totalordermag* |check|
   * getpayload* |check|
-  * setpayload*
+  * setpayload* |check|
   * iscannonical
   * issignaling
   * issubnormal
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index 9ccdf0efeeb92..0e8121aac1deb 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -212,6 +212,8 @@ Basic Operations
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | scalbn           | |check|          | |check|         | |check|                |                      | |check|                | 7.12.6.19              | F.10.3.19                  |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
+| setpayload       |                  |                 |                        | |check|              |                        | F.10.13.2              | N/A                        |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | totalorder       |                  |                 |                        | |check|              |                        | F.10.12.1              | N/A                        |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | totalordermag    |                  |                 |                        | |check|              |                        | F.10.12.2              | N/A                        |
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index aef21077333d1..d69974404f465 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -716,6 +716,8 @@ def StdC : StandardSpec<"stdc"> {
           GuardedFunctionSpec<"totalordermagf16", RetValSpec<IntType>, [ArgSpec<Float16Ptr>, ArgSpec<Float16Ptr>], "LIBC_TYPES_HAS_FLOAT16">,
 
           GuardedFunctionSpec<"getpayloadf16", RetValSpec<Float16Type>, [ArgSpec<Float16Ptr>], "LIBC_TYPES_HAS_FLOAT16">,
+
+          GuardedFunctionSpec<"setpayloadf16", RetValSpec<IntType>, [ArgSpec<Float16Ptr>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
       ]
   >;
 
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 06b139ff430be..ceaaded3d322c 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -276,6 +276,31 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> getpayload(T x) {
   return T(x_bits.uintval() & (FPBits::FRACTION_MASK >> 1));
 }
 
+template <typename T>
+LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
+setpayload(T *res, T pl) {
+  using FPBits = FPBits<T>;
+  FPBits pl_bits(pl);
+
+  if (pl_bits.is_zero()) {
+    *res = FPBits::quiet_nan(Sign::POS).get_val();
+    return false;
+  }
+
+  int pl_exp = pl_bits.get_exponent();
+
+  if (pl_bits.is_neg() || pl_exp < 0 || pl_exp >= FPBits::FRACTION_LEN - 1 ||
+      ((pl_bits.get_mantissa() << pl_exp) & FPBits::FRACTION_MASK) != 0) {
+    *res = T(0.0);
+    return true;
+  }
+
+  using StorageType = typename FPBits::StorageType;
+  StorageType v(pl_bits.get_explicit_mantissa() >> (FPBits::SIG_LEN - pl_exp));
+  *res = FPBits::quiet_nan(Sign::POS, v).get_val();
+  return false;
+}
+
 } // namespace fputil
 } // namespace LIBC_NAMESPACE
 
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 236c5f7999f2f..2326b5e743e20 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -348,6 +348,8 @@ add_math_entrypoint_object(scalbnf)
 add_math_entrypoint_object(scalbnl)
 add_math_entrypoint_object(scalbnf128)
 
+add_math_entrypoint_object(setpayloadf16)
+
 add_math_entrypoint_object(sincos)
 add_math_entrypoint_object(sincosf)
 
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 3b9aaec129573..aa922e7bad906 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -3613,3 +3613,15 @@ add_entrypoint_object(
   COMPILE_OPTIONS
     -O3
 )
+
+add_entrypoint_object(
+  setpayloadf16
+  SRCS
+    setpayloadf16.cpp
+  HDRS
+    ../setpayloadf16.h
+  DEPENDS
+    libc.src.__support.FPUtil.basic_operations
+  COMPILE_OPTIONS
+    -O3
+)
diff --git a/libc/src/math/generic/setpayloadf16.cpp b/libc/src/math/generic/setpayloadf16.cpp
new file mode 100644
index 0000000000000..f9fe74bb545d0
--- /dev/null
+++ b/libc/src/math/generic/setpayloadf16.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of setpayloadf16 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/setpayloadf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, setpayloadf16, (float16 * res, float16 pl)) {
+  return static_cast<int>(fputil::setpayload(res, pl));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/setpayloadf16.h b/libc/src/math/setpayloadf16.h
new file mode 100644
index 0000000000000..8705e2804fa99
--- /dev/null
+++ b/libc/src/math/setpayloadf16.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for setpayloadf16 -----------------*- 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_SETPAYLOADF16_H
+#define LLVM_LIBC_SRC_MATH_SETPAYLOADF16_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+int setpayloadf16(float16 *res, float16 pl);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_SETPAYLOADF16_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 1a6ab8a83b2a4..fb4e5d347bf1e 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -3555,3 +3555,15 @@ add_fp_unittest(
   DEPENDS
     libc.src.math.getpayloadf16
 )
+
+add_fp_unittest(
+  setpayloadf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    setpayloadf16_test.cpp
+  HDRS
+    SetPayloadTest.h
+  DEPENDS
+    libc.src.math.setpayloadf16
+)
diff --git a/libc/test/src/math/smoke/SetPayloadTest.h b/libc/test/src/math/smoke/SetPayloadTest.h
new file mode 100644
index 0000000000000..3bac5f0ac1848
--- /dev/null
+++ b/libc/test/src/math/smoke/SetPayloadTest.h
@@ -0,0 +1,66 @@
+//===-- Utility class to test different flavors of setpayload ---*- 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 LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADTEST_H
+#define LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADTEST_H
+
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class SetPayloadTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+
+  DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+  typedef int (*SetPayloadFunc)(T *, T);
+
+  void testInvalidPayloads(SetPayloadFunc func) {
+    T res;
+
+    EXPECT_EQ(1, func(&res, T(aNaN)));
+    EXPECT_EQ(1, func(&res, T(neg_aNaN)));
+    EXPECT_EQ(1, func(&res, T(inf)));
+    EXPECT_EQ(1, func(&res, T(neg_inf)));
+    EXPECT_EQ(1, func(&res, T(0.1)));
+    EXPECT_EQ(1, func(&res, T(-0.1)));
+    EXPECT_EQ(1, func(&res, T(-1.0)));
+    EXPECT_EQ(1, func(&res, T(0x42.1p+0)));
+    EXPECT_EQ(1, func(&res, T(-0x42.1p+0)));
+    EXPECT_EQ(1, func(&res, T(StorageType(1) << (FPBits::FRACTION_LEN - 1))));
+  }
+
+  void testValidPayloads(SetPayloadFunc func) {
+    T res;
+
+    EXPECT_EQ(0, func(&res, T(0.0)));
+    EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(res).uintval());
+    EXPECT_EQ(0, func(&res, T(1.0)));
+    EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 1).uintval(), FPBits(res).uintval());
+    EXPECT_EQ(0, func(&res, T(0x42.0p+0)));
+    EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x42).uintval(),
+              FPBits(res).uintval());
+    EXPECT_EQ(0, func(&res, T(0x123.0p+0)));
+    EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x123).uintval(),
+              FPBits(res).uintval());
+    EXPECT_EQ(0, func(&res, T(FPBits::FRACTION_MASK >> 1)));
+    EXPECT_EQ(
+        FPBits::quiet_nan(Sign::POS, FPBits::FRACTION_MASK >> 1).uintval(),
+        FPBits(res).uintval());
+  }
+};
+
+#define LIST_SETPAYLOAD_TESTS(T, func)                                         \
+  using LlvmLibcSetPayloadTest = SetPayloadTestTemplate<T>;                    \
+  TEST_F(LlvmLibcSetPayloadTest, InvalidPayloads) {                            \
+    testInvalidPayloads(&func);                                                \
+  }                                                                            \
+  TEST_F(LlvmLibcSetPayloadTest, ValidPayloads) { testValidPayloads(&func); }
+
+#endif // LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADTEST_H
diff --git a/libc/test/src/math/smoke/setpayloadf16_test.cpp b/libc/test/src/math/smoke/setpayloadf16_test.cpp
new file mode 100644
index 0000000000000..ccf5370272345
--- /dev/null
+++ b/libc/test/src/math/smoke/setpayloadf16_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for setpayloadf16 ---------------------------------------===//
+//
+// 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 "SetPayloadTest.h"
+
+#include "src/math/setpayloadf16.h"
+
+LIST_SETPAYLOAD_TESTS(float16, LIBC_NAMESPACE::setpayloadf16)

>From f9fb6c99ca96b10a217c4febe0ea82c2dc6d8a75 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Tue, 11 Jun 2024 20:22:41 +0200
Subject: [PATCH 3/3] [libc][math][c23] Add setpayloadsigf16 C23 math function

---
 libc/config/linux/aarch64/entrypoints.txt     |  1 +
 libc/config/linux/x86_64/entrypoints.txt      |  1 +
 libc/docs/c23.rst                             |  1 +
 libc/docs/math/index.rst                      |  2 +
 libc/spec/stdc.td                             |  2 +
 libc/src/__support/FPUtil/BasicOperations.h   | 12 ++-
 libc/src/math/CMakeLists.txt                  |  2 +
 libc/src/math/generic/CMakeLists.txt          | 12 +++
 libc/src/math/generic/setpayloadf16.cpp       |  2 +-
 libc/src/math/generic/setpayloadsigf16.cpp    | 19 +++++
 libc/src/math/setpayloadsigf16.h              | 20 +++++
 libc/test/src/math/smoke/CMakeLists.txt       | 12 +++
 libc/test/src/math/smoke/SetPayloadSigTest.h  | 74 +++++++++++++++++++
 libc/test/src/math/smoke/SetPayloadTest.h     |  9 +++
 .../src/math/smoke/setpayloadsigf16_test.cpp  | 13 ++++
 15 files changed, 178 insertions(+), 4 deletions(-)
 create mode 100644 libc/src/math/generic/setpayloadsigf16.cpp
 create mode 100644 libc/src/math/setpayloadsigf16.h
 create mode 100644 libc/test/src/math/smoke/SetPayloadSigTest.h
 create mode 100644 libc/test/src/math/smoke/setpayloadsigf16_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 5b87d8dbdabf4..2fdddb37861fc 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -543,6 +543,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.roundf16
     libc.src.math.roundevenf16
     libc.src.math.setpayloadf16
+    libc.src.math.setpayloadsigf16
     libc.src.math.totalorderf16
     libc.src.math.totalordermagf16
     libc.src.math.truncf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index af3dd2d0f69f9..bf642f1cbfa3e 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -573,6 +573,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.roundf16
     libc.src.math.roundevenf16
     libc.src.math.setpayloadf16
+    libc.src.math.setpayloadsigf16
     libc.src.math.totalorderf16
     libc.src.math.totalordermagf16
     libc.src.math.truncf16
diff --git a/libc/docs/c23.rst b/libc/docs/c23.rst
index 1ac1403bbceb7..b9a2424307f84 100644
--- a/libc/docs/c23.rst
+++ b/libc/docs/c23.rst
@@ -46,6 +46,7 @@ Additions:
   * totalordermag* |check|
   * getpayload* |check|
   * setpayload* |check|
+  * setpayloadsig* |check|
   * iscannonical
   * issignaling
   * issubnormal
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index 0e8121aac1deb..1cb56799977bc 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -214,6 +214,8 @@ Basic Operations
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | setpayload       |                  |                 |                        | |check|              |                        | F.10.13.2              | N/A                        |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
+| setpayloadsig    |                  |                 |                        | |check|              |                        | F.10.13.3              | N/A                        |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | totalorder       |                  |                 |                        | |check|              |                        | F.10.12.1              | N/A                        |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | totalordermag    |                  |                 |                        | |check|              |                        | F.10.12.2              | N/A                        |
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index d69974404f465..1b394476f1e82 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -718,6 +718,8 @@ def StdC : StandardSpec<"stdc"> {
           GuardedFunctionSpec<"getpayloadf16", RetValSpec<Float16Type>, [ArgSpec<Float16Ptr>], "LIBC_TYPES_HAS_FLOAT16">,
 
           GuardedFunctionSpec<"setpayloadf16", RetValSpec<IntType>, [ArgSpec<Float16Ptr>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
+
+          GuardedFunctionSpec<"setpayloadsigf16", RetValSpec<IntType>, [ArgSpec<Float16Ptr>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
       ]
   >;
 
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index ceaaded3d322c..adc21fef9ab56 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -276,13 +276,15 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> getpayload(T x) {
   return T(x_bits.uintval() & (FPBits::FRACTION_MASK >> 1));
 }
 
-template <typename T>
+template <bool IsSignaling, typename T>
 LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
 setpayload(T *res, T pl) {
   using FPBits = FPBits<T>;
   FPBits pl_bits(pl);
 
-  if (pl_bits.is_zero()) {
+  // Signaling NaNs don't have the mantissa's MSB set to 1, so they need a
+  // non-zero payload to distinguish them from infinities.
+  if (!IsSignaling && pl_bits.is_zero()) {
     *res = FPBits::quiet_nan(Sign::POS).get_val();
     return false;
   }
@@ -297,7 +299,11 @@ setpayload(T *res, T pl) {
 
   using StorageType = typename FPBits::StorageType;
   StorageType v(pl_bits.get_explicit_mantissa() >> (FPBits::SIG_LEN - pl_exp));
-  *res = FPBits::quiet_nan(Sign::POS, v).get_val();
+
+  if constexpr (IsSignaling)
+    *res = FPBits::signaling_nan(Sign::POS, v).get_val();
+  else
+    *res = FPBits::quiet_nan(Sign::POS, v).get_val();
   return false;
 }
 
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 2326b5e743e20..6b9f6ba2bc8cf 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -350,6 +350,8 @@ add_math_entrypoint_object(scalbnf128)
 
 add_math_entrypoint_object(setpayloadf16)
 
+add_math_entrypoint_object(setpayloadsigf16)
+
 add_math_entrypoint_object(sincos)
 add_math_entrypoint_object(sincosf)
 
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index aa922e7bad906..90fb554ba058d 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -3625,3 +3625,15 @@ add_entrypoint_object(
   COMPILE_OPTIONS
     -O3
 )
+
+add_entrypoint_object(
+  setpayloadsigf16
+  SRCS
+    setpayloadsigf16.cpp
+  HDRS
+    ../setpayloadsigf16.h
+  DEPENDS
+    libc.src.__support.FPUtil.basic_operations
+  COMPILE_OPTIONS
+    -O3
+)
diff --git a/libc/src/math/generic/setpayloadf16.cpp b/libc/src/math/generic/setpayloadf16.cpp
index f9fe74bb545d0..7b40d434001c1 100644
--- a/libc/src/math/generic/setpayloadf16.cpp
+++ b/libc/src/math/generic/setpayloadf16.cpp
@@ -13,7 +13,7 @@
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, setpayloadf16, (float16 * res, float16 pl)) {
-  return static_cast<int>(fputil::setpayload(res, pl));
+  return static_cast<int>(fputil::setpayload</*IsSignaling=*/false>(res, pl));
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/setpayloadsigf16.cpp b/libc/src/math/generic/setpayloadsigf16.cpp
new file mode 100644
index 0000000000000..28e95cf26c238
--- /dev/null
+++ b/libc/src/math/generic/setpayloadsigf16.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of setpayloadsigf16 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/setpayloadsigf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, setpayloadsigf16, (float16 * res, float16 pl)) {
+  return static_cast<int>(fputil::setpayload</*IsSignaling=*/true>(res, pl));
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/setpayloadsigf16.h b/libc/src/math/setpayloadsigf16.h
new file mode 100644
index 0000000000000..ee9bc38ab9423
--- /dev/null
+++ b/libc/src/math/setpayloadsigf16.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for setpayloadsigf16 --------------*- 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_SETPAYLOADSIGF16_H
+#define LLVM_LIBC_SRC_MATH_SETPAYLOADSIGF16_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+int setpayloadsigf16(float16 *res, float16 pl);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_SETPAYLOADSIGF16_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index fb4e5d347bf1e..170493f43180b 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -3567,3 +3567,15 @@ add_fp_unittest(
   DEPENDS
     libc.src.math.setpayloadf16
 )
+
+add_fp_unittest(
+  setpayloadsigf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    setpayloadsigf16_test.cpp
+  HDRS
+    SetPayloadSigTest.h
+  DEPENDS
+    libc.src.math.setpayloadsigf16
+)
diff --git a/libc/test/src/math/smoke/SetPayloadSigTest.h b/libc/test/src/math/smoke/SetPayloadSigTest.h
new file mode 100644
index 0000000000000..7ec3ac08a180a
--- /dev/null
+++ b/libc/test/src/math/smoke/SetPayloadSigTest.h
@@ -0,0 +1,74 @@
+//===-- Utility class to test flavors of setpayloadsig ----------*- 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 LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADSIGTEST_H
+#define LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADSIGTEST_H
+
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class SetPayloadSigTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+
+  DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+  typedef int (*SetPayloadSigFunc)(T *, T);
+
+  void testInvalidPayloads(SetPayloadSigFunc func) {
+    T res;
+
+    EXPECT_EQ(1, func(&res, T(aNaN)));
+    EXPECT_EQ(1, func(&res, T(neg_aNaN)));
+    EXPECT_EQ(1, func(&res, T(inf)));
+    EXPECT_EQ(1, func(&res, T(neg_inf)));
+    EXPECT_EQ(1, func(&res, T(0.0)));
+    EXPECT_EQ(1, func(&res, T(-0.0)));
+    EXPECT_EQ(1, func(&res, T(0.1)));
+    EXPECT_EQ(1, func(&res, T(-0.1)));
+    EXPECT_EQ(1, func(&res, T(-1.0)));
+    EXPECT_EQ(1, func(&res, T(0x42.1p+0)));
+    EXPECT_EQ(1, func(&res, T(-0x42.1p+0)));
+    EXPECT_EQ(1, func(&res, T(StorageType(1) << (FPBits::FRACTION_LEN - 1))));
+  }
+
+  void testValidPayloads(SetPayloadSigFunc func) {
+    T res;
+
+    EXPECT_EQ(0, func(&res, T(1.0)));
+    EXPECT_TRUE(FPBits(res).is_signaling_nan());
+    EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 1).uintval(),
+              FPBits(res).uintval());
+
+    EXPECT_EQ(0, func(&res, T(0x42.0p+0)));
+    EXPECT_TRUE(FPBits(res).is_signaling_nan());
+    EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x42).uintval(),
+              FPBits(res).uintval());
+
+    EXPECT_EQ(0, func(&res, T(0x123.0p+0)));
+    EXPECT_TRUE(FPBits(res).is_signaling_nan());
+    EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x123).uintval(),
+              FPBits(res).uintval());
+
+    EXPECT_EQ(0, func(&res, T(FPBits::FRACTION_MASK >> 1)));
+    EXPECT_TRUE(FPBits(res).is_signaling_nan());
+    EXPECT_EQ(
+        FPBits::signaling_nan(Sign::POS, FPBits::FRACTION_MASK >> 1).uintval(),
+        FPBits(res).uintval());
+  }
+};
+
+#define LIST_SETPAYLOADSIG_TESTS(T, func)                                      \
+  using LlvmLibcSetPayloadSigTest = SetPayloadSigTestTemplate<T>;              \
+  TEST_F(LlvmLibcSetPayloadSigTest, InvalidPayloads) {                         \
+    testInvalidPayloads(&func);                                                \
+  }                                                                            \
+  TEST_F(LlvmLibcSetPayloadSigTest, ValidPayloads) { testValidPayloads(&func); }
+
+#endif // LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADSIGTEST_H
diff --git a/libc/test/src/math/smoke/SetPayloadTest.h b/libc/test/src/math/smoke/SetPayloadTest.h
index 3bac5f0ac1848..4b0dacf3e1544 100644
--- a/libc/test/src/math/smoke/SetPayloadTest.h
+++ b/libc/test/src/math/smoke/SetPayloadTest.h
@@ -40,16 +40,25 @@ class SetPayloadTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     T res;
 
     EXPECT_EQ(0, func(&res, T(0.0)));
+    EXPECT_TRUE(FPBits(res).is_quiet_nan());
     EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(res).uintval());
+
     EXPECT_EQ(0, func(&res, T(1.0)));
+    EXPECT_TRUE(FPBits(res).is_quiet_nan());
     EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 1).uintval(), FPBits(res).uintval());
+
     EXPECT_EQ(0, func(&res, T(0x42.0p+0)));
+    EXPECT_TRUE(FPBits(res).is_quiet_nan());
     EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x42).uintval(),
               FPBits(res).uintval());
+
     EXPECT_EQ(0, func(&res, T(0x123.0p+0)));
+    EXPECT_TRUE(FPBits(res).is_quiet_nan());
     EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x123).uintval(),
               FPBits(res).uintval());
+
     EXPECT_EQ(0, func(&res, T(FPBits::FRACTION_MASK >> 1)));
+    EXPECT_TRUE(FPBits(res).is_quiet_nan());
     EXPECT_EQ(
         FPBits::quiet_nan(Sign::POS, FPBits::FRACTION_MASK >> 1).uintval(),
         FPBits(res).uintval());
diff --git a/libc/test/src/math/smoke/setpayloadsigf16_test.cpp b/libc/test/src/math/smoke/setpayloadsigf16_test.cpp
new file mode 100644
index 0000000000000..9f786e636d086
--- /dev/null
+++ b/libc/test/src/math/smoke/setpayloadsigf16_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for setpayloadsigf16 ------------------------------------===//
+//
+// 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 "SetPayloadSigTest.h"
+
+#include "src/math/setpayloadsigf16.h"
+
+LIST_SETPAYLOADSIG_TESTS(float16, LIBC_NAMESPACE::setpayloadsigf16)



More information about the libc-commits mailing list