Skip to content

Commit 4fc4ced

Browse files
committed
[libc][math][c23] Add acoshf16 C23 math function.
1 parent cac6d43 commit 4fc4ced

File tree

11 files changed

+221
-1
lines changed

11 files changed

+221
-1
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
653653
# math.h C23 _Float16 entrypoints
654654
libc.src.math.asinf16
655655
libc.src.math.acosf16
656+
libc.src.math.acoshf16
656657
libc.src.math.canonicalizef16
657658
libc.src.math.ceilf16
658659
libc.src.math.copysignf16

libc/docs/headers/math/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ Higher Math Functions
251251
+===========+==================+=================+========================+======================+========================+========================+============================+
252252
| acos | |check| | | | |check| | | 7.12.4.1 | F.10.1.1 |
253253
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
254-
| acosh | |check| | | | | | 7.12.5.1 | F.10.2.1 |
254+
| acosh | |check| | | | |check| | | 7.12.5.1 | F.10.2.1 |
255255
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
256256
| acospi | | | | | | 7.12.4.8 | F.10.1.8 |
257257
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+

libc/include/math.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ functions:
2727
return_type: float
2828
arguments:
2929
- type: float
30+
name: acoshf16
31+
standards:
32+
- stdc
33+
return_type: _Float16
34+
arguments:
35+
- type: _Float16
36+
guard: LIBC_TYPES_HAS_FLOAT16
3037
- name: asin
3138
standards:
3239
- stdc

libc/src/math/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ add_math_entrypoint_object(acosf16)
4646

4747
add_math_entrypoint_object(acosh)
4848
add_math_entrypoint_object(acoshf)
49+
add_math_entrypoint_object(acoshf16)
4950

5051
add_math_entrypoint_object(asin)
5152
add_math_entrypoint_object(asinf)

libc/src/math/acoshf16.h

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

libc/src/math/generic/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3944,6 +3944,26 @@ add_entrypoint_object(
39443944
libc.src.__support.macros.optimization
39453945
)
39463946

3947+
add_entrypoint_object(
3948+
acoshf16
3949+
SRCS
3950+
acoshf16.cpp
3951+
HDRS
3952+
../acoshf16.h
3953+
DEPENDS
3954+
libc.hdr.errno_macros
3955+
libc.hdr.fenv_macros
3956+
libc.src.__support.FPUtil.cast
3957+
libc.src.__support.FPUtil.except_value_utils
3958+
libc.src.__support.FPUtil.fenv_impl
3959+
libc.src.__support.FPUtil.fp_bits
3960+
libc.src.__support.FPUtil.multiply_add
3961+
libc.src.__support.FPUtil.polyeval
3962+
libc.src.__support.FPUtil.sqrt
3963+
libc.src.__support.macros.optimization
3964+
libc.src.__support.macros.properties.types
3965+
)
3966+
39473967
add_entrypoint_object(
39483968
asinhf
39493969
SRCS

libc/src/math/generic/acoshf16.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//===-- Half-precision acoshf16 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/acoshf16.h"
10+
#include "hdr/errno_macros.h"
11+
#include "hdr/fenv_macros.h"
12+
#include "src/__support/FPUtil/FEnvImpl.h"
13+
#include "src/__support/FPUtil/FPBits.h"
14+
#include "src/__support/FPUtil/sqrt.h"
15+
#include "src/__support/FPUtil/multiply_add.h"
16+
#include "src/__support/FPUtil/cast.h"
17+
#include "src/__support/macros/optimization.h"
18+
#include "src/math/generic/explogxf.h"
19+
20+
namespace LIBC_NAMESPACE_DECL {
21+
22+
LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
23+
using FPBits = fputil::FPBits<float16>;
24+
FPBits xbits(x);
25+
26+
uint16_t x_u = xbits.uintval();
27+
uint16_t x_abs = x_u & 0x7fff;
28+
29+
// acoshf16(x) domain: x >= 1.0
30+
if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
31+
fputil::set_errno_if_required(EDOM);
32+
fputil::raise_except_if_required(FE_INVALID);
33+
return FPBits::quiet_nan().get_val();
34+
}
35+
36+
if (LIBC_UNLIKELY(x == float16(1.0f)))
37+
return float16(0.0f);
38+
39+
// acosh(inf) = inf, acosh(NaN) = NaN
40+
if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
41+
return x;
42+
43+
// Compute in float32 for accuracy
44+
float xf32 = static_cast<float>(x);
45+
// sqrt(x^2 - 1)
46+
float sqrt_term = fputil::sqrt<float>(
47+
fputil::multiply_add(xf32, xf32, -1.0f));
48+
49+
// log(x + sqrt(x^2 - 1))
50+
float result = static_cast<float>(log_eval(xf32 + sqrt_term));
51+
52+
return fputil::cast<float16>(result);
53+
}
54+
55+
} // namespace LIBC_NAMESPACE_DECL

