Skip to content

Commit 0640c54

Browse files
committed
[libc][math][c23] Reduce MPFR to 1.
1 parent d9091d1 commit 0640c54

File tree

2 files changed

+21
-32
lines changed

2 files changed

+21
-32
lines changed

libc/src/math/generic/acoshf16.cpp

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,28 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/math/acoshf16.h"
10-
#include "hdr/errno_macros.h"
11-
#include "hdr/fenv_macros.h"
1210
#include "src/__support/FPUtil/FEnvImpl.h"
1311
#include "src/__support/FPUtil/FPBits.h"
1412
#include "src/__support/FPUtil/cast.h"
13+
#include "src/__support/FPUtil/except_value_utils.h"
14+
#include "src/__support/FPUtil/generic/sqrt.h"
1515
#include "src/__support/FPUtil/multiply_add.h"
16-
#include "src/__support/FPUtil/sqrt.h"
1716
#include "src/__support/macros/optimization.h"
18-
#include "src/math/generic/common_constants.h"
1917
#include "src/math/generic/explogxf.h"
2018

2119
namespace LIBC_NAMESPACE_DECL {
2220

21+
static constexpr size_t N_EXCEPTS = 1;
22+
static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
23+
{// (input, RZ output, RU offset, RD offset, RN offset)
24+
{0x41B7, 0x3ED8, 0, 1, 0}}};
25+
2326
LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
2427
using FPBits = fputil::FPBits<float16>;
2528
FPBits xbits(x);
2629
uint16_t x_u = xbits.uintval();
2730
uint16_t x_abs = x_u & 0x7fff;
2831

29-
// if (LIBC_UNLIKELY(x <= 1.0f)) {
30-
// if (x == 1.0f)
31-
// return 0.0f;
32-
// // x < 1.
33-
// fputil::set_errno_if_required(EDOM);
34-
// fputil::raise_except_if_required(FE_INVALID);
35-
// return FPBits::quiet_nan().get_val();
36-
// }
37-
3832
// Check for NaN input first.
3933
if (LIBC_UNLIKELY(xbits.is_nan())) {
4034
if (xbits.is_signaling_nan()) {
@@ -68,25 +62,20 @@ LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
6862
float xf32 = x;
6963

7064
// High precision for inputs very close to 1.0
71-
// if (LIBC_UNLIKELY(xf32 < 1.25f)) {
72-
// float delta = xf32 - 1.0f;
73-
// float sqrt_2 = fputil::sqrt<float>(2.0f * delta);
74-
// float sqrt_2d = fputil::sqrt<float>(2.0f * delta);
75-
// float d32 = delta * fputil::sqrt<float>(delta);
76-
// float term2 = d32 / (6.0f * fputil::sqrt<float>(2.0f));
77-
// float d52 = d32 * delta;
78-
// float term3 = 3.0f * d52 / (80.0f * sqrt_2);
79-
// float d72 = d52 * delta;
80-
// float term4 = 5.0f * d72 / (1792.0f * sqrt_2);
81-
// float result = sqrt_2d - term2 + term3 - term4;
82-
// return fputil::cast<float16>(result);
83-
// }
65+
if (LIBC_UNLIKELY(xf32 < 1.25f)) {
66+
float delta = xf32 - 1.0f;
67+
float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
68+
float x2 = delta;
69+
float pe = fputil::polyeval(x2, 0x1.0000000000000p+0f,
70+
-0x1.55551a83a9472p-4f, 0x1.331601c4b8ecfp-6f,
71+
-0x1.6890f49eb0acbp-8f, 0x1.8f3a617040a6ap-10f);
72+
float approx = sqrt_2_delta * pe;
73+
return fputil::cast<float16>(approx);
74+
}
8475

85-
// Special optimization for large input values.
86-
// if (LIBC_UNLIKELY(xf32 >= 32.0f)) {
87-
// float result = static_cast<float>(log_eval(2.0f * xf32));
88-
// return fputil::cast<float16>(result);
89-
// }
76+
if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
77+
LIBC_UNLIKELY(r.has_value()))
78+
return r.value();
9079

9180
// Standard computation for general case.
9281
float sqrt_term =

libc/test/src/math/acoshf16_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ TEST_F(LlvmLibcAcoshf16Test, PositiveRange) {
4848
float16 x = FPBits(v).get_val();
4949

5050
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x,
51-
LIBC_NAMESPACE::acoshf16(x), 3.0);
51+
LIBC_NAMESPACE::acoshf16(x), 1.0);
5252
}
5353
}
5454

0 commit comments

Comments
 (0)