Skip to content

[libc] Add sinpif16 function #110994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.sinf
libc.src.math.sinhf
libc.src.math.sinpif
libc.src.math.sinpif16
libc.src.math.sqrt
libc.src.math.sqrtf
libc.src.math.sqrtl
Expand Down Expand Up @@ -668,7 +667,8 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.scalblnf16
libc.src.math.scalbnf16
libc.src.math.setpayloadf16
libc.src.math.setpayloadsigf16
libc.src.math.setpayloadsigf16
libc.src.math.sinpif16
libc.src.math.totalorderf16
libc.src.math.totalordermagf16
libc.src.math.truncf16
Expand Down
2 changes: 1 addition & 1 deletion libc/docs/math/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ Higher Math Functions
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| sinh | |check| | | | | | 7.12.5.5 | F.10.2.5 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| sinpi | |check| | | | | | 7.12.4.13 | F.10.1.13 |
| sinpi | |check| | | | |check| | | 7.12.4.13 | F.10.1.13 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| sqrt | |check| | |check| | |check| | | |check| | 7.12.7.10 | F.10.4.10 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
Expand Down
33 changes: 15 additions & 18 deletions libc/src/math/generic/sinpif16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,9 @@ LLVM_LIBC_FUNCTION(float16, sinpif16, (float16 x)) {
// * pi/32) and cos(y * pi/32) are computed using degree-9 chebyshev
// polynomials generated by Sollya.

if (LIBC_UNLIKELY(x_abs == 0U)) {
// For signed zeros
// For signed zeros
if (LIBC_UNLIKELY(x_abs == 0U))
return x;
}

// Numbers greater or equal to 2^10 are integers, or infinity, or NaN
if (LIBC_UNLIKELY(x_abs >= 0x6400)) {
Expand All @@ -101,8 +100,6 @@ LLVM_LIBC_FUNCTION(float16, sinpif16, (float16 x)) {
float sin_k = SIN_K_PI_OVER_32[k & 63];
float cos_k = SIN_K_PI_OVER_32[(k + 16) & 63];

float cosm1_y, sin_y;

// Recall;
// sin(x * pi/32) = sin((k + y) * pi/32)
// = sin(y * pi/32) * cos(k * pi/32) + cos(y * pi/32) * sin(k *
Expand All @@ -115,22 +112,22 @@ LLVM_LIBC_FUNCTION(float16, sinpif16, (float16 x)) {
// Degree-6 minimax even polynomial for sin(y*pi/32)/y generated by Sollya
// with:
// > Q = fpminimax(sin(y*pi/32)/y, [|0, 2, 4, 6|], [|SG...|], [0, 0.5]);
sin_y = y * fputil::polyeval(ysq, 0x1.921fb6p-4f, -0x1.4aeabcp-13f,
0x1.a03354p-21f, -0x1.ad02d2p-20f);
float sin_y = y * fputil::polyeval(ysq, 0x1.921fb6p-4f, -0x1.4aeabcp-13f,
0x1.a03354p-21f, -0x1.ad02d2p-20f);

// Note that cosm1_y = cos(y*pi/32) - 1 = cos_y - 1
// Derivation: // sin(x * pi)
// = sin((k + y) * pi/32) // = sin_y *
// cos_k + cos_y * sin_k // = cos_k * sin_y +
// sin_k * (1 + cos_y - 1) Degree-6 minimax even polynomial for cos(y*pi/32)
// generated by Sollya with: > P = fpminimax(cos(y*pi/32), [|0, 2, 4, 6|],
// [|1, SG...|], [0, 0.5]);
cosm1_y = ysq * fputil::polyeval(ysq, -0x1.3bd3ccp-8f, 0x1.03a61ap-18f,
0x1.a6f7a2p-29f);

if (LIBC_UNLIKELY(sin_y == 0 && sin_k == 0)) {
// Derivation:
// sin(x * pi) = sin((k + y) * pi/32)
// = sin_y * cos_k + cos_y * sin_k
// = cos_k * sin_y + sin_k * (1 + cos_y - 1)
// Degree-6 minimax even polynomial for cos(y*pi/32)
// generated by Sollya with:
// > P = fpminimax(cos(y*pi/32), [|0, 2, 4, 6|],[|1, SG...|], [0, 0.5]);
float cosm1_y = ysq * fputil::polyeval(ysq, -0x1.3bd3ccp-8f, 0x1.03a61ap-18f,
0x1.a6f7a2p-29f);

if (LIBC_UNLIKELY(sin_y == 0 && sin_k == 0))
return FPBits::zero(xbits.sign()).get_val();
}

// Since, cosm1_y = cos_y - 1, therefore:
// sin(x * pi) = cos_k * sin_y + sin_k + (cosm1_y * sin_k)
Expand Down
3 changes: 1 addition & 2 deletions libc/test/src/math/sinpif16_test.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//===-- Exhaustive test for sinpif16
//---------------------------------------===//
//===-- Exhaustive test for sinpif16---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
Expand Down
1 change: 1 addition & 0 deletions libc/utils/MPFRWrapper/MPFRUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ class MPFRNumber {
(MPFR_VERSION_MAJOR == 4 && MPFR_VERSION_MINOR >= 2)

mpfr_sinpi(result.value, value, mpfr_rounding);
return result;
#else
if (mpfr_integer_p(value)) {
mpfr_set_si(result.value, 0, mpfr_rounding);
Expand Down