libc/test/src/math/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,6 +2173,17 @@ add_fp_unittest(
21732173
libc.src.__support.FPUtil.fp_bits
21742174
)
21752175

2176+
add_fp_unittest(
2177+
acoshf16_test
2178+
NEED_MPFR
2179+
SUITE
2180+
libc-math-unittests
2181+
SRCS
2182+
acoshf16_test.cpp
2183+
DEPENDS
2184+
libc.src.math.acoshf16
2185+
)
2186+
21762187
add_fp_unittest(
21772188
asinf_test
21782189
NEED_MPFR
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===-- Unittests for acoshf16 ---------------------------------------------===//
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/__support/FPUtil/FPBits.h"
10+
#include "src/errno/libc_errno.h"
11+
#include "src/math/acoshf16.h"
12+
#include "test/UnitTest/FPMatcher.h"
13+
#include "test/UnitTest/Test.h"
14+
#include "utils/MPFRWrapper/MPFRUtils.h"
15+
16+
using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
17+
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
18+
19+
TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
20+
LIBC_NAMESPACE::libc_errno = 0;
21+
22+
// NaN input
23+
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
24+
EXPECT_MATH_ERRNO(0);
25+
26+
// acoshf16(1.0) = 0
27+
EXPECT_FP_EQ_ALL_ROUNDING(float16(0.0f), LIBC_NAMESPACE::acoshf16(float16(1.0f)));
28+
EXPECT_MATH_ERRNO(0);
29+
30+
// Domain error (x < 1)
31+
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
32+
EXPECT_MATH_ERRNO(EDOM);
33+
34+
// acoshf16(+inf) = inf
35+
EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::acoshf16(inf));
36+
EXPECT_MATH_ERRNO(0);
37+
38+
// acoshf16(x) domain error (negative infinity)
39+
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
40+
EXPECT_MATH_ERRNO(EDOM);
41+
}
42+
43+
TEST_F(LlvmLibcAcoshf16Test, InFloat16Range) {
44+
constexpr uint16_t START = 0x3c00U; // 1.0
45+
constexpr uint16_t STOP = 0x7bffU; // Largest finite float16 value
46+
47+
for (uint16_t bits = START; bits <= STOP; ++bits) {
48+
float16 x = FPBits(bits).get_val();
49+
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, float(x),
50+
float(LIBC_NAMESPACE::acoshf16(x)), 0.5);
51+
}
52+
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3945,6 +3945,17 @@ add_fp_unittest(
39453945
libc.src.__support.FPUtil.fp_bits
39463946
)
39473947

3948+
add_fp_unittest(
3949+
acoshf16_test
3950+
SUITE
3951+
libc-math-smoke-tests
3952+
SRCS
3953+
acoshf16_test.cpp
3954+
DEPENDS
3955+
libc.src.errno.errno
3956+
libc.src.math.acoshf16
3957+
)
3958+
39483959
add_fp_unittest(
39493960
asinf_test
39503961
SUITE

0 commit comments

Comments
 (0)