[libc-commits] [libc] [libc][math][c23] implement C23 math function asinpif16 (PR #146226)
Mohamed Emad via libc-commits
libc-commits at lists.llvm.org
Sat Jun 28 10:09:31 PDT 2025
https://github.com/hulxv updated https://github.com/llvm/llvm-project/pull/146226
>From 790f1c42e74d1c2daf6133ec04ae542bcc00c2f6 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Fri, 27 Jun 2025 02:58:36 +0300
Subject: [PATCH 01/11] [libc][math][c23] implement C23 math function
`asinpif16`
---
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/docs/headers/math/index.rst | 2 +-
libc/include/math.yaml | 9 +-
libc/src/math/asinpif16.h | 21 +++
libc/src/math/generic/CMakeLists.txt | 16 ++
libc/src/math/generic/asinpif16.cpp | 191 ++++++++++++++++++++++
7 files changed, 239 insertions(+), 2 deletions(-)
create mode 100644 libc/src/math/asinpif16.h
create mode 100644 libc/src/math/generic/asinpif16.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index be5f5a66016b5..240d48f5bcdb8 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -651,6 +651,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# math.h C23 _Float16 entrypoints
# libc.src.math.acoshf16
+ libc.src.math.asinpif16
libc.src.math.canonicalizef16
libc.src.math.ceilf16
libc.src.math.copysignf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 73dfeae1a2c94..c9e5b0096099f 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -664,6 +664,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.acoshf16
libc.src.math.asinf16
libc.src.math.asinhf16
+ libc.src.math.asinpif16
libc.src.math.canonicalizef16
libc.src.math.ceilf16
libc.src.math.copysignf16
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index 947bd4b60b391..aaacc3ca92832 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -259,7 +259,7 @@ Higher Math Functions
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| asinh | |check| | | | |check| | | 7.12.5.2 | F.10.2.2 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| asinpi | | | | | | 7.12.4.9 | F.10.1.9 |
+| asinpi | | | | |check| | | 7.12.4.9 | F.10.1.9 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| atan | |check| | 1 ULP | | | | 7.12.4.3 | F.10.1.3 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/include/math.yaml b/libc/include/math.yaml
index fef829422244d..b49c17b871a93 100644
--- a/libc/include/math.yaml
+++ b/libc/include/math.yaml
@@ -71,7 +71,14 @@ functions:
- stdc
return_type: double
arguments:
- - type: double
+ - type: double
+ - name: asinpif16
+ standards:
+ - stdc
+ return_type: _Float16
+ arguments:
+ - type: _Float16
+ guard: LIBC_TYPES_HAS_FLOAT16
- name: atan2
standards:
- stdc
diff --git a/libc/src/math/asinpif16.h b/libc/src/math/asinpif16.h
new file mode 100644
index 0000000000000..67ccb4ff4ac3d
--- /dev/null
+++ b/libc/src/math/asinpif16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for asinpif16 ---------------------*- 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_ASINFPI16_H
+#define LLVM_LIBC_SRC_MATH_ASINFPI16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float16 asinpif16(float16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ASINPIF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index adbed5b2de48c..76accf72058d3 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4017,6 +4017,22 @@ add_entrypoint_object(
libc.src.__support.macros.properties.types
)
+add_entrypoint_object(
+ asinpif16
+ SRCS
+ asinpif16.cpp
+ HDRS
+ ../asinpif16.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.macros.optimization
+)
+
add_entrypoint_object(
atanhf
SRCS
diff --git a/libc/src/math/generic/asinpif16.cpp b/libc/src/math/generic/asinpif16.cpp
new file mode 100644
index 0000000000000..7de675211e5d2
--- /dev/null
+++ b/libc/src/math/generic/asinpif16.cpp
@@ -0,0 +1,191 @@
+//===-- Half-precision asinf16(x) 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 "hdr/errno_macros.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/asinfpi16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr float16 ONE_OVER_TWO = 0x3800; // 0.5f16
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+static constexpr size_t N_ASINFPI_EXCEPTS = 9;
+
+static constexpr float16 ONE_OVER_THREE = 0x3555; // 0.333251953125f16
+static constexpr float16 ONE_OVER_FOUR = 0x3400; // 0.25f16
+static constexpr float16 ONE_OVER_SIX = 0x32ab; // 0.166748046875f16
+
+static constexpr fputil::ExceptValues<float16, N_ASINFPI_EXCEPTS>
+ ASINFPI_EXCEPTS{{
+ // (input_hex, RZ_output_hex, RU_offset, RD_offset, RN_offset)
+
+ // x = 0.0, asinfpi(0.0) = 0.0
+ {0x0000, 0x0000, 0, 0, 0},
+
+ // x = 1.0, asinfpi(1.0) = 0.5
+ {0x3C00, ONE_OVER_TWO.uintval(), 0, 0, 0},
+
+ // x = -1.0, asinfpi(-1.0) = -0.5
+ {0xBC00, (fputil::FPBits<float16>(-ONE_OVER_TWO)).uintval(), 0, 0, 0},
+
+ // x = 0.5, asinfpi(0.5) = 1/6
+ {0x3800, ONE_OVER_SIX.uintval(), 0, 0, 0},
+
+ // x = -0.5, asinfpi(-0.5) = -1/6
+ {0xB800, (fputil::FPBits<float16>(-ONE_OVER_SIX)).uintval(), 0, 0, 0},
+
+ // x = sqrt(2)/2 ~ 0.70710678, asinfpi(x) = 1/4
+ // 0x3B41 is float16 for ~0.707. 0x3400 is float16 for 0.25
+ {0x3B41, ONE_OVER_FOUR.uintval(), 0, 0, 0},
+
+ // x = -sqrt(2)/2 ~ -0.70710678, asinfpi(x) = -1/4
+ {0xBB41, (fputil::FPBits<float16>(-ONE_OVER_FOUR)).uintval(), 0, 0, 0},
+
+ // x = sqrt(3)/2 ~ 0.8660254, asinfpi(x) = 1/3
+ // 0x3BF2 is float16 for ~0.866. 0x3555 is float16 for 1/3
+ {0x3BF2, ONE_OVER_THREE.uintval(), 0, 0, 0},
+
+ // x = -sqrt(3)/2 ~ -0.8660254, asinfpi(x) = -1/3
+ {0xBBF2, (fputil::FPBits<float16>(-ONE_OVER_THREE)).uintval(), 0, 0, 0},
+ }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
+ using FPBits = fputil::FPBits<float16>;
+
+ FPBits xbits(x);
+ uint16_t x_uint = xbits.uintval();
+ uint16_t x_abs = xbits.uintval() & 0x7fffU;
+ uint16_t x_sign = x_uint >> 15;
+
+ if (LIBC_UNLIKELY(x_abs > 0x3c00)) {
+ // aspinf16(NaN) = NaN
+ if (xbits.is_nan()) {
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ return x;
+ }
+
+ // 1 < |x| <= +/-inf
+ fputil::raise_except_if_required(FE_INVALID);
+ fputil::set_errno_if_required(EDOM);
+
+ return FPBits::quiet_nan().get_val();
+ }
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ // Handle exceptional values
+ if (auto r = ACOSF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+
+#else
+ // Handling zero
+ if (LIBC_UNLIKELY(x_abs == 0x0000)) {
+ return x;
+ }
+
+ // Handling +/-1.0
+ // If x is +/-1.0, return +/-0.5
+ if (LIBC_UNLIKELY(x_abs == 0x3c00)) {
+ return fputil::cast<float16>(x_sign ? -ONE_OVER_TWO : ONE_OVER_TWO);
+ }
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // the coefficients for the polynomial approximation of asin(x)/pi in the
+ // range [0, 0.5] extracted using python-sympy
+ //
+ // Python code to generate the coefficients:
+ // from sympy import *
+ // import math
+ // x = symbols('x')
+ // print(series(asin(x)/math.pi, x, 0, 21))
+ //
+ // OUTPUT:
+ //
+ // 0.318309886183791*x + 0.0530516476972984*x**3 + 0.0238732414637843*x**5 +
+ // 0.0142102627760621*x**7 + 0.00967087327815336*x**9 +
+ // 0.00712127941391293*x**11 + 0.00552355646848375*x**13 +
+ // 0.00444514782463692*x**15 + 0.00367705242846804*x**17 +
+ // 0.00310721681820837*x**19 + O(x**21)
+ //
+ // it's very accurate in the range [0, 0.5] and has a maximum error of
+ // 0.0000000000000001 in the range [0, 0.5].
+ static constexpr float16 POLY_COEFFS[10] = {
+ 0.318309886183791f16, // x^1
+ 0.0530516476972984f16, // x^3
+ 0.0238732414637843f16, // x^5
+ 0.0142102627760621f16, // x^7
+ 0.00967087327815336f16, // x^9
+ 0.00712127941391293f16, // x^11
+ 0.00552355646848375f16, // x^13
+ 0.00444514782463692f16, // x^15
+ 0.00367705242846804f16, // x^17
+ 0.00310721681820837f16 // x^19
+ };
+
+ // polynomial evaluation using horner's method
+ // work only for |x| in [0, 0.5]
+ auto __asinpi_polyeval = [](float16 xsq) -> float16 {
+ return fputil::polyeval(xsq, POLY_COEFFS[0], POLY_COEFFS[1], POLY_COEFFS[2],
+ POLY_COEFFS[3], POLY_COEFFS[4], POLY_COEFFS[5],
+ POLY_COEFFS[6], POLY_COEFFS[7], POLY_COEFFS[9],
+ POLY_COEFFS[9]);
+ };
+
+ // if |x| <= 0.5:
+ if (x_abs <= 0x3800) {
+ // Use polynomial approximation of asin(x)/pi in the range [0, 0.5]
+ float16 xsq = x * x;
+ float16 result = x * __asinpi_polyeval(xsq);
+ return fputil::cast<float16>(result);
+ }
+
+ // If |x| > 0.5, we need to use the range reduction method:
+ // y = asin(x) => x = sin(y)
+ // because: sin(a) = cos(pi/2 - a)
+ // therefore:
+ // x = cos(pi/2 - y)
+ // let z = pi/2 - y,
+ // x = cos(z)
+ // becuase: cos(2a) = 1 - 2 * sin^2(a), z = 2a, a = z/2
+ // therefore:
+ // cos(z) = 1 - 2 * sin^2(z/2)
+ // sin(z/2) = sqrt((1 - cos(z))/2)
+ // sin(z/2) = sqrt((1 - x)/2)
+ // let u = (1 - x)/2
+ // then:
+ // sin(z/2) = sqrt(u)
+ // z/2 = asin(sqrt(u))
+ // z = 2 * asin(sqrt(u))
+ // pi/2 - y = 2 * asin(sqrt(u))
+ // y = pi/2 - 2 * asin(sqrt(u))
+ // y/pi = 1/2 - 2 * asin(sqrt(u))/pi
+ //
+ // Finally, we can write:
+ // asinpi(x) = 1/2 - 2 * asinpi(sqrt(u))
+
+ float16 u = fputil::multiply_add(-ONE_OVER_TWO, x, ONE_OVER_TWO);
+
+ float16 asinpi_sqrt_u = __asinpi_polyeval(u);
+
+ float16 result = fputil::multiply_add(-2.0f16, asinpi_sqrt_u, ONE_OVER_TWO);
+
+ return fputil::cast<float16>(result);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
>From 813f341c3efa799fa310d8ff17d0c84323434b57 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Fri, 27 Jun 2025 22:40:29 +0300
Subject: [PATCH 02/11] formatting
---
libc/src/math/generic/asinpif16.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/libc/src/math/generic/asinpif16.cpp b/libc/src/math/generic/asinpif16.cpp
index 7de675211e5d2..facb06b540644 100644
--- a/libc/src/math/generic/asinpif16.cpp
+++ b/libc/src/math/generic/asinpif16.cpp
@@ -180,9 +180,7 @@ LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
// asinpi(x) = 1/2 - 2 * asinpi(sqrt(u))
float16 u = fputil::multiply_add(-ONE_OVER_TWO, x, ONE_OVER_TWO);
-
float16 asinpi_sqrt_u = __asinpi_polyeval(u);
-
float16 result = fputil::multiply_add(-2.0f16, asinpi_sqrt_u, ONE_OVER_TWO);
return fputil::cast<float16>(result);
>From 69e654e4657283b8dd7123b781953909cc14b66c Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Fri, 27 Jun 2025 22:46:14 +0300
Subject: [PATCH 03/11] builld: add missed entrypoint
---
libc/src/math/CMakeLists.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index d177ff79141c0..e7ccb3726c54c 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -56,6 +56,8 @@ add_math_entrypoint_object(asinh)
add_math_entrypoint_object(asinhf)
add_math_entrypoint_object(asinhf16)
+add_math_entrypoint_object(asinpif16)
+
add_math_entrypoint_object(atan)
add_math_entrypoint_object(atanf)
>From 453cf1850b70c49b297dab33548677e5fea1e20c Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Fri, 27 Jun 2025 22:46:33 +0300
Subject: [PATCH 04/11] test: add unit tests for `asinpif16`
---
libc/test/src/math/CMakeLists.txt | 11 ++
libc/test/src/math/asinpif16_test.cpp | 140 ++++++++++++++++++++++++++
2 files changed, 151 insertions(+)
create mode 100644 libc/test/src/math/asinpif16_test.cpp
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 7ee8b86135557..e6786a706eec9 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2245,6 +2245,17 @@ add_fp_unittest(
libc.src.math.asinf16
)
+add_fp_unittest(
+ asinfpi16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ asinpif16_test.cpp
+ DEPENDS
+ libc.src.math.asinpif16
+)
+
add_fp_unittest(
acosf_test
NEED_MPFR
diff --git a/libc/test/src/math/asinpif16_test.cpp b/libc/test/src/math/asinpif16_test.cpp
new file mode 100644
index 0000000000000..ba01bc0119f0c
--- /dev/null
+++ b/libc/test/src/math/asinpif16_test.cpp
@@ -0,0 +1,140 @@
+//===-- Unittests for asinpif16 -------------------------------------------===//
+//
+// 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/errno/libc_errno.h"
+#include "src/math/asinpif16.h"
+#include "test/UnitTest/FPMatcher.h"
+
+#include <errno.h>
+#include <stdint.h>
+
+using LlvmLibcAsinpif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAsinpif16Test, SpecialNumbers) {
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<float16>;
+
+ // Test zero
+ EXPECT_FP_EQ(FPBits::zero(), LIBC_NAMESPACE::asinpif16(FPBits::zero()));
+ EXPECT_FP_EQ(FPBits::neg_zero(),
+ LIBC_NAMESPACE::asinpif16(FPBits::neg_zero()));
+
+ // Test +/-1
+ EXPECT_FP_EQ(float16(0.5), LIBC_NAMESPACE::asinpif16(float16(1.0)));
+ EXPECT_FP_EQ(float16(-0.5), LIBC_NAMESPACE::asinpif16(float16(-1.0)));
+
+ // Test NaN inputs
+ EXPECT_FP_EQ(FPBits::quiet_nan(),
+ LIBC_NAMESPACE::asinpif16(FPBits::quiet_nan()));
+ EXPECT_FP_EQ(FPBits::quiet_nan(),
+ LIBC_NAMESPACE::asinpif16(FPBits::signaling_nan()));
+
+ // Test infinity inputs - should return NaN and set errno
+ errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan(), LIBC_NAMESPACE::asinpif16(FPBits::inf()));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan(),
+ LIBC_NAMESPACE::asinpif16(FPBits::neg_inf()));
+ EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAsinpif16Test, OutOfRange) {
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<float16>;
+
+ // Test values > 1
+ errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan(), LIBC_NAMESPACE::asinpif16(float16(1.5)));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan(), LIBC_NAMESPACE::asinpif16(float16(2.0)));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ // Test values < -1
+ errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan(), LIBC_NAMESPACE::asinpif16(float16(-1.5)));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan(), LIBC_NAMESPACE::asinpif16(float16(-2.0)));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ // Test maximum normal value (should be > 1 for float16)
+ errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan(),
+ LIBC_NAMESPACE::asinpif16(FPBits::max_normal()));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan(),
+ LIBC_NAMESPACE::asinpif16(FPBits::max_normal().get_sign()));
+ EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAsinpif16Test, SmallValues) {
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<float16>;
+
+ // Test very small values - should be close to x/π
+ constexpr float16 small_vals[] = {
+ 0x1.0p-10, // Small positive
+ -0x1.0p-10, // Small negative
+ 0x1.0p-14, // Very small positive
+ -0x1.0p-14, // Very small negative
+ };
+
+ for (float16 x : small_vals) {
+ float16 result = LIBC_NAMESPACE::asinpif16(x);
+ // For small x, asinpi(x) ≈ x/π ≈ 0.318309886 * x
+ // We expect the result to be close to x/π but not exactly due to polynomial
+ // approximation
+ EXPECT_TRUE(LIBC_NAMESPACE::fputil::abs(result) <=
+ LIBC_NAMESPACE::fputil::abs(x));
+ }
+
+ // Test minimum subnormal values
+ EXPECT_FP_EQ_ALL_ROUNDING(FPBits::min_subnormal(),
+ LIBC_NAMESPACE::asinpif16(FPBits::min_subnormal()));
+ EXPECT_FP_EQ_ALL_ROUNDING(
+ FPBits::min_subnormal().get_sign(),
+ LIBC_NAMESPACE::asinpif16(FPBits::min_subnormal().get_sign()));
+}
+
+
+TEST_F(LlvmLibcAsinpif16Test, SymmetryProperty) {
+ // Test that asinpi(-x) = -asinpi(x)
+ constexpr float16 test_vals[] = {0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 1.0};
+
+ for (float16 x : test_vals) {
+ if (x <= 1.0) { // Only test valid domain
+ float16 pos_result = LIBC_NAMESPACE::asinpif16(x);
+ float16 neg_result = LIBC_NAMESPACE::asinpif16(-x);
+
+ EXPECT_FP_EQ(pos_result, -neg_result);
+ }
+ }
+}
+
+TEST_F(LlvmLibcAsinpif16Test, RangeValidation) {
+ // Test that output is always in [-0.5, 0.5] for valid inputs
+ constexpr int num_tests = 1000;
+
+ for (int i = 0; i <= num_tests; ++i) {
+ // Generate test value in [-1, 1]
+ float t = -1.0f + (2.0f * i) / num_tests;
+ float16 x = static_cast<float16>(t);
+
+ if (LIBC_NAMESPACE::fputil::abs(x) <= 1.0) {
+ float16 result = LIBC_NAMESPACE::asinpif16(x);
+
+ // Result should be in [-0.5, 0.5]
+ EXPECT_TRUE(result >= -0.5);
+ EXPECT_TRUE(result <= 0.5);
+ }
+ }
+}
\ No newline at end of file
>From 1897e003b564b6fbe6010719156bd11f5a536975 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 28 Jun 2025 18:43:51 +0300
Subject: [PATCH 05/11] fix the typo in unittest build entry
---
libc/test/src/math/CMakeLists.txt | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index e6786a706eec9..bd62b76817ceb 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2246,14 +2246,16 @@ add_fp_unittest(
)
add_fp_unittest(
- asinfpi16_test
+ asinpif16_test
NEED_MPFR
SUITE
libc-math-unittests
SRCS
asinpif16_test.cpp
DEPENDS
- libc.src.math.asinpif16
+ libc.src.math.fabs
+ libc.src.math.asinpif16
+ libc.src.__support.FPUtil.fp_bits
)
add_fp_unittest(
>From a8122b77119ad5fa812ba884f525c21c98e16006 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 28 Jun 2025 19:07:34 +0300
Subject: [PATCH 06/11] fix bugs
---
libc/src/math/generic/asinpif16.cpp | 98 +++++++++++++----------------
1 file changed, 43 insertions(+), 55 deletions(-)
diff --git a/libc/src/math/generic/asinpif16.cpp b/libc/src/math/generic/asinpif16.cpp
index facb06b540644..34b0b7e7779fc 100644
--- a/libc/src/math/generic/asinpif16.cpp
+++ b/libc/src/math/generic/asinpif16.cpp
@@ -6,60 +6,40 @@
//
//===----------------------------------------------------------------------===//
+#include "src/math/asinpif16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/FPUtil/sqrt.h"
#include "src/__support/macros/optimization.h"
-#include "src/math/asinfpi16.h"
namespace LIBC_NAMESPACE_DECL {
-static constexpr float16 ONE_OVER_TWO = 0x3800; // 0.5f16
+static constexpr float16 ONE_OVER_TWO = 0.5f16;
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-static constexpr size_t N_ASINFPI_EXCEPTS = 9;
-
-static constexpr float16 ONE_OVER_THREE = 0x3555; // 0.333251953125f16
-static constexpr float16 ONE_OVER_FOUR = 0x3400; // 0.25f16
-static constexpr float16 ONE_OVER_SIX = 0x32ab; // 0.166748046875f16
+static constexpr size_t N_ASINFPI_EXCEPTS = 3;
+static constexpr float16 ONE_OVER_SIX = 0.166748046875f16;
static constexpr fputil::ExceptValues<float16, N_ASINFPI_EXCEPTS>
ASINFPI_EXCEPTS{{
// (input_hex, RZ_output_hex, RU_offset, RD_offset, RN_offset)
-
// x = 0.0, asinfpi(0.0) = 0.0
{0x0000, 0x0000, 0, 0, 0},
// x = 1.0, asinfpi(1.0) = 0.5
- {0x3C00, ONE_OVER_TWO.uintval(), 0, 0, 0},
-
- // x = -1.0, asinfpi(-1.0) = -0.5
- {0xBC00, (fputil::FPBits<float16>(-ONE_OVER_TWO)).uintval(), 0, 0, 0},
+ {(fputil::FPBits<float16>(1.0f16)).uintval(),
+ (fputil::FPBits<float16>(ONE_OVER_TWO)).uintval(), 0, 0, 0},
// x = 0.5, asinfpi(0.5) = 1/6
- {0x3800, ONE_OVER_SIX.uintval(), 0, 0, 0},
-
- // x = -0.5, asinfpi(-0.5) = -1/6
- {0xB800, (fputil::FPBits<float16>(-ONE_OVER_SIX)).uintval(), 0, 0, 0},
-
- // x = sqrt(2)/2 ~ 0.70710678, asinfpi(x) = 1/4
- // 0x3B41 is float16 for ~0.707. 0x3400 is float16 for 0.25
- {0x3B41, ONE_OVER_FOUR.uintval(), 0, 0, 0},
-
- // x = -sqrt(2)/2 ~ -0.70710678, asinfpi(x) = -1/4
- {0xBB41, (fputil::FPBits<float16>(-ONE_OVER_FOUR)).uintval(), 0, 0, 0},
-
- // x = sqrt(3)/2 ~ 0.8660254, asinfpi(x) = 1/3
- // 0x3BF2 is float16 for ~0.866. 0x3555 is float16 for 1/3
- {0x3BF2, ONE_OVER_THREE.uintval(), 0, 0, 0},
+ {(fputil::FPBits<float16>(0.5f16)).uintval(),
+ (fputil::FPBits<float16>(ONE_OVER_SIX)).uintval(), 0, 0, 0},
- // x = -sqrt(3)/2 ~ -0.8660254, asinfpi(x) = -1/3
- {0xBBF2, (fputil::FPBits<float16>(-ONE_OVER_THREE)).uintval(), 0, 0, 0},
}};
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
@@ -68,10 +48,14 @@ LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
FPBits xbits(x);
uint16_t x_uint = xbits.uintval();
- uint16_t x_abs = xbits.uintval() & 0x7fffU;
- uint16_t x_sign = x_uint >> 15;
+ bool is_neg = static_cast<bool>(x_uint >> 15);
+ float16 x_abs = is_neg ? -x : x;
- if (LIBC_UNLIKELY(x_abs > 0x3c00)) {
+ auto __signed_result = [is_neg](float16 r) -> float16 {
+ return is_neg ? -r : r;
+ };
+
+ if (LIBC_UNLIKELY(x_abs > 1.0f16)) {
// aspinf16(NaN) = NaN
if (xbits.is_nan()) {
if (xbits.is_signaling_nan()) {
@@ -89,31 +73,31 @@ LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
}
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Handle exceptional values
- if (auto r = ACOSF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
- return r.value();
-
-#else
- // Handling zero
- if (LIBC_UNLIKELY(x_abs == 0x0000)) {
- return x;
+ // exceptional values
+ if (auto r = ASINFPI_EXCEPTS.lookup(x_uint); LIBC_UNLIKELY(r.has_value())) {
+ return (r.value());
+ }
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // zero
+ if (LIBC_UNLIKELY(x_abs == 0.0f16)) {
+ return 0.0f16;
}
- // Handling +/-1.0
- // If x is +/-1.0, return +/-0.5
- if (LIBC_UNLIKELY(x_abs == 0x3c00)) {
- return fputil::cast<float16>(x_sign ? -ONE_OVER_TWO : ONE_OVER_TWO);
+ // +/-1.0
+ // if x is +/-1.0, return +/-0.5
+ if (LIBC_UNLIKELY(x_abs == 1.0f16)) {
+ return fputil::cast<float16>(__signed_result(ONE_OVER_TWO));
}
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
// the coefficients for the polynomial approximation of asin(x)/pi in the
// range [0, 0.5] extracted using python-sympy
//
// Python code to generate the coefficients:
- // from sympy import *
- // import math
- // x = symbols('x')
- // print(series(asin(x)/math.pi, x, 0, 21))
+ // > from sympy import *
+ // > import math
+ // > x = symbols('x')
+ // > print(series(asin(x)/math.pi, x, 0, 21))
//
// OUTPUT:
//
@@ -143,16 +127,16 @@ LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
auto __asinpi_polyeval = [](float16 xsq) -> float16 {
return fputil::polyeval(xsq, POLY_COEFFS[0], POLY_COEFFS[1], POLY_COEFFS[2],
POLY_COEFFS[3], POLY_COEFFS[4], POLY_COEFFS[5],
- POLY_COEFFS[6], POLY_COEFFS[7], POLY_COEFFS[9],
+ POLY_COEFFS[6], POLY_COEFFS[7], POLY_COEFFS[8],
POLY_COEFFS[9]);
};
// if |x| <= 0.5:
- if (x_abs <= 0x3800) {
+ if (LIBC_UNLIKELY(x_abs <= ONE_OVER_TWO)) {
// Use polynomial approximation of asin(x)/pi in the range [0, 0.5]
float16 xsq = x * x;
float16 result = x * __asinpi_polyeval(xsq);
- return fputil::cast<float16>(result);
+ return fputil::cast<float16>(__signed_result(result));
}
// If |x| > 0.5, we need to use the range reduction method:
@@ -178,12 +162,16 @@ LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
//
// Finally, we can write:
// asinpi(x) = 1/2 - 2 * asinpi(sqrt(u))
+ // where u = (1 - x) /2
+ // = 0.5 - 0.5 * x
+ // = multiply_add(-0.5, x, 0.5)
- float16 u = fputil::multiply_add(-ONE_OVER_TWO, x, ONE_OVER_TWO);
- float16 asinpi_sqrt_u = __asinpi_polyeval(u);
+ float16 u = fputil::multiply_add(-ONE_OVER_TWO, x_abs, ONE_OVER_TWO);
+ float16 u_sqrt = fputil::sqrt<float16>(u);
+ float16 asinpi_sqrt_u = u_sqrt * __asinpi_polyeval(u);
float16 result = fputil::multiply_add(-2.0f16, asinpi_sqrt_u, ONE_OVER_TWO);
- return fputil::cast<float16>(result);
+ return fputil::cast<float16>(__signed_result(result));
}
} // namespace LIBC_NAMESPACE_DECL
>From 50f9029c0945379a2e788135a184639cd0d66d83 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 28 Jun 2025 19:07:45 +0300
Subject: [PATCH 07/11] fix the test
---
libc/test/src/math/asinpif16_test.cpp | 102 +++++++++-----------------
1 file changed, 36 insertions(+), 66 deletions(-)
diff --git a/libc/test/src/math/asinpif16_test.cpp b/libc/test/src/math/asinpif16_test.cpp
index ba01bc0119f0c..6d8f76568902e 100644
--- a/libc/test/src/math/asinpif16_test.cpp
+++ b/libc/test/src/math/asinpif16_test.cpp
@@ -8,6 +8,7 @@
#include "src/errno/libc_errno.h"
#include "src/math/asinpif16.h"
+#include "src/math/fabs.h"
#include "test/UnitTest/FPMatcher.h"
#include <errno.h>
@@ -18,29 +19,28 @@ using LlvmLibcAsinpif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
TEST_F(LlvmLibcAsinpif16Test, SpecialNumbers) {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<float16>;
- // Test zero
- EXPECT_FP_EQ(FPBits::zero(), LIBC_NAMESPACE::asinpif16(FPBits::zero()));
- EXPECT_FP_EQ(FPBits::neg_zero(),
- LIBC_NAMESPACE::asinpif16(FPBits::neg_zero()));
+ // zero
+ EXPECT_FP_EQ(0.0f16, LIBC_NAMESPACE::asinpif16(0.0f16));
- // Test +/-1
+ // +/-1
EXPECT_FP_EQ(float16(0.5), LIBC_NAMESPACE::asinpif16(float16(1.0)));
EXPECT_FP_EQ(float16(-0.5), LIBC_NAMESPACE::asinpif16(float16(-1.0)));
- // Test NaN inputs
- EXPECT_FP_EQ(FPBits::quiet_nan(),
- LIBC_NAMESPACE::asinpif16(FPBits::quiet_nan()));
- EXPECT_FP_EQ(FPBits::quiet_nan(),
- LIBC_NAMESPACE::asinpif16(FPBits::signaling_nan()));
+ // NaN inputs
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(FPBits::quiet_nan().get_val()));
- // Test infinity inputs - should return NaN and set errno
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(FPBits::signaling_nan().get_val()));
+
+ // infinity inputs -> should return NaN
errno = 0;
- EXPECT_FP_EQ(FPBits::quiet_nan(), LIBC_NAMESPACE::asinpif16(FPBits::inf()));
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), LIBC_NAMESPACE::asinpif16(inf));
EXPECT_MATH_ERRNO(EDOM);
errno = 0;
- EXPECT_FP_EQ(FPBits::quiet_nan(),
- LIBC_NAMESPACE::asinpif16(FPBits::neg_inf()));
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(neg_inf));
EXPECT_MATH_ERRNO(EDOM);
}
@@ -49,73 +49,44 @@ TEST_F(LlvmLibcAsinpif16Test, OutOfRange) {
// Test values > 1
errno = 0;
- EXPECT_FP_EQ(FPBits::quiet_nan(), LIBC_NAMESPACE::asinpif16(float16(1.5)));
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(float16(1.5)));
EXPECT_MATH_ERRNO(EDOM);
errno = 0;
- EXPECT_FP_EQ(FPBits::quiet_nan(), LIBC_NAMESPACE::asinpif16(float16(2.0)));
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(float16(2.0)));
EXPECT_MATH_ERRNO(EDOM);
// Test values < -1
errno = 0;
- EXPECT_FP_EQ(FPBits::quiet_nan(), LIBC_NAMESPACE::asinpif16(float16(-1.5)));
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(float16(-1.5)));
EXPECT_MATH_ERRNO(EDOM);
errno = 0;
- EXPECT_FP_EQ(FPBits::quiet_nan(), LIBC_NAMESPACE::asinpif16(float16(-2.0)));
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(float16(-2.0)));
EXPECT_MATH_ERRNO(EDOM);
// Test maximum normal value (should be > 1 for float16)
errno = 0;
- EXPECT_FP_EQ(FPBits::quiet_nan(),
- LIBC_NAMESPACE::asinpif16(FPBits::max_normal()));
- EXPECT_MATH_ERRNO(EDOM);
-
- errno = 0;
- EXPECT_FP_EQ(FPBits::quiet_nan(),
- LIBC_NAMESPACE::asinpif16(FPBits::max_normal().get_sign()));
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(FPBits::max_normal().get_val()));
EXPECT_MATH_ERRNO(EDOM);
}
-TEST_F(LlvmLibcAsinpif16Test, SmallValues) {
- using FPBits = LIBC_NAMESPACE::fputil::FPBits<float16>;
-
- // Test very small values - should be close to x/π
- constexpr float16 small_vals[] = {
- 0x1.0p-10, // Small positive
- -0x1.0p-10, // Small negative
- 0x1.0p-14, // Very small positive
- -0x1.0p-14, // Very small negative
- };
-
- for (float16 x : small_vals) {
- float16 result = LIBC_NAMESPACE::asinpif16(x);
- // For small x, asinpi(x) ≈ x/π ≈ 0.318309886 * x
- // We expect the result to be close to x/π but not exactly due to polynomial
- // approximation
- EXPECT_TRUE(LIBC_NAMESPACE::fputil::abs(result) <=
- LIBC_NAMESPACE::fputil::abs(x));
- }
-
- // Test minimum subnormal values
- EXPECT_FP_EQ_ALL_ROUNDING(FPBits::min_subnormal(),
- LIBC_NAMESPACE::asinpif16(FPBits::min_subnormal()));
- EXPECT_FP_EQ_ALL_ROUNDING(
- FPBits::min_subnormal().get_sign(),
- LIBC_NAMESPACE::asinpif16(FPBits::min_subnormal().get_sign()));
-}
-
-
TEST_F(LlvmLibcAsinpif16Test, SymmetryProperty) {
// Test that asinpi(-x) = -asinpi(x)
- constexpr float16 test_vals[] = {0.1, 0.25, 0.5, 0.75, 0.9, 0.99, 1.0};
+ constexpr float16 test_vals[] = {0.1f16, 0.25f16, 0.5f16, 0.75f16,
+ 0.9f16, 0.99f16, 1.0f16};
for (float16 x : test_vals) {
- if (x <= 1.0) { // Only test valid domain
+ if (x <= 1.0) {
float16 pos_result = LIBC_NAMESPACE::asinpif16(x);
float16 neg_result = LIBC_NAMESPACE::asinpif16(-x);
- EXPECT_FP_EQ(pos_result, -neg_result);
+ EXPECT_FP_EQ(pos_result, LIBC_NAMESPACE::fabs(neg_result));
}
}
}
@@ -125,16 +96,15 @@ TEST_F(LlvmLibcAsinpif16Test, RangeValidation) {
constexpr int num_tests = 1000;
for (int i = 0; i <= num_tests; ++i) {
- // Generate test value in [-1, 1]
- float t = -1.0f + (2.0f * i) / num_tests;
- float16 x = static_cast<float16>(t);
+ float16 t = -1.0f16 + (2.0f16 * static_cast<float16>(i)) /
+ static_cast<float16>(num_tests);
- if (LIBC_NAMESPACE::fputil::abs(x) <= 1.0) {
- float16 result = LIBC_NAMESPACE::asinpif16(x);
+ if (LIBC_NAMESPACE::fabs(t) <= 1.0) {
+ float16 result = LIBC_NAMESPACE::asinpif16(t);
- // Result should be in [-0.5, 0.5]
- EXPECT_TRUE(result >= -0.5);
- EXPECT_TRUE(result <= 0.5);
+ // should be in [-0.5, 0.5]
+ EXPECT_TRUE(result >= -0.5f16);
+ EXPECT_TRUE(result <= 0.5f16);
}
}
-}
\ No newline at end of file
+}
>From 930f5be76abced4cf2762a32d23a99fdd105780e Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 28 Jun 2025 19:41:29 +0300
Subject: [PATCH 08/11] remove unesseccery code
---
libc/src/math/generic/asinpif16.cpp | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/libc/src/math/generic/asinpif16.cpp b/libc/src/math/generic/asinpif16.cpp
index 34b0b7e7779fc..b66327c536f5f 100644
--- a/libc/src/math/generic/asinpif16.cpp
+++ b/libc/src/math/generic/asinpif16.cpp
@@ -79,17 +79,6 @@ LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
}
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // zero
- if (LIBC_UNLIKELY(x_abs == 0.0f16)) {
- return 0.0f16;
- }
-
- // +/-1.0
- // if x is +/-1.0, return +/-0.5
- if (LIBC_UNLIKELY(x_abs == 1.0f16)) {
- return fputil::cast<float16>(__signed_result(ONE_OVER_TWO));
- }
-
// the coefficients for the polynomial approximation of asin(x)/pi in the
// range [0, 0.5] extracted using python-sympy
//
@@ -101,6 +90,7 @@ LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
//
// OUTPUT:
//
+ //
// 0.318309886183791*x + 0.0530516476972984*x**3 + 0.0238732414637843*x**5 +
// 0.0142102627760621*x**7 + 0.00967087327815336*x**9 +
// 0.00712127941391293*x**11 + 0.00552355646848375*x**13 +
>From 3db1b0dcbd0fd2890d9ad12ea4842de6092dc867 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 28 Jun 2025 20:06:35 +0300
Subject: [PATCH 09/11] add negatives for expected values
---
libc/src/math/generic/asinpif16.cpp | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/libc/src/math/generic/asinpif16.cpp b/libc/src/math/generic/asinpif16.cpp
index b66327c536f5f..fdcf8f78bb8d0 100644
--- a/libc/src/math/generic/asinpif16.cpp
+++ b/libc/src/math/generic/asinpif16.cpp
@@ -23,7 +23,7 @@ namespace LIBC_NAMESPACE_DECL {
static constexpr float16 ONE_OVER_TWO = 0.5f16;
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-static constexpr size_t N_ASINFPI_EXCEPTS = 3;
+static constexpr size_t N_ASINFPI_EXCEPTS = 5;
static constexpr float16 ONE_OVER_SIX = 0.166748046875f16;
static constexpr fputil::ExceptValues<float16, N_ASINFPI_EXCEPTS>
@@ -32,14 +32,22 @@ static constexpr fputil::ExceptValues<float16, N_ASINFPI_EXCEPTS>
// x = 0.0, asinfpi(0.0) = 0.0
{0x0000, 0x0000, 0, 0, 0},
- // x = 1.0, asinfpi(1.0) = 0.5
- {(fputil::FPBits<float16>(1.0f16)).uintval(),
- (fputil::FPBits<float16>(ONE_OVER_TWO)).uintval(), 0, 0, 0},
+ // x = 1.0, asinfpi(1) = 1/2
+ {(fputil::FPBits<float16>(-1.0f16)).uintval(),
+ (fputil::FPBits<float16>(-ONE_OVER_TWO)).uintval(), 0, 0, 0},
+
+ // x = -1.0, asinfpi(-1.0) = -1/2
+ {(fputil::FPBits<float16>(-1.0f16)).uintval(),
+ (fputil::FPBits<float16>(-ONE_OVER_TWO)).uintval(), 0, 0, 0},
// x = 0.5, asinfpi(0.5) = 1/6
{(fputil::FPBits<float16>(0.5f16)).uintval(),
(fputil::FPBits<float16>(ONE_OVER_SIX)).uintval(), 0, 0, 0},
+ // x = -0.5, asinfpi(0.5) = -1/6
+ {(fputil::FPBits<float16>(-0.5f16)).uintval(),
+ (fputil::FPBits<float16>(-ONE_OVER_SIX)).uintval(), 0, 0, 0},
+
}};
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
@@ -75,7 +83,7 @@ LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
// exceptional values
if (auto r = ASINFPI_EXCEPTS.lookup(x_uint); LIBC_UNLIKELY(r.has_value())) {
- return (r.value());
+ return r.value();
}
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
@@ -90,7 +98,7 @@ LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
//
// OUTPUT:
//
- //
+ //
// 0.318309886183791*x + 0.0530516476972984*x**3 + 0.0238732414637843*x**5 +
// 0.0142102627760621*x**7 + 0.00967087327815336*x**9 +
// 0.00712127941391293*x**11 + 0.00552355646848375*x**13 +
>From 1097815848c58f49c6523a252d62eabcac23128c Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 28 Jun 2025 20:06:52 +0300
Subject: [PATCH 10/11] remove unused headers
---
libc/test/src/math/asinpif16_test.cpp | 4 ----
1 file changed, 4 deletions(-)
diff --git a/libc/test/src/math/asinpif16_test.cpp b/libc/test/src/math/asinpif16_test.cpp
index 6d8f76568902e..7dad1b8fff3ed 100644
--- a/libc/test/src/math/asinpif16_test.cpp
+++ b/libc/test/src/math/asinpif16_test.cpp
@@ -6,14 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#include "src/errno/libc_errno.h"
#include "src/math/asinpif16.h"
#include "src/math/fabs.h"
#include "test/UnitTest/FPMatcher.h"
-#include <errno.h>
-#include <stdint.h>
-
using LlvmLibcAsinpif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
TEST_F(LlvmLibcAsinpif16Test, SpecialNumbers) {
>From efa3207b799456c32b4971a628b6f167d824b0f2 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 28 Jun 2025 20:09:13 +0300
Subject: [PATCH 11/11] fix formatting
---
libc/src/math/generic/asinpif16.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/libc/src/math/generic/asinpif16.cpp b/libc/src/math/generic/asinpif16.cpp
index fdcf8f78bb8d0..fdfb4484c9dfe 100644
--- a/libc/src/math/generic/asinpif16.cpp
+++ b/libc/src/math/generic/asinpif16.cpp
@@ -98,7 +98,6 @@ LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
//
// OUTPUT:
//
- //
// 0.318309886183791*x + 0.0530516476972984*x**3 + 0.0238732414637843*x**5 +
// 0.0142102627760621*x**7 + 0.00967087327815336*x**9 +
// 0.00712127941391293*x**11 + 0.00552355646848375*x**13 +
More information about the libc-commits
mailing list