Skip to content

Commit f2ccfc1

Browse files
committed
[libc][math][c23] Add getpayloadf16 C23 math function
1 parent f5dcfb9 commit f2ccfc1

File tree

13 files changed

+166
-1
lines changed

13 files changed

+166
-1
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
519519
libc.src.math.frexpf16
520520
libc.src.math.fromfpf16
521521
libc.src.math.fromfpxf16
522+
libc.src.math.getpayloadf16
522523
libc.src.math.ilogbf16
523524
libc.src.math.llogbf16
524525
libc.src.math.llrintf16

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
552552
libc.src.math.frexpf16
553553
libc.src.math.fromfpf16
554554
libc.src.math.fromfpxf16
555+
libc.src.math.getpayloadf16
555556
libc.src.math.ilogbf16
556557
libc.src.math.llogbf16
557558
libc.src.math.llrintf16

libc/docs/c23.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Additions:
4444
* compoundn*
4545
* totalorder* |check|
4646
* totalordermag* |check|
47-
* getpayload*
47+
* getpayload* |check|
4848
* setpayload*
4949
* iscannonical
5050
* issignaling

libc/docs/math/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ Basic Operations
168168
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
169169
| fsub | N/A | | | N/A | | 7.12.14.2 | F.10.11 |
170170
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
171+
| getpayload | | | | |check| | | F.10.13.1 | N/A |
172+
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
171173
| ilogb | |check| | |check| | |check| | |check| | |check| | 7.12.6.8 | F.10.3.8 |
172174
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
173175
| ldexp | |check| | |check| | |check| | | |check| | 7.12.6.9 | F.10.3.9 |

libc/spec/stdc.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,8 @@ def StdC : StandardSpec<"stdc"> {
714714
GuardedFunctionSpec<"totalorderf16", RetValSpec<IntType>, [ArgSpec<Float16Ptr>, ArgSpec<Float16Ptr>], "LIBC_TYPES_HAS_FLOAT16">,
715715

716716
GuardedFunctionSpec<"totalordermagf16", RetValSpec<IntType>, [ArgSpec<Float16Ptr>, ArgSpec<Float16Ptr>], "LIBC_TYPES_HAS_FLOAT16">,
717+
718+
GuardedFunctionSpec<"getpayloadf16", RetValSpec<Float16Type>, [ArgSpec<Float16Ptr>], "LIBC_TYPES_HAS_FLOAT16">,
717719
]
718720
>;
719721

libc/src/__support/FPUtil/BasicOperations.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,17 @@ totalordermag(T x, T y) {
265265
return FPBits<T>(x).abs().uintval() <= FPBits<T>(y).abs().uintval();
266266
}
267267

268+
template <typename T>
269+
LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> getpayload(T x) {
270+
using FPBits = FPBits<T>;
271+
FPBits x_bits(x);
272+
273+
if (!x_bits.is_nan())
274+
return T(-1.0);
275+
276+
return T(x_bits.uintval() & (FPBits::FRACTION_MASK >> 1));
277+
}
278+
268279
} // namespace fputil
269280
} // namespace LIBC_NAMESPACE
270281

libc/src/math/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ add_math_entrypoint_object(fromfpxl)
206206
add_math_entrypoint_object(fromfpxf16)
207207
add_math_entrypoint_object(fromfpxf128)
208208

209+
add_math_entrypoint_object(getpayloadf16)
210+
209211
add_math_entrypoint_object(hypot)
210212
add_math_entrypoint_object(hypotf)
211213

libc/src/math/generic/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3601,3 +3601,15 @@ add_entrypoint_object(
36013601
COMPILE_OPTIONS
36023602
-O3
36033603
)
3604+
3605+
add_entrypoint_object(
3606+
getpayloadf16
3607+
SRCS
3608+
getpayloadf16.cpp
3609+
HDRS
3610+
../getpayloadf16.h
3611+
DEPENDS
3612+
libc.src.__support.FPUtil.basic_operations
3613+
COMPILE_OPTIONS
3614+
-O3
3615+
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===-- Implementation of getpayloadf16 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/getpayloadf16.h"
10+
#include "src/__support/FPUtil/BasicOperations.h"
11+
#include "src/__support/common.h"
12+
13+
namespace LIBC_NAMESPACE {
14+
15+
LLVM_LIBC_FUNCTION(float16, getpayloadf16, (const float16 *x)) {
16+
return fputil::getpayload(*x);
17+
}
18+
19+
} // namespace LIBC_NAMESPACE

libc/src/math/getpayloadf16.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header for getpayloadf16 -----------------*- 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_GETPAYLOADF16_H
10+
#define LLVM_LIBC_SRC_MATH_GETPAYLOADF16_H
11+
12+
#include "src/__support/macros/properties/types.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
float16 getpayloadf16(const float16 *x);
17+
18+
} // namespace LIBC_NAMESPACE
19+
20+
#endif // LLVM_LIBC_SRC_MATH_GETPAYLOADF16_H

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3543,3 +3543,15 @@ add_fp_unittest(
35433543
DEPENDS
35443544
libc.src.math.totalordermagf16
35453545
)
3546+
3547+
add_fp_unittest(
3548+
getpayloadf16_test
3549+
SUITE
3550+
libc-math-smoke-tests
3551+
SRCS
3552+
getpayloadf16_test.cpp
3553+
HDRS
3554+
GetPayloadTest.h
3555+
DEPENDS
3556+
libc.src.math.getpayloadf16
3557+
)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===-- Utility class to test different flavors of getpayload ---*- 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_GETPAYLOADTEST_H
10+
#define LIBC_TEST_SRC_MATH_SMOKE_GETPAYLOADTEST_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 GetPayloadTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
18+
19+
DECLARE_SPECIAL_CONSTANTS(T)
20+
21+
public:
22+
typedef T (*GetPayloadFunc)(const T *);
23+
24+
T funcWrapper(GetPayloadFunc func, T x) { return func(&x); }
25+
26+
void testNonNaNs(GetPayloadFunc func) {
27+
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(0.0)));
28+
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(-0.0)));
29+
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(0.1)));
30+
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(-0.1)));
31+
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(123.38)));
32+
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, T(-123.38)));
33+
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, inf));
34+
EXPECT_FP_EQ(T(-1.0), funcWrapper(func, neg_inf));
35+
}
36+
37+
void testNaNs(GetPayloadFunc func) {
38+
EXPECT_FP_EQ(T(0.0), funcWrapper(func, aNaN));
39+
EXPECT_FP_EQ(T(0.0), funcWrapper(func, neg_aNaN));
40+
41+
T default_snan_payload = StorageType(1) << (FPBits::SIG_LEN - 2);
42+
EXPECT_FP_EQ(default_snan_payload, funcWrapper(func, sNaN));
43+
EXPECT_FP_EQ(default_snan_payload, funcWrapper(func, neg_sNaN));
44+
45+
T qnan_42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val();
46+
T neg_qnan_42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val();
47+
T snan_42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val();
48+
T neg_snan_42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val();
49+
EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, qnan_42));
50+
EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_qnan_42));
51+
EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, snan_42));
52+
EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_snan_42));
53+
54+
T qnan_123 = FPBits::quiet_nan(Sign::POS, 0x123).get_val();
55+
T neg_qnan_123 = FPBits::quiet_nan(Sign::NEG, 0x123).get_val();
56+
T snan_123 = FPBits::signaling_nan(Sign::POS, 0x123).get_val();
57+
T neg_snan_123 = FPBits::signaling_nan(Sign::NEG, 0x123).get_val();
58+
EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, qnan_123));
59+
EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_qnan_123));
60+
EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, snan_123));
61+
EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_snan_123));
62+
}
63+
};
64+
65+
#define LIST_GETPAYLOAD_TESTS(T, func) \
66+
using LlvmLibcGetPayloadTest = GetPayloadTestTemplate<T>; \
67+
TEST_F(LlvmLibcGetPayloadTest, NonNaNs) { testNonNaNs(&func); } \
68+
TEST_F(LlvmLibcGetPayloadTest, NaNs) { testNaNs(&func); }
69+
70+
#endif // LIBC_TEST_SRC_MATH_SMOKE_GETPAYLOADTEST_H
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//===-- Unittests for getpayloadf16 ---------------------------------------===//
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 "GetPayloadTest.h"
10+
11+
#include "src/math/getpayloadf16.h"
12+
13+
LIST_GETPAYLOAD_TESTS(float16, LIBC_NAMESPACE::getpayloadf16)

0 commit comments

Comments
 (0)