Skip to content

Commit 3076712

Browse files
committed
[libc][math][c23] Add setpayloadf16 C23 math function
1 parent 84fc86c commit 3076712

File tree

13 files changed

+177
-1
lines changed

13 files changed

+177
-1
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
545545
libc.src.math.rintf16
546546
libc.src.math.roundf16
547547
libc.src.math.roundevenf16
548+
libc.src.math.setpayloadf16
548549
libc.src.math.totalorderf16
549550
libc.src.math.totalordermagf16
550551
libc.src.math.truncf16

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
575575
libc.src.math.rintf16
576576
libc.src.math.roundf16
577577
libc.src.math.roundevenf16
578+
libc.src.math.setpayloadf16
578579
libc.src.math.totalorderf16
579580
libc.src.math.totalordermagf16
580581
libc.src.math.truncf16

libc/docs/c23.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Additions:
4545
* totalorder* |check|
4646
* totalordermag* |check|
4747
* getpayload* |check|
48-
* setpayload*
48+
* setpayload* |check|
4949
* iscannonical
5050
* issignaling
5151
* issubnormal

libc/docs/math/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ Basic Operations
214214
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
215215
| scalbn | |check| | |check| | |check| | | |check| | 7.12.6.19 | F.10.3.19 |
216216
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
217+
| setpayload | | | | |check| | | F.10.13.2 | N/A |
218+
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
217219
| totalorder | | | | |check| | | F.10.12.1 | N/A |
218220
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
219221
| totalordermag | | | | |check| | | F.10.12.2 | N/A |

libc/spec/stdc.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,8 @@ def StdC : StandardSpec<"stdc"> {
718718

719719
GuardedFunctionSpec<"getpayloadf16", RetValSpec<Float16Type>, [ArgSpec<Float16Ptr>], "LIBC_TYPES_HAS_FLOAT16">,
720720

721+
GuardedFunctionSpec<"setpayloadf16", RetValSpec<IntType>, [ArgSpec<Float16Ptr>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
722+
721723
GuardedFunctionSpec<"f16sqrtf", RetValSpec<Float16Type>, [ArgSpec<FloatType>], "LIBC_TYPES_HAS_FLOAT16">,
722724
]
723725
>;

libc/src/__support/FPUtil/BasicOperations.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,31 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> getpayload(T x) {
276276
return T(x_bits.uintval() & (FPBits::FRACTION_MASK >> 1));
277277
}
278278

279+
template <typename T>
280+
LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
281+
setpayload(T *res, T pl) {
282+
using FPBits = FPBits<T>;
283+
FPBits pl_bits(pl);
284+
285+
if (pl_bits.is_zero()) {
286+
*res = FPBits::quiet_nan(Sign::POS).get_val();
287+
return false;
288+
}
289+
290+
int pl_exp = pl_bits.get_exponent();
291+
292+
if (pl_bits.is_neg() || pl_exp < 0 || pl_exp >= FPBits::FRACTION_LEN - 1 ||
293+
((pl_bits.get_mantissa() << pl_exp) & FPBits::FRACTION_MASK) != 0) {
294+
*res = T(0.0);
295+
return true;
296+
}
297+
298+
using StorageType = typename FPBits::StorageType;
299+
StorageType v(pl_bits.get_explicit_mantissa() >> (FPBits::SIG_LEN - pl_exp));
300+
*res = FPBits::quiet_nan(Sign::POS, v).get_val();
301+
return false;
302+
}
303+
279304
} // namespace fputil
280305
} // namespace LIBC_NAMESPACE
281306

libc/src/math/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,8 @@ add_math_entrypoint_object(scalbnf)
352352
add_math_entrypoint_object(scalbnl)
353353
add_math_entrypoint_object(scalbnf128)
354354

355+
add_math_entrypoint_object(setpayloadf16)
356+
355357
add_math_entrypoint_object(sincos)
356358
add_math_entrypoint_object(sincosf)
357359

libc/src/math/generic/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3615,6 +3615,19 @@ add_entrypoint_object(
36153615
-O3
36163616
)
36173617

3618+
add_entrypoint_object(
3619+
setpayloadf16
3620+
SRCS
3621+
setpayloadf16.cpp
3622+
HDRS
3623+
../setpayloadf16.h
3624+
DEPENDS
3625+
libc.src.__support.macros.properties.types
3626+
libc.src.__support.FPUtil.basic_operations
3627+
COMPILE_OPTIONS
3628+
-O3
3629+
)
3630+
36183631
add_entrypoint_object(
36193632
f16fmaf
36203633
SRCS
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===-- Implementation of setpayloadf16 function --------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/math/setpayloadf16.h"
10+
#include "src/__support/FPUtil/BasicOperations.h"
11+
#include "src/__support/common.h"
12+
13+
namespace LIBC_NAMESPACE {
14+
15+
LLVM_LIBC_FUNCTION(int, setpayloadf16, (float16 * res, float16 pl)) {
16+
return static_cast<int>(fputil::setpayload(res, pl));
17+
}
18+
19+
} // namespace LIBC_NAMESPACE

libc/src/math/setpayloadf16.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header for setpayloadf16 -----------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_MATH_SETPAYLOADF16_H
10+
#define LLVM_LIBC_SRC_MATH_SETPAYLOADF16_H
11+
12+
#include "src/__support/macros/properties/types.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
int setpayloadf16(float16 *res, float16 pl);
17+
18+
} // namespace LIBC_NAMESPACE
19+
20+
#endif // LLVM_LIBC_SRC_MATH_SETPAYLOADF16_H

libc/test/src/math/smoke/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3565,6 +3565,18 @@ add_fp_unittest(
35653565
libc.src.math.getpayloadf16
35663566
)
35673567

3568+
add_fp_unittest(
3569+
setpayloadf16_test
3570+
SUITE
3571+
libc-math-smoke-tests
3572+
SRCS
3573+
setpayloadf16_test.cpp
3574+
HDRS
3575+
SetPayloadTest.h
3576+
DEPENDS
3577+
libc.src.math.setpayloadf16
3578+
)
3579+
35683580
add_fp_unittest(
35693581
f16fmaf_test
35703582
SUITE
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//===-- Utility class to test different flavors of setpayload ---*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADTEST_H
10+
#define LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADTEST_H
11+
12+
#include "test/UnitTest/FEnvSafeTest.h"
13+
#include "test/UnitTest/FPMatcher.h"
14+
#include "test/UnitTest/Test.h"
15+
16+
template <typename T>
17+
class SetPayloadTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
18+
19+
DECLARE_SPECIAL_CONSTANTS(T)
20+
21+
public:
22+
typedef int (*SetPayloadFunc)(T *, T);
23+
24+
void testInvalidPayloads(SetPayloadFunc func) {
25+
T res;
26+
27+
EXPECT_EQ(1, func(&res, T(aNaN)));
28+
EXPECT_EQ(1, func(&res, T(neg_aNaN)));
29+
EXPECT_EQ(1, func(&res, T(inf)));
30+
EXPECT_EQ(1, func(&res, T(neg_inf)));
31+
EXPECT_EQ(1, func(&res, T(0.1)));
32+
EXPECT_EQ(1, func(&res, T(-0.1)));
33+
EXPECT_EQ(1, func(&res, T(-1.0)));
34+
EXPECT_EQ(1, func(&res, T(0x42.1p+0)));
35+
EXPECT_EQ(1, func(&res, T(-0x42.1p+0)));
36+
EXPECT_EQ(1, func(&res, T(StorageType(1) << (FPBits::FRACTION_LEN - 1))));
37+
}
38+
39+
void testValidPayloads(SetPayloadFunc func) {
40+
T res;
41+
42+
EXPECT_EQ(0, func(&res, T(0.0)));
43+
EXPECT_EQ(FPBits(aNaN).uintval(), FPBits(res).uintval());
44+
EXPECT_EQ(0, func(&res, T(1.0)));
45+
EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 1).uintval(), FPBits(res).uintval());
46+
EXPECT_EQ(0, func(&res, T(0x42.0p+0)));
47+
EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x42).uintval(),
48+
FPBits(res).uintval());
49+
EXPECT_EQ(0, func(&res, T(0x123.0p+0)));
50+
EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x123).uintval(),
51+
FPBits(res).uintval());
52+
EXPECT_EQ(0, func(&res, T(FPBits::FRACTION_MASK >> 1)));
53+
EXPECT_EQ(
54+
FPBits::quiet_nan(Sign::POS, FPBits::FRACTION_MASK >> 1).uintval(),
55+
FPBits(res).uintval());
56+
}
57+
};
58+
59+
#define LIST_SETPAYLOAD_TESTS(T, func) \
60+
using LlvmLibcSetPayloadTest = SetPayloadTestTemplate<T>; \
61+
TEST_F(LlvmLibcSetPayloadTest, InvalidPayloads) { \
62+
testInvalidPayloads(&func); \
63+
} \
64+
TEST_F(LlvmLibcSetPayloadTest, ValidPayloads) { testValidPayloads(&func); }
65+
66+
#endif // LIBC_TEST_SRC_MATH_SMOKE_SETPAYLOADTEST_H
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//===-- Unittests for setpayloadf16 ---------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "SetPayloadTest.h"
10+
11+
#include "src/math/setpayloadf16.h"
12+
13+
LIST_SETPAYLOAD_TESTS(float16, LIBC_NAMESPACE::setpayloadf16)

0 commit comments

Comments
 (0)