[libc-commits] [libc] [llvm] [libc][math] reduce duplicated inv trig helpers (PR #191364)
via libc-commits
libc-commits at lists.llvm.org
Fri Apr 10 01:50:49 PDT 2026
https://github.com/hulxv updated https://github.com/llvm/llvm-project/pull/191364
>From cfb34014a0656af640f9a07c2c97bc877e765a02 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Fri, 10 Apr 2026 10:38:04 +0200
Subject: [PATCH 1/2] [libc][math] reduce duplicated inv trig helpers
---
libc/src/__support/math/CMakeLists.txt | 23 +-
libc/src/__support/math/acos.h | 10 +-
libc/src/__support/math/acosf.h | 8 +-
libc/src/__support/math/acospif.h | 10 +-
libc/src/__support/math/asin.h | 7 +-
libc/src/__support/math/asin_utils.h | 137 ++++-----
libc/src/__support/math/asinf.h | 8 +-
libc/src/__support/math/asinpi.h | 12 +-
libc/src/__support/math/asinpif.h | 10 +-
libc/src/__support/math/atan2f.h | 4 +-
libc/src/__support/math/atan2f16.h | 6 +-
libc/src/__support/math/atan_utils.h | 137 +++++++++
libc/src/__support/math/atanf.h | 4 +-
libc/src/__support/math/inv_trigf_utils.h | 263 ------------------
.../llvm-project-overlay/libc/BUILD.bazel | 13 -
15 files changed, 261 insertions(+), 391 deletions(-)
delete mode 100644 libc/src/__support/math/inv_trigf_utils.h
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 987ecab8c57ef..64fbffc2e0db9 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -21,7 +21,7 @@ add_header_library(
HDRS
acosf.h
DEPENDS
- .inv_trigf_utils
+ .asin_utils
libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
@@ -101,7 +101,7 @@ add_header_library(
HDRS
acospif.h
DEPENDS
- .inv_trigf_utils
+ .asin_utils
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.polyeval
@@ -211,7 +211,7 @@ add_header_library(
HDRS
asinpif.h
DEPENDS
- .inv_trigf_utils
+ .asin_utils
libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
@@ -267,7 +267,7 @@ add_header_library(
atan2f_float.h
atan2f.h
DEPENDS
- .inv_trigf_utils
+ .atan_utils
libc.src.__support.FPUtil.double_double
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
@@ -283,7 +283,7 @@ add_header_library(
HDRS
atan2f16.h
DEPENDS
- .inv_trigf_utils
+ .atan_utils
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.cast
@@ -329,7 +329,7 @@ add_header_library(
atanf_float.h
atanf.h
DEPENDS
- .inv_trigf_utils
+ .atan_utils
libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
@@ -417,7 +417,7 @@ add_header_library(
HDRS
asinf.h
DEPENDS
- .inv_trigf_utils
+ .asin_utils
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.except_value_utils
@@ -1685,15 +1685,6 @@ add_header_library(
libc.src.__support.macros.config
)
-add_header_library(
- inv_trigf_utils
- HDRS
- inv_trigf_utils.h
- DEPENDS
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.common
-)
add_header_library(
frexpf16
diff --git a/libc/src/__support/math/acos.h b/libc/src/__support/math/acos.h
index 6b419449176fd..cb35f1a24d670 100644
--- a/libc/src/__support/math/acos.h
+++ b/libc/src/__support/math/acos.h
@@ -48,9 +48,10 @@ LIBC_INLINE constexpr double acos(double x) {
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
// acos(x) = pi/2 - asin(x)
- // = pi/2 - x * P(x^2)
- double p = asin_eval(x * x);
- return PI_OVER_TWO.hi + fputil::multiply_add(-x, p, PI_OVER_TWO.lo);
+ // = pi/2 - x * (1 + x^2 * P1(x^2))
+ // = pi/2 - x - x^3 * P1(x^2)
+ double xsq = x * x;
+ return PI_OVER_TWO.hi + fputil::multiply_add(-x * xsq, asinf_eval(xsq), PI_OVER_TWO.lo - x);
#else
unsigned idx = 0;
DoubleDouble x_sq = fputil::exact_mult(x, x);
@@ -177,9 +178,8 @@ LIBC_INLINE constexpr double acos(double x) {
constexpr DoubleDouble CONST_TERM[2] = {{0.0, 0.0}, PI};
DoubleDouble const_term = CONST_TERM[xbits.is_neg()];
- double p = asin_eval(u);
double scale = x_sign * 2.0 * v_hi;
- double r = const_term.hi + fputil::multiply_add(scale, p, const_term.lo);
+ double r = const_term.hi + fputil::multiply_add(scale * u, asinf_eval(u), const_term.lo + scale);
return r;
#else
diff --git a/libc/src/__support/math/acosf.h b/libc/src/__support/math/acosf.h
index ae93abe7e716a..b34e89f62a644 100644
--- a/libc/src/__support/math/acosf.h
+++ b/libc/src/__support/math/acosf.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ACOSF_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSF_H
-#include "inv_trigf_utils.h"
+#include "asin_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/except_value_utils.h"
@@ -48,7 +48,7 @@ LIBC_INLINE_VAR constexpr fputil::ExceptValues<float, N_EXCEPTS> ACOSF_EXCEPTS =
LIBC_INLINE constexpr float acosf(float x) {
using namespace acosf_internal;
- using namespace inv_trigf_utils_internal;
+ using namespace asin_internal;
using FPBits = typename fputil::FPBits<float>;
FPBits xbits(x);
@@ -84,7 +84,7 @@ LIBC_INLINE constexpr float acosf(float x) {
double xd = static_cast<double>(x);
double xsq = xd * xd;
double x3 = xd * xsq;
- double r = asin_eval(xsq);
+ double r = asinf_eval(xsq);
return static_cast<float>(fputil::multiply_add(-x3, r, M_MATH_PI_2 - xd));
}
@@ -136,7 +136,7 @@ LIBC_INLINE constexpr float acosf(float x) {
double u = fputil::multiply_add(-0.5, xd, 0.5);
double cv = 2 * fputil::sqrt<double>(u);
- double r3 = asin_eval(u);
+ double r3 = asinf_eval(u);
double r = fputil::multiply_add(cv * u, r3, cv);
return static_cast<float>(x_sign ? M_MATH_PI - r : r);
}
diff --git a/libc/src/__support/math/acospif.h b/libc/src/__support/math/acospif.h
index acf2b9748975b..a9f6aae5ea4f9 100644
--- a/libc/src/__support/math/acospif.h
+++ b/libc/src/__support/math/acospif.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ACOSPIF_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSPIF_H
-#include "inv_trigf_utils.h"
+#include "asin_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -54,8 +54,8 @@ LIBC_INLINE float acospif(float x) {
double x_d = fputil::cast<double>(x);
double v2 = x_d * x_d;
double result = x_d * fputil::multiply_add(
- v2, inv_trigf_utils_internal::asinpi_eval(v2),
- inv_trigf_utils_internal::ASINPI_COEFFS[0]);
+ v2, asin_internal::asinpif_eval(v2),
+ asin_internal::ASINPIF_COEFFS[0]);
return fputil::cast<float>(0.5 - result);
}
@@ -76,7 +76,7 @@ LIBC_INLINE float acospif(float x) {
constexpr double ONE_OVER_PI_LO = -0x1.6b01ec5417056p-56;
// C0_MINUS_1OVERPI = c0 - 1/pi = DELTA_C0 + ONE_OVER_PI_LO
constexpr double C0_MINUS_1OVERPI =
- (inv_trigf_utils_internal::ASINPI_COEFFS[0] - ONE_OVER_PI_HI) +
+ (asin_internal::ASINPIF_COEFFS[0] - ONE_OVER_PI_HI) +
ONE_OVER_PI_LO;
double u = fputil::multiply_add(-0.5, x_abs, 0.5);
@@ -85,7 +85,7 @@ LIBC_INLINE float acospif(float x) {
// tail = (c0 - 1/pi) + u * P1(u)
double tail = fputil::multiply_add(
- u, inv_trigf_utils_internal::asinpi_eval(u), C0_MINUS_1OVERPI);
+ u, asin_internal::asinpif_eval(u), C0_MINUS_1OVERPI);
double result_hi = fputil::multiply_add(neg2_sqrt_u, ONE_OVER_PI_HI, 0.5);
double result = fputil::multiply_add(tail, neg2_sqrt_u, result_hi);
diff --git a/libc/src/__support/math/asin.h b/libc/src/__support/math/asin.h
index 98e77d0b97454..3117d950ed1ea 100644
--- a/libc/src/__support/math/asin.h
+++ b/libc/src/__support/math/asin.h
@@ -72,7 +72,8 @@ LIBC_INLINE double asin(double x) {
}
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- return x * asin_eval(x * x);
+ double xsq = x * x;
+ return fputil::multiply_add(x * xsq, asinf_eval(xsq), x);
#else
using Float128 = fputil::DyadicFloat<128>;
using DoubleDouble = fputil::DoubleDouble;
@@ -189,8 +190,8 @@ LIBC_INLINE double asin(double x) {
double v_hi = fputil::sqrt<double>(u);
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- double p = asin_eval(u);
- double r = x_sign * fputil::multiply_add(-2.0 * v_hi, p, PI_OVER_TWO.hi);
+ double neg2_v = -2.0 * v_hi;
+ double r = x_sign * fputil::multiply_add(neg2_v * u, asinf_eval(u), PI_OVER_TWO.hi + neg2_v);
return r;
#else
diff --git a/libc/src/__support/math/asin_utils.h b/libc/src/__support/math/asin_utils.h
index 4f64ad5291711..fcad2259e8814 100644
--- a/libc/src/__support/math/asin_utils.h
+++ b/libc/src/__support/math/asin_utils.h
@@ -30,81 +30,96 @@ LIBC_INLINE_VAR constexpr DoubleDouble PI = {0x1.1a62633145c07p-53,
LIBC_INLINE_VAR constexpr DoubleDouble PI_OVER_TWO = {0x1.1a62633145c07p-54,
0x1.921fb54442d18p0};
-#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+// Scalar double constants for pi and pi/2, used by float-precision
+// implementations (acosf etc.).
+LIBC_INLINE_VAR constexpr double M_MATH_PI = 0x1.921fb54442d18p+1;
+LIBC_INLINE_VAR constexpr double M_MATH_PI_2 = 0x1.921fb54442d18p+0;
-// When correct rounding is not needed, we use a degree-22 minimax polynomial to
-// approximate asin(x)/x on [0, 0.5] using Sollya with:
-// > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22|],
+// > Q = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24|],
// [|1, D...|], [0, 0.5]);
-// > dirtyinfnorm(asin(x)/x - P, [0, 0.5]);
-// 0x1.1a71ef0a0f26a9fb7ed7e41dee788b13d1770db3dp-52
-
-LIBC_INLINE_VAR constexpr double ASIN_COEFFS[12] = {
- 0x1.0000000000000p0, 0x1.5555555556dcfp-3, 0x1.3333333082e11p-4,
- 0x1.6db6dd14099edp-5, 0x1.f1c69b35bf81fp-6, 0x1.6e97194225a67p-6,
- 0x1.1babddb82ce12p-6, 0x1.d55bd078600d6p-7, 0x1.33328959e63d6p-7,
- 0x1.2b5993bda1d9bp-6, -0x1.806aff270bf25p-7, 0x1.02614e5ed3936p-5,
+// > dirtyinfnorm((asin(x) - x*Q)/x, [0, 0.5]);
+// 0x1.feb2fcdba66447ccbe28a1a0f935b51678a718fb1p-59
+// Coefficients for float-precision asin (ASINF_COEFFS excludes the leading 1
+// term; used as: asin(x) ~ x + x^3 * asinf_eval(x^2)).
+LIBC_INLINE_VAR constexpr double ASINF_COEFFS[12] = {
+ 0x1.555555555538p-3, 0x1.333333336fd5bp-4, 0x1.6db6db41ce4bcp-5,
+ 0x1.f1c72c66896dep-6, 0x1.6e89f0a0ac64bp-6, 0x1.1c6c111de4074p-6,
+ 0x1.c6fa84b5699acp-7, 0x1.8ed60a3e6dd19p-7, 0x1.ab3a090750049p-8,
+ 0x1.405213cd1ef46p-6, -0x1.0a5a381f73f65p-6, 0x1.05985a32a9045p-5,
};
-LIBC_INLINE double asin_eval(double u) {
- double u2 = u * u;
- double c0 = fputil::multiply_add(u, ASIN_COEFFS[1], ASIN_COEFFS[0]);
- double c1 = fputil::multiply_add(u, ASIN_COEFFS[3], ASIN_COEFFS[2]);
- double c2 = fputil::multiply_add(u, ASIN_COEFFS[5], ASIN_COEFFS[4]);
- double c3 = fputil::multiply_add(u, ASIN_COEFFS[7], ASIN_COEFFS[6]);
- double c4 = fputil::multiply_add(u, ASIN_COEFFS[9], ASIN_COEFFS[8]);
- double c5 = fputil::multiply_add(u, ASIN_COEFFS[11], ASIN_COEFFS[10]);
-
- double u4 = u2 * u2;
- double d0 = fputil::multiply_add(u2, c1, c0);
- double d1 = fputil::multiply_add(u2, c3, c2);
- double d2 = fputil::multiply_add(u2, c5, c4);
-
- return fputil::polyeval(u4, d0, d1, d2);
+// Evaluate P(x^2) - 1, where P(x^2) ~ asin(x)/x, for float-precision asin.
+// Used as: asin(x) ~ x + x^3 * asinf_eval(x^2).
+LIBC_INLINE double asinf_eval(double xsq) {
+ double x4 = xsq * xsq;
+ double c0 = fputil::multiply_add(xsq, ASINF_COEFFS[1], ASINF_COEFFS[0]);
+ double c1 = fputil::multiply_add(xsq, ASINF_COEFFS[3], ASINF_COEFFS[2]);
+ double c2 = fputil::multiply_add(xsq, ASINF_COEFFS[5], ASINF_COEFFS[4]);
+ double c3 = fputil::multiply_add(xsq, ASINF_COEFFS[7], ASINF_COEFFS[6]);
+ double c4 = fputil::multiply_add(xsq, ASINF_COEFFS[9], ASINF_COEFFS[8]);
+ double c5 = fputil::multiply_add(xsq, ASINF_COEFFS[11], ASINF_COEFFS[10]);
+ double x8 = x4 * x4;
+ double d0 = fputil::multiply_add(x4, c1, c0);
+ double d1 = fputil::multiply_add(x4, c3, c2);
+ double d2 = fputil::multiply_add(x4, c5, c4);
+ return fputil::polyeval(x8, d0, d1, d2);
}
-// Coefficients for the polynomial approximation of asin(x)/(pi*x) on [0, 0.5].
-// Generated by Sollya:
+// the coefficients for the polynomial approximation of asin(x)/(pi*x) in the
+// range [0, 0.5] extracted using Sollya, for float-precision asinpi.
+//
+// Sollya code:
// > prec = 200;
+// > display = hexadecimal;
// > g = asin(x) / (pi * x);
// > P = fpminimax(g, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22|],
// > [|D...|], [0, 0.5]);
+// > for i from 0 to degree(P) do coeff(P, i);
// > print("Error:", dirtyinfnorm(P - g, [1e-30; 0.25]));
-// Error : 0x1.a53f84eafa3ea69bb81b6c52b3278872083fca2c757bd778acp-54 ~= 2^-54
-LIBC_INLINE_VAR constexpr double ASINPI_COEFFS[12] = {
- 0x1.45f306dc9c881p-2, // x^0
- 0x1.b2995e7b7e756p-5, // x^2
- 0x1.8723a1d12f828p-6, // x^4
- 0x1.d1a45564b9545p-7, // x^6
- 0x1.3ce4ceaa0e1e9p-7, // x^8
- 0x1.d2c305898ea13p-8, // x^10
- 0x1.692212e27a5f9p-8, // x^12
- 0x1.2b22cc744d25bp-8, // x^14
- 0x1.8427b864479ffp-9, // x^16
- 0x1.815522d7a2bf1p-8, // x^18
- -0x1.f6df98438aef4p-9, // x^20
- 0x1.4b50c2eb13708p-7, // x^22
+// Error : 0x1.6b01ec54170565911f924eb53361de37df00d74e2a10a21d5p-56 ~ 2^−55.496
+//
+// Non-zero coefficients (even powers only):
+LIBC_INLINE_VAR constexpr double ASINPIF_COEFFS[13] = {
+ 0x1.45f306dc9c883p-2, // x^0
+ 0x1.b2995e7b7af0fp-5, // x^2
+ 0x1.8723a1d61d2e9p-6, // x^4
+ 0x1.d1a4529a30a69p-7, // x^6
+ 0x1.3ce53861f8f1fp-7, // x^8
+ 0x1.d2b076c914efep-8, // x^10
+ 0x1.6a2b36f9aed68p-8, // x^12
+ 0x1.21604ae2879a2p-8, // x^14
+ 0x1.ff0549b4fd0d6p-9, // x^16
+ 0x1.035d343508f72p-9, // x^18
+ 0x1.a7b91f72b1592p-8, // x^20
+ -0x1.6a3fb073e97aep-8, // x^22
+ 0x1.547a51d51664ap-7 // x^24
};
-// Evaluate P(u) where P(u) ~ asin(sqrt(u))/(pi*sqrt(u)), using Estrin's scheme.
-LIBC_INLINE double asinpi_eval(double u) {
- double u2 = u * u;
- double c0 = fputil::multiply_add(u, ASINPI_COEFFS[1], ASINPI_COEFFS[0]);
- double c1 = fputil::multiply_add(u, ASINPI_COEFFS[3], ASINPI_COEFFS[2]);
- double c2 = fputil::multiply_add(u, ASINPI_COEFFS[5], ASINPI_COEFFS[4]);
- double c3 = fputil::multiply_add(u, ASINPI_COEFFS[7], ASINPI_COEFFS[6]);
- double c4 = fputil::multiply_add(u, ASINPI_COEFFS[9], ASINPI_COEFFS[8]);
- double c5 = fputil::multiply_add(u, ASINPI_COEFFS[11], ASINPI_COEFFS[10]);
-
- double u4 = u2 * u2;
- double d0 = fputil::multiply_add(u2, c1, c0);
- double d1 = fputil::multiply_add(u2, c3, c2);
- double d2 = fputil::multiply_add(u2, c5, c4);
-
- return fputil::polyeval(u4, d0, d1, d2);
+// Evaluates P1(v2) = c1 + c2*v2 + ... + c12*v2^11 (tail of the asinpif
+// polynomial without c0) using Estrin's scheme.
+// Used as: asinpif(x) ~ x * (ASINPIF_COEFFS[0] + v2 * asinpif_eval(v2))
+// where v2 = x^2.
+LIBC_INLINE double asinpif_eval(double v2) {
+ double v4 = v2 * v2;
+ double v8 = v4 * v4;
+ double v16 = v8 * v8;
+
+ double p0 = fputil::multiply_add(v2, ASINPIF_COEFFS[2], ASINPIF_COEFFS[1]);
+ double p1 = fputil::multiply_add(v2, ASINPIF_COEFFS[4], ASINPIF_COEFFS[3]);
+ double p2 = fputil::multiply_add(v2, ASINPIF_COEFFS[6], ASINPIF_COEFFS[5]);
+ double p3 = fputil::multiply_add(v2, ASINPIF_COEFFS[8], ASINPIF_COEFFS[7]);
+ double p4 = fputil::multiply_add(v2, ASINPIF_COEFFS[10], ASINPIF_COEFFS[9]);
+ double p5 = fputil::multiply_add(v2, ASINPIF_COEFFS[12], ASINPIF_COEFFS[11]);
+
+ double q0 = fputil::multiply_add(v4, p1, p0);
+ double q1 = fputil::multiply_add(v4, p3, p2);
+ double q2 = fputil::multiply_add(v4, p5, p4);
+
+ double r0 = fputil::multiply_add(v8, q1, q0);
+
+ return fputil::multiply_add(v16, q2, r0);
}
-#else
// The Taylor expansion of asin(x) around 0 is:
// asin(x) = x + x^3/6 + 3x^5/40 + ...
@@ -635,8 +650,6 @@ LIBC_INLINE constexpr Float128 asinpi_eval(const Float128 &u, unsigned idx) {
return fputil::quick_mul(p, ONE_OVER_PI_F128);
}
-#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
} // namespace asin_internal
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math/asinf.h b/libc/src/__support/math/asinf.h
index 08cfb192754e4..ceab243581d01 100644
--- a/libc/src/__support/math/asinf.h
+++ b/libc/src/__support/math/asinf.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ASINF_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ASINF_H
-#include "inv_trigf_utils.h"
+#include "asin_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/except_value_utils.h"
@@ -24,7 +24,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
LIBC_INLINE constexpr float asinf(float x) {
- using namespace inv_trigf_utils_internal;
+ using namespace asin_internal;
using FPBits = typename fputil::FPBits<float>;
FPBits xbits(x);
@@ -76,7 +76,7 @@ LIBC_INLINE constexpr float asinf(float x) {
double xd = static_cast<double>(x);
double xsq = xd * xd;
double x3 = xd * xsq;
- double r = asin_eval(xsq);
+ double r = asinf_eval(xsq);
return static_cast<float>(fputil::multiply_add(x3, r, xd));
}
@@ -128,7 +128,7 @@ LIBC_INLINE constexpr float asinf(float x) {
double c2 = fputil::multiply_add(sign_two, M_PI_OVER_4, c1);
double c3 = c1 * u;
- double r = asin_eval(u);
+ double r = asinf_eval(u);
return static_cast<float>(fputil::multiply_add(c3, r, c2));
}
diff --git a/libc/src/__support/math/asinpi.h b/libc/src/__support/math/asinpi.h
index a088ae322ad79..9284dc3e2d6f8 100644
--- a/libc/src/__support/math/asinpi.h
+++ b/libc/src/__support/math/asinpi.h
@@ -43,12 +43,14 @@ LIBC_INLINE double asinpi(double x) {
// The relative error of x/pi is:
// |asinpi(x) - x/pi| / |asinpi(x)| < x^2/6 < 2^-54.
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- return x * ASINPI_COEFFS[0];
+ return x * asin_internal::ASINPIF_COEFFS[0];
#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
}
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- return x * asinpi_eval(x * x);
+ double xsq = x * x;
+ return x * fputil::multiply_add(xsq, asin_internal::asinpif_eval(xsq),
+ asin_internal::ASINPIF_COEFFS[0]);
#else
using Float128 = fputil::DyadicFloat<128>;
using DoubleDouble = fputil::DoubleDouble;
@@ -193,8 +195,10 @@ LIBC_INLINE double asinpi(double x) {
double v_hi = fputil::sqrt<double>(u);
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- double p = asinpi_eval(u);
- double r = x_sign * fputil::multiply_add(-2.0 * v_hi, p, 0.5);
+ double neg2_v = -2.0 * v_hi;
+ double r = x_sign * fputil::multiply_add(
+ neg2_v * u, asin_internal::asinpif_eval(u),
+ 0.5 + neg2_v * asin_internal::ASINPIF_COEFFS[0]);
return r;
#else
using Float128 = fputil::DyadicFloat<128>;
diff --git a/libc/src/__support/math/asinpif.h b/libc/src/__support/math/asinpif.h
index 79d3ebbe63b5b..ad521e025d1fa 100644
--- a/libc/src/__support/math/asinpif.h
+++ b/libc/src/__support/math/asinpif.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ASINPIF_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ASINPIF_H
-#include "inv_trigf_utils.h"
+#include "asin_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -51,8 +51,8 @@ LIBC_INLINE float asinpif(float x) {
double x_d = fputil::cast<double>(x);
double v2 = x_d * x_d;
double result = x_d * fputil::multiply_add(
- v2, inv_trigf_utils_internal::asinpi_eval(v2),
- inv_trigf_utils_internal::ASINPI_COEFFS[0]);
+ v2, asin_internal::asinpif_eval(v2),
+ asin_internal::ASINPIF_COEFFS[0]);
return fputil::cast<float>(result);
}
@@ -74,7 +74,7 @@ LIBC_INLINE float asinpif(float x) {
constexpr double ONE_OVER_PI_LO = -0x1.6b01ec5417056p-56;
// C0_MINUS_1OVERPI = c0 - 1/pi = DELTA_C0 + ONE_OVER_PI_LO
constexpr double C0_MINUS_1OVERPI =
- (inv_trigf_utils_internal::ASINPI_COEFFS[0] - ONE_OVER_PI_HI) +
+ (asin_internal::ASINPIF_COEFFS[0] - ONE_OVER_PI_HI) +
ONE_OVER_PI_LO;
double u = fputil::multiply_add(-0.5, x_abs, 0.5);
@@ -83,7 +83,7 @@ LIBC_INLINE float asinpif(float x) {
// tail = (c0 - 1/pi) + u * P1(u)
double tail = fputil::multiply_add(
- u, inv_trigf_utils_internal::asinpi_eval(u), C0_MINUS_1OVERPI);
+ u, asin_internal::asinpif_eval(u), C0_MINUS_1OVERPI);
double result_hi = fputil::multiply_add(neg2_sqrt_u, ONE_OVER_PI_HI, 0.5);
double result = fputil::multiply_add(tail, neg2_sqrt_u, result_hi);
diff --git a/libc/src/__support/math/atan2f.h b/libc/src/__support/math/atan2f.h
index 15d1fce2b707c..c9314ee28af2d 100644
--- a/libc/src/__support/math/atan2f.h
+++ b/libc/src/__support/math/atan2f.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ATAN2F_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ATAN2F_H
-#include "inv_trigf_utils.h"
+#include "atan_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -241,7 +241,7 @@ LIBC_INLINE float atan2f_double_double(double num_d, double den_d, double q_d,
LIBC_INLINE constexpr float atan2f(float y, float x) {
using namespace atan2f_internal;
- using namespace inv_trigf_utils_internal;
+ using namespace atan_internal;
using FPBits = typename fputil::FPBits<float>;
constexpr double IS_NEG[2] = {1.0, -1.0};
constexpr double PI = 0x1.921fb54442d18p1;
diff --git a/libc/src/__support/math/atan2f16.h b/libc/src/__support/math/atan2f16.h
index 297167a429d9f..0621ab4fd0547 100644
--- a/libc/src/__support/math/atan2f16.h
+++ b/libc/src/__support/math/atan2f16.h
@@ -13,7 +13,7 @@
#ifdef LIBC_TYPES_HAS_FLOAT16
-#include "inv_trigf_utils.h"
+#include "atan_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/cast.h"
@@ -26,7 +26,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
LIBC_INLINE float16 atan2f16(float16 y, float16 x) {
- using namespace inv_trigf_utils_internal;
+ using namespace atan_internal;
using FPBits = fputil::FPBits<float16>;
constexpr double IS_NEG[2] = {1.0, -1.0};
@@ -84,7 +84,7 @@ LIBC_INLINE float16 atan2f16(float16 y, float16 x) {
// atan(n/d) = atan(idx/16) + q_d * Q(q_d)
// where Q(q_d) approximates
// [atan(idx/16 + q_d) - atan(idx/16)] / q_d
- // via atan_eval(q_d, idx) from inv_trigf_utils.
+ // via atan_eval(q_d, idx) from atan_utils.
double n = static_cast<double>(FPBits(min_abs).get_val());
double d = static_cast<double>(FPBits(max_abs).get_val());
double q_d = n / d;
diff --git a/libc/src/__support/math/atan_utils.h b/libc/src/__support/math/atan_utils.h
index e752af3568373..9f6cea97ff3a0 100644
--- a/libc/src/__support/math/atan_utils.h
+++ b/libc/src/__support/math/atan_utils.h
@@ -234,6 +234,143 @@ LIBC_INLINE_VAR constexpr Float128 ATAN_POLY_F128[] = {
return fputil::multiply_add(x3, p, x);
}
+// Polynomial approximation for 0 <= x <= 1:
+// atan(x) ~ atan((i/16) + (x - (i/16)) * Q(x - i/16)
+// = P(x - i/16)
+// Generated by Sollya with:
+// > for i from 1 to 16 do {
+// mid_point = i/16;
+// P = fpminimax(atan(mid_point + x), 8, [|D...|], [-1/32, 1/32]);
+// print("{", coeff(P, 0), ",", coeff(P, 1), ",", coeff(P, 2), ",",
+// coeff(P, 3), ",", coeff(P, 4), ",", coeff(P, 5), ",", coeff(P, 6),
+// ",", coeff(P, 7), ",", coeff(P, 8), "},");
+// };
+// For i = 0, the polynomial is generated by:
+// > P = fpminimax(atan(x)/x, 7, [|1, D...|], [0, 1/32]);
+// > dirtyinfnorm((atan(x) - x*P)/x, [0, 1/32]);
+// 0x1.feb2fcdba66447ccbe28a1a0f935b51678a718fb1p-59
+// Notice that degree-7 is good enough for atanf, but degree-8 helps reduce the
+// error bounds for atan2f's fast pass 16 times, and it does not affect the
+// performance of atanf much.
+LIBC_INLINE_VAR constexpr double ATAN_COEFFS[17][9] = {
+ {0.0, 1.0, 0x1.3f8d76d26d61bp-47, -0x1.5555555574cd8p-2,
+ 0x1.0dde5d06878eap-29, 0x1.99997738acc77p-3, 0x1.2c43eac9797cap-16,
+ -0x1.25fb020007dbdp-3, 0x1.c1b6c31d7b0aep-7},
+ {0x1.ff55bb72cfde9p-5, 0x1.fe01fe01fe007p-1, -0x1.fc05f809ed8dap-5,
+ -0x1.4d69303afe04ep-2, 0x1.f61bc3e8349cp-5, 0x1.820839278756bp-3,
+ -0x1.eda4de1c6bf3fp-5, -0x1.0514d42d64a63p-3, 0x1.db3746a442dcbp-5},
+ {0x1.fd5ba9aac2f6ep-4, 0x1.f81f81f81f813p-1, -0x1.f05e09d0dc378p-4,
+ -0x1.368c3aa719215p-2, 0x1.d9b16b33ff9c9p-4, 0x1.40488f9c6262ap-3,
+ -0x1.ba55933e62ea5p-4, -0x1.64c6a15cd9116p-4, 0x1.9273d5939a75ap-4},
+ {0x1.7b97b4bce5b02p-3, 0x1.ee9c7f8458e05p-1, -0x1.665c226d6961p-3,
+ -0x1.1344bb7391703p-2, 0x1.42aca8b0081b9p-3, 0x1.c32d9381d7c03p-4,
+ -0x1.13e970672e246p-3, -0x1.181ed934dd733p-5, 0x1.bad81ea190c08p-4},
+ {0x1.f5b75f92c80ddp-3, 0x1.e1e1e1e1e1e2cp-1, -0x1.c5894d10d363dp-3,
+ -0x1.ce6de025f9f5ep-3, 0x1.78a3a07c8dd7fp-3, 0x1.dd5f5180f386ep-5,
+ -0x1.1b1f513c4536bp-3, 0x1.0df852e58c43cp-6, 0x1.722e7a7e42505p-4},
+ {0x1.362773707ebccp-2, 0x1.d272ca3fc5b2ep-1, -0x1.0997e8aeca8fbp-2,
+ -0x1.6cf6666e5e693p-3, 0x1.8dd1e907e88adp-3, 0x1.24849ac0caa5dp-7,
+ -0x1.f496be486229dp-4, 0x1.b7d54b8e759ecp-5, 0x1.d39c0d39c3922p-5},
+ {0x1.6f61941e4def1p-2, 0x1.c0e070381c0f2p-1, -0x1.2726dd135d9eep-2,
+ -0x1.09f37b39b70e4p-3, 0x1.85eacdaadd712p-3, -0x1.04d66340d5b9p-5,
+ -0x1.8056b15a22b98p-4, 0x1.29baf494ad3ddp-4, 0x1.52d5881322a7ap-6},
+ {0x1.a64eec3cc23fdp-2, 0x1.adbe87f94906ap-1, -0x1.3b9d8eab55addp-2,
+ -0x1.57c09646eb7p-4, 0x1.6795319e3b8dfp-3, -0x1.f2d89b5ef31bep-5,
+ -0x1.f38aac26203cap-5, 0x1.3262802235e3fp-4, -0x1.2afd6b9a57d66p-7},
+ {0x1.dac670561bb4fp-2, 0x1.99999999999ap-1, -0x1.47ae147adff11p-2,
+ -0x1.5d867c40188b7p-5, 0x1.3a92a2df85e7ap-3, -0x1.3ec457c46e851p-4,
+ -0x1.ec1b9777e2e5bp-6, 0x1.0a542992a821ep-4, -0x1.ccffbe2f0d945p-6},
+ {0x1.0657e94db30dp-1, 0x1.84f00c2780615p-1, -0x1.4c62cb562defap-2,
+ -0x1.e6495b3c14e03p-8, 0x1.063c2fa617bfcp-3, -0x1.58b782d9907aap-4,
+ -0x1.41e6ff524b7fp-8, 0x1.937dfff3205a7p-5, -0x1.0fb1fd1c729dp-5},
+ {0x1.1e00babdefeb4p-1, 0x1.702e05c0b816ep-1, -0x1.4af2b78215fbep-2,
+ 0x1.5d0b7e9f36997p-6, 0x1.a1247cb978debp-4, -0x1.519e1457734cap-4,
+ 0x1.a755cf86b5bfbp-7, 0x1.096d174284564p-5, -0x1.081adf539ad58p-5},
+ {0x1.345f01cce37bbp-1, 0x1.5babcc647fa8ep-1, -0x1.449db09426a6dp-2,
+ 0x1.655caac5896dap-5, 0x1.3bbbd22d05a61p-4, -0x1.34a2febee042fp-4,
+ 0x1.84df9c8269e34p-6, 0x1.200e8176c899ap-6, -0x1.c00b23c3ce222p-6},
+ {0x1.4978fa3269ee1p-1, 0x1.47ae147ae1477p-1, -0x1.3a92a3055231ap-2,
+ 0x1.ec21b515a4a2p-5, 0x1.c2f8b81f9a0d2p-5, -0x1.0ba9964125453p-4,
+ 0x1.d7b5614777a05p-6, 0x1.971e91ed73595p-8, -0x1.3fc375a78dc74p-6},
+ {0x1.5d58987169b18p-1, 0x1.34679ace01343p-1, -0x1.2ddfb039136e5p-2,
+ 0x1.2491307b9fb73p-4, 0x1.29c7e4886dc22p-5, -0x1.bca78bcca83ap-5,
+ 0x1.e63efd7cbe1ddp-6, -0x1.8ea6c4f03b42dp-10, -0x1.9385b5c3a6997p-7},
+ {0x1.700a7c5784634p-1, 0x1.21fb78121fb76p-1, -0x1.1f6a8499e5d1ap-2,
+ 0x1.41b15e5e29423p-4, 0x1.59bc953163345p-6, -0x1.63b54b13184ddp-5,
+ 0x1.c9086666d213p-6, -0x1.90c3b4ad8d4bcp-8, -0x1.80f08ed9f6f57p-8},
+ {0x1.819d0b7158a4dp-1, 0x1.107fbbe01107ep-1, -0x1.0feeb4089670ep-2,
+ 0x1.50e5afb93f5cbp-4, 0x1.2a7c2adffeffbp-7, -0x1.12bd29b4f1b43p-5,
+ 0x1.93f71f0eb00eap-6, -0x1.10ece5ad30e28p-7, -0x1.db1a76bcd2b9cp-10},
+ {0x1.921fb54442d18p-1, 0x1.ffffffffffffep-2, -0x1.fffffffffc51cp-3,
+ 0x1.555555557002ep-4, -0x1.a88260c338e75p-30, -0x1.99999f9a7614fp-6,
+ 0x1.555e31a1e15e9p-6, -0x1.245240d65e629p-7, -0x1.fa9ba66478903p-11},
+};
+
+// Look-up table for atan(k/16) with k = 0..16.
+LIBC_INLINE_VAR constexpr double ATAN_K_OVER_16[17] = {
+ 0.0,
+ 0x1.ff55bb72cfdeap-5,
+ 0x1.fd5ba9aac2f6ep-4,
+ 0x1.7b97b4bce5b02p-3,
+ 0x1.f5b75f92c80ddp-3,
+ 0x1.362773707ebccp-2,
+ 0x1.6f61941e4def1p-2,
+ 0x1.a64eec3cc23fdp-2,
+ 0x1.dac670561bb4fp-2,
+ 0x1.0657e94db30dp-1,
+ 0x1.1e00babdefeb4p-1,
+ 0x1.345f01cce37bbp-1,
+ 0x1.4978fa3269ee1p-1,
+ 0x1.5d58987169b18p-1,
+ 0x1.700a7c5784634p-1,
+ 0x1.819d0b7158a4dp-1,
+ 0x1.921fb54442d18p-1,
+};
+
+// For |x| <= 1/32 and 0 <= i <= 16, return Q(x) such that:
+// Q(x) ~ (atan(x + i/16) - atan(i/16)) / x.
+LIBC_INLINE double atan_eval(double x, unsigned i) {
+ double x2 = x * x;
+
+ double c0 = fputil::multiply_add(x, ATAN_COEFFS[i][2], ATAN_COEFFS[i][1]);
+ double c1 = fputil::multiply_add(x, ATAN_COEFFS[i][4], ATAN_COEFFS[i][3]);
+ double c2 = fputil::multiply_add(x, ATAN_COEFFS[i][6], ATAN_COEFFS[i][5]);
+ double c3 = fputil::multiply_add(x, ATAN_COEFFS[i][8], ATAN_COEFFS[i][7]);
+
+ double x4 = x2 * x2;
+ double d1 = fputil::multiply_add(x2, c1, c0);
+ double d2 = fputil::multiply_add(x2, c3, c2);
+ double p = fputil::multiply_add(x4, d2, d1);
+ return p;
+}
+
+// Evaluate atan without big lookup table.
+// atan(n/d) - atan(k/16) = atan((n/d - k/16) / (1 + (n/d) * (k/16)))
+// = atan((n - d * k/16)) / (d + n * k/16))
+// So we let q = (n - d * k/16) / (d + n * k/16),
+// and approximate with Taylor polynomial:
+// atan(q) ~ q - q^3/3 + q^5/5 - q^7/7 + q^9/9
+LIBC_INLINE double atan_eval_no_table(double num, double den,
+ double k_over_16) {
+ double num_r = fputil::multiply_add(den, -k_over_16, num);
+ double den_r = fputil::multiply_add(num, k_over_16, den);
+ double q = num_r / den_r;
+
+ constexpr double ATAN_TAYLOR[] = {
+ -0x1.5555555555555p-2,
+ 0x1.999999999999ap-3,
+ -0x1.2492492492492p-3,
+ 0x1.c71c71c71c71cp-4,
+ };
+ double q2 = q * q;
+ double q3 = q2 * q;
+ double q4 = q2 * q2;
+ double c0 = fputil::multiply_add(q2, ATAN_TAYLOR[1], ATAN_TAYLOR[0]);
+ double c1 = fputil::multiply_add(q2, ATAN_TAYLOR[3], ATAN_TAYLOR[2]);
+ double d = fputil::multiply_add(q4, c1, c0);
+ return fputil::multiply_add(q3, d, q);
+}
+
} // namespace atan_internal
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math/atanf.h b/libc/src/__support/math/atanf.h
index 633a95b02d5ff..bccfb1f5b412b 100644
--- a/libc/src/__support/math/atanf.h
+++ b/libc/src/__support/math/atanf.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ATANF_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ATANF_H
-#include "inv_trigf_utils.h"
+#include "atan_utils.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
#include "src/__support/FPUtil/except_value_utils.h"
@@ -31,7 +31,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
LIBC_INLINE constexpr float atanf(float x) {
- using namespace inv_trigf_utils_internal;
+ using namespace atan_internal;
using FPBits = typename fputil::FPBits<float>;
constexpr double FINAL_SIGN[2] = {1.0, -1.0};
diff --git a/libc/src/__support/math/inv_trigf_utils.h b/libc/src/__support/math/inv_trigf_utils.h
deleted file mode 100644
index e30eaeb3a3f9a..0000000000000
--- a/libc/src/__support/math/inv_trigf_utils.h
+++ /dev/null
@@ -1,263 +0,0 @@
-//===-- Single-precision general inverse trigonometric functions ----------===//
-//
-// 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___SUPPORT_MATH_INV_TRIGF_UTILS_H
-#define LLVM_LIBC_SRC___SUPPORT_MATH_INV_TRIGF_UTILS_H
-
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-
-namespace LIBC_NAMESPACE_DECL {
-
-namespace inv_trigf_utils_internal {
-
-// PI and PI / 2
-LIBC_INLINE_VAR constexpr double M_MATH_PI = 0x1.921fb54442d18p+1;
-LIBC_INLINE_VAR constexpr double M_MATH_PI_2 = 0x1.921fb54442d18p+0;
-
-// Polynomial approximation for 0 <= x <= 1:
-// atan(x) ~ atan((i/16) + (x - (i/16)) * Q(x - i/16)
-// = P(x - i/16)
-// Generated by Sollya with:
-// > for i from 1 to 16 do {
-// mid_point = i/16;
-// P = fpminimax(atan(mid_point + x), 8, [|D...|], [-1/32, 1/32]);
-// print("{", coeff(P, 0), ",", coeff(P, 1), ",", coeff(P, 2), ",",
-// coeff(P, 3), ",", coeff(P, 4), ",", coeff(P, 5), ",", coeff(P, 6),
-// ",", coeff(P, 7), ",", coeff(P, 8), "},");
-// };
-// For i = 0, the polynomial is generated by:
-// > P = fpminimax(atan(x)/x, 7, [|1, D...|], [0, 1/32]);
-// > dirtyinfnorm((atan(x) - x*P)/x, [0, 1/32]);
-// 0x1.feb2fcdba66447ccbe28a1a0f935b51678a718fb1p-59
-// Notice that degree-7 is good enough for atanf, but degree-8 helps reduce the
-// error bounds for atan2f's fast pass 16 times, and it does not affect the
-// performance of atanf much.
-LIBC_INLINE_VAR constexpr double ATAN_COEFFS[17][9] = {
- {0.0, 1.0, 0x1.3f8d76d26d61bp-47, -0x1.5555555574cd8p-2,
- 0x1.0dde5d06878eap-29, 0x1.99997738acc77p-3, 0x1.2c43eac9797cap-16,
- -0x1.25fb020007dbdp-3, 0x1.c1b6c31d7b0aep-7},
- {0x1.ff55bb72cfde9p-5, 0x1.fe01fe01fe007p-1, -0x1.fc05f809ed8dap-5,
- -0x1.4d69303afe04ep-2, 0x1.f61bc3e8349cp-5, 0x1.820839278756bp-3,
- -0x1.eda4de1c6bf3fp-5, -0x1.0514d42d64a63p-3, 0x1.db3746a442dcbp-5},
- {0x1.fd5ba9aac2f6ep-4, 0x1.f81f81f81f813p-1, -0x1.f05e09d0dc378p-4,
- -0x1.368c3aa719215p-2, 0x1.d9b16b33ff9c9p-4, 0x1.40488f9c6262ap-3,
- -0x1.ba55933e62ea5p-4, -0x1.64c6a15cd9116p-4, 0x1.9273d5939a75ap-4},
- {0x1.7b97b4bce5b02p-3, 0x1.ee9c7f8458e05p-1, -0x1.665c226d6961p-3,
- -0x1.1344bb7391703p-2, 0x1.42aca8b0081b9p-3, 0x1.c32d9381d7c03p-4,
- -0x1.13e970672e246p-3, -0x1.181ed934dd733p-5, 0x1.bad81ea190c08p-4},
- {0x1.f5b75f92c80ddp-3, 0x1.e1e1e1e1e1e2cp-1, -0x1.c5894d10d363dp-3,
- -0x1.ce6de025f9f5ep-3, 0x1.78a3a07c8dd7fp-3, 0x1.dd5f5180f386ep-5,
- -0x1.1b1f513c4536bp-3, 0x1.0df852e58c43cp-6, 0x1.722e7a7e42505p-4},
- {0x1.362773707ebccp-2, 0x1.d272ca3fc5b2ep-1, -0x1.0997e8aeca8fbp-2,
- -0x1.6cf6666e5e693p-3, 0x1.8dd1e907e88adp-3, 0x1.24849ac0caa5dp-7,
- -0x1.f496be486229dp-4, 0x1.b7d54b8e759ecp-5, 0x1.d39c0d39c3922p-5},
- {0x1.6f61941e4def1p-2, 0x1.c0e070381c0f2p-1, -0x1.2726dd135d9eep-2,
- -0x1.09f37b39b70e4p-3, 0x1.85eacdaadd712p-3, -0x1.04d66340d5b9p-5,
- -0x1.8056b15a22b98p-4, 0x1.29baf494ad3ddp-4, 0x1.52d5881322a7ap-6},
- {0x1.a64eec3cc23fdp-2, 0x1.adbe87f94906ap-1, -0x1.3b9d8eab55addp-2,
- -0x1.57c09646eb7p-4, 0x1.6795319e3b8dfp-3, -0x1.f2d89b5ef31bep-5,
- -0x1.f38aac26203cap-5, 0x1.3262802235e3fp-4, -0x1.2afd6b9a57d66p-7},
- {0x1.dac670561bb4fp-2, 0x1.99999999999ap-1, -0x1.47ae147adff11p-2,
- -0x1.5d867c40188b7p-5, 0x1.3a92a2df85e7ap-3, -0x1.3ec457c46e851p-4,
- -0x1.ec1b9777e2e5bp-6, 0x1.0a542992a821ep-4, -0x1.ccffbe2f0d945p-6},
- {0x1.0657e94db30dp-1, 0x1.84f00c2780615p-1, -0x1.4c62cb562defap-2,
- -0x1.e6495b3c14e03p-8, 0x1.063c2fa617bfcp-3, -0x1.58b782d9907aap-4,
- -0x1.41e6ff524b7fp-8, 0x1.937dfff3205a7p-5, -0x1.0fb1fd1c729dp-5},
- {0x1.1e00babdefeb4p-1, 0x1.702e05c0b816ep-1, -0x1.4af2b78215fbep-2,
- 0x1.5d0b7e9f36997p-6, 0x1.a1247cb978debp-4, -0x1.519e1457734cap-4,
- 0x1.a755cf86b5bfbp-7, 0x1.096d174284564p-5, -0x1.081adf539ad58p-5},
- {0x1.345f01cce37bbp-1, 0x1.5babcc647fa8ep-1, -0x1.449db09426a6dp-2,
- 0x1.655caac5896dap-5, 0x1.3bbbd22d05a61p-4, -0x1.34a2febee042fp-4,
- 0x1.84df9c8269e34p-6, 0x1.200e8176c899ap-6, -0x1.c00b23c3ce222p-6},
- {0x1.4978fa3269ee1p-1, 0x1.47ae147ae1477p-1, -0x1.3a92a3055231ap-2,
- 0x1.ec21b515a4a2p-5, 0x1.c2f8b81f9a0d2p-5, -0x1.0ba9964125453p-4,
- 0x1.d7b5614777a05p-6, 0x1.971e91ed73595p-8, -0x1.3fc375a78dc74p-6},
- {0x1.5d58987169b18p-1, 0x1.34679ace01343p-1, -0x1.2ddfb039136e5p-2,
- 0x1.2491307b9fb73p-4, 0x1.29c7e4886dc22p-5, -0x1.bca78bcca83ap-5,
- 0x1.e63efd7cbe1ddp-6, -0x1.8ea6c4f03b42dp-10, -0x1.9385b5c3a6997p-7},
- {0x1.700a7c5784634p-1, 0x1.21fb78121fb76p-1, -0x1.1f6a8499e5d1ap-2,
- 0x1.41b15e5e29423p-4, 0x1.59bc953163345p-6, -0x1.63b54b13184ddp-5,
- 0x1.c9086666d213p-6, -0x1.90c3b4ad8d4bcp-8, -0x1.80f08ed9f6f57p-8},
- {0x1.819d0b7158a4dp-1, 0x1.107fbbe01107ep-1, -0x1.0feeb4089670ep-2,
- 0x1.50e5afb93f5cbp-4, 0x1.2a7c2adffeffbp-7, -0x1.12bd29b4f1b43p-5,
- 0x1.93f71f0eb00eap-6, -0x1.10ece5ad30e28p-7, -0x1.db1a76bcd2b9cp-10},
- {0x1.921fb54442d18p-1, 0x1.ffffffffffffep-2, -0x1.fffffffffc51cp-3,
- 0x1.555555557002ep-4, -0x1.a88260c338e75p-30, -0x1.99999f9a7614fp-6,
- 0x1.555e31a1e15e9p-6, -0x1.245240d65e629p-7, -0x1.fa9ba66478903p-11},
-};
-
-// Look-up table for atan(k/16) with k = 0..16.
-LIBC_INLINE_VAR constexpr double ATAN_K_OVER_16[17] = {
- 0.0,
- 0x1.ff55bb72cfdeap-5,
- 0x1.fd5ba9aac2f6ep-4,
- 0x1.7b97b4bce5b02p-3,
- 0x1.f5b75f92c80ddp-3,
- 0x1.362773707ebccp-2,
- 0x1.6f61941e4def1p-2,
- 0x1.a64eec3cc23fdp-2,
- 0x1.dac670561bb4fp-2,
- 0x1.0657e94db30dp-1,
- 0x1.1e00babdefeb4p-1,
- 0x1.345f01cce37bbp-1,
- 0x1.4978fa3269ee1p-1,
- 0x1.5d58987169b18p-1,
- 0x1.700a7c5784634p-1,
- 0x1.819d0b7158a4dp-1,
- 0x1.921fb54442d18p-1,
-};
-
-// For |x| <= 1/32 and 0 <= i <= 16, return Q(x) such that:
-// Q(x) ~ (atan(x + i/16) - atan(i/16)) / x.
-LIBC_INLINE double atan_eval(double x, unsigned i) {
- double x2 = x * x;
-
- double c0 = fputil::multiply_add(x, ATAN_COEFFS[i][2], ATAN_COEFFS[i][1]);
- double c1 = fputil::multiply_add(x, ATAN_COEFFS[i][4], ATAN_COEFFS[i][3]);
- double c2 = fputil::multiply_add(x, ATAN_COEFFS[i][6], ATAN_COEFFS[i][5]);
- double c3 = fputil::multiply_add(x, ATAN_COEFFS[i][8], ATAN_COEFFS[i][7]);
-
- double x4 = x2 * x2;
- double d1 = fputil::multiply_add(x2, c1, c0);
- double d2 = fputil::multiply_add(x2, c3, c2);
- double p = fputil::multiply_add(x4, d2, d1);
- return p;
-}
-
-// Evaluate atan without big lookup table.
-// atan(n/d) - atan(k/16) = atan((n/d - k/16) / (1 + (n/d) * (k/16)))
-// = atan((n - d * k/16)) / (d + n * k/16))
-// So we let q = (n - d * k/16) / (d + n * k/16),
-// and approximate with Taylor polynomial:
-// atan(q) ~ q - q^3/3 + q^5/5 - q^7/7 + q^9/9
-LIBC_INLINE double atan_eval_no_table(double num, double den,
- double k_over_16) {
- double num_r = fputil::multiply_add(den, -k_over_16, num);
- double den_r = fputil::multiply_add(num, k_over_16, den);
- double q = num_r / den_r;
-
- constexpr double ATAN_TAYLOR[] = {
- -0x1.5555555555555p-2,
- 0x1.999999999999ap-3,
- -0x1.2492492492492p-3,
- 0x1.c71c71c71c71cp-4,
- };
- double q2 = q * q;
- double q3 = q2 * q;
- double q4 = q2 * q2;
- double c0 = fputil::multiply_add(q2, ATAN_TAYLOR[1], ATAN_TAYLOR[0]);
- double c1 = fputil::multiply_add(q2, ATAN_TAYLOR[3], ATAN_TAYLOR[2]);
- double d = fputil::multiply_add(q4, c1, c0);
- return fputil::multiply_add(q3, d, q);
-}
-
-// > Q = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24|],
-// [|1, D...|], [0, 0.5]);
-// > dirtyinfnorm((asin(x) - x*Q)/asin(x), [0, 0.5]);
-// 0x1.1ff...p-56
-LIBC_INLINE_VAR constexpr double ASIN_COEFFS[12] = {
- 0x1.555555555538p-3, 0x1.333333336fd5bp-4, 0x1.6db6db41ce4bcp-5,
- 0x1.f1c72c66896dep-6, 0x1.6e89f0a0ac64bp-6, 0x1.1c6c111de4074p-6,
- 0x1.c6fa84b5699acp-7, 0x1.8ed60a3e6dd19p-7, 0x1.ab3a090750049p-8,
- 0x1.405213cd1ef46p-6, -0x1.0a5a381f73f65p-6, 0x1.05985a32a9045p-5,
-};
-
-// Evaluate P(x^2) - 1, where P(x^2) ~ asin(x)/x
-LIBC_INLINE LIBC_CONSTEXPR double asin_eval(double xsq) {
- double x4 = xsq * xsq;
- double c0 = fputil::multiply_add(xsq, ASIN_COEFFS[1], ASIN_COEFFS[0]);
- double c1 = fputil::multiply_add(xsq, ASIN_COEFFS[3], ASIN_COEFFS[2]);
- double c2 = fputil::multiply_add(xsq, ASIN_COEFFS[5], ASIN_COEFFS[4]);
- double c3 = fputil::multiply_add(xsq, ASIN_COEFFS[7], ASIN_COEFFS[6]);
- double c4 = fputil::multiply_add(xsq, ASIN_COEFFS[9], ASIN_COEFFS[8]);
- double c5 = fputil::multiply_add(xsq, ASIN_COEFFS[11], ASIN_COEFFS[10]);
- double x8 = x4 * x4;
- double d0 = fputil::multiply_add(x4, c1, c0);
- double d1 = fputil::multiply_add(x4, c3, c2);
- double d2 = fputil::multiply_add(x4, c5, c4);
- return fputil::polyeval(x8, d0, d1, d2);
-}
-
-// the coefficients for the polynomial approximation of asin(x)/(pi*x) in the
-// range [0, 0.5] extracted using Sollya.
-//
-// Sollya code:
-// > prec = 200;
-// > display = hexadecimal;
-// > g = asin(x) / (pi * x);
-// > P = fpminimax(g, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22|],
-// > [|D...|], [0, 0.5]);
-// > for i from 0 to degree(P) do coeff(P, i);
-// > print("Error:", dirtyinfnorm(P - g, [1e-30; 0.25]));
-// Error : 0x1.6b01ec54170565911f924eb53361de37df00d74e2a10a21d5p-56 ~ 2^−55.496
-//
-// Non-zero coefficients (even powers only):
-constexpr double ASINPI_COEFFS[13] = {
- 0x1.45f306dc9c883p-2, // x^0
- 0x1.b2995e7b7af0fp-5, // x^2
- 0x1.8723a1d61d2e9p-6, // x^4
- 0x1.d1a4529a30a69p-7, // x^6
- 0x1.3ce53861f8f1fp-7, // x^8
- 0x1.d2b076c914efep-8, // x^10
- 0x1.6a2b36f9aed68p-8, // x^12
- 0x1.21604ae2879a2p-8, // x^14
- 0x1.ff0549b4fd0d6p-9, // x^16
- 0x1.035d343508f72p-9, // x^18
- 0x1.a7b91f72b1592p-8, // x^20
- -0x1.6a3fb073e97aep-8, // x^22
- 0x1.547a51d51664ap-7 // x^24
-};
-
-// Evaluates P1(v2) = c1 + c2*v2 + c3*v2^2 + ... + c12*v2^11 (tail of P
-// without c0) using Estrin's scheme for instruction-level parallelism.
-//
-// The tail polynomial has 12 coefficients (ASINPI_COEFFS[1] through
-// ASINPI_COEFFS[12]) in powers of v2:
-// P1(v2) = c1 + c2*v2 + c3*v2^2 + c4*v2^3 + ... + c12*v2^11
-//
-// Estrin pairs them bottom-up:
-// Level 0 (6 pairs, using v2):
-// p0 = c1 + c2*v2 p1 = c3 + c4*v2
-// p2 = c5 + c6*v2 p3 = c7 + c8*v2
-// p4 = c9 + c10*v2 p5 = c11 + c12*v2
-// Level 1 (3 pairs, using v4):
-// q0 = p0 + p1*v4 q1 = p2 + p3*v4
-// q2 = p4 + p5*v4
-// Level 2 (using v8):
-// r0 = q0 + q1*v8 r1 = q2
-// Level 3 (using v16):
-// result = r0 + r1*v16
-LIBC_INLINE double asinpi_eval(double v2) {
- double v4 = v2 * v2;
- double v8 = v4 * v4;
- double v16 = v8 * v8;
-
- double p0 = fputil::multiply_add(v2, ASINPI_COEFFS[2], ASINPI_COEFFS[1]);
- double p1 = fputil::multiply_add(v2, ASINPI_COEFFS[4], ASINPI_COEFFS[3]);
- double p2 = fputil::multiply_add(v2, ASINPI_COEFFS[6], ASINPI_COEFFS[5]);
- double p3 = fputil::multiply_add(v2, ASINPI_COEFFS[8], ASINPI_COEFFS[7]);
- double p4 = fputil::multiply_add(v2, ASINPI_COEFFS[10], ASINPI_COEFFS[9]);
- double p5 = fputil::multiply_add(v2, ASINPI_COEFFS[12], ASINPI_COEFFS[11]);
-
- double q0 = fputil::multiply_add(v4, p1, p0);
- double q1 = fputil::multiply_add(v4, p3, p2);
- double q2 = fputil::multiply_add(v4, p5, p4);
-
- double r0 = fputil::multiply_add(v8, q1, q0);
-
- return fputil::multiply_add(v16, q2, r0);
-}
-
-} // namespace inv_trigf_utils_internal
-
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC___SUPPORT_MATH_INV_TRIGF_UTILS_H
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 692f4ebbca32b..53f18f387e027 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -3168,7 +3168,6 @@ libc_support_library(
name = "__support_math_asinpi",
hdrs = ["src/__support/math/asinpi.h"],
deps = [
- ":__support_fputil_cast",
":__support_fputil_double_double",
":__support_fputil_dyadic_float",
":__support_fputil_except_value_utils",
@@ -3176,7 +3175,6 @@ libc_support_library(
":__support_fputil_fp_bits",
":__support_fputil_multiply_add",
":__support_fputil_polyeval",
- ":__support_fputil_rounding_mode",
":__support_fputil_sqrt",
":__support_macros_config",
":__support_macros_optimization",
@@ -4731,17 +4729,6 @@ libc_support_library(
],
)
-libc_support_library(
- name = "__support_math_inv_trigf_utils",
- hdrs = ["src/__support/math/inv_trigf_utils.h"],
- deps = [
- ":__support_common",
- ":__support_fputil_multiply_add",
- ":__support_fputil_polyeval",
- ":__support_macros_config",
- ],
-)
-
libc_support_library(
name = "__support_math_frexpf16",
hdrs = ["src/__support/math/frexpf16.h"],
>From 4371faf65a1d5cc62b90317ec1da5cf5695c4a48 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Fri, 10 Apr 2026 10:50:36 +0200
Subject: [PATCH 2/2] fix ci
---
libc/src/__support/math/CMakeLists.txt | 2 +-
libc/src/__support/math/acos.h | 6 ++++--
libc/src/__support/math/acosf.h | 4 ++--
libc/src/__support/math/acospif.h | 13 ++++++-------
libc/src/__support/math/asin.h | 5 +++--
libc/src/__support/math/asin_utils.h | 11 +++++------
libc/src/__support/math/asinbf16.h | 6 +++---
libc/src/__support/math/asinf.h | 4 ++--
libc/src/__support/math/asinpi.h | 6 +++---
libc/src/__support/math/asinpif.h | 13 ++++++-------
utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 2 ++
11 files changed, 37 insertions(+), 35 deletions(-)
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 64fbffc2e0db9..c3539acf69419 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -385,7 +385,7 @@ add_header_library(
HDRS
asinbf16.h
DEPENDS
- .inv_trigf_utils
+ .asin_utils
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.bfloat16
diff --git a/libc/src/__support/math/acos.h b/libc/src/__support/math/acos.h
index cb35f1a24d670..1531d2a1b825a 100644
--- a/libc/src/__support/math/acos.h
+++ b/libc/src/__support/math/acos.h
@@ -51,7 +51,8 @@ LIBC_INLINE constexpr double acos(double x) {
// = pi/2 - x * (1 + x^2 * P1(x^2))
// = pi/2 - x - x^3 * P1(x^2)
double xsq = x * x;
- return PI_OVER_TWO.hi + fputil::multiply_add(-x * xsq, asinf_eval(xsq), PI_OVER_TWO.lo - x);
+ return PI_OVER_TWO.hi +
+ fputil::multiply_add(-x * xsq, asin_eval(xsq), PI_OVER_TWO.lo - x);
#else
unsigned idx = 0;
DoubleDouble x_sq = fputil::exact_mult(x, x);
@@ -179,7 +180,8 @@ LIBC_INLINE constexpr double acos(double x) {
DoubleDouble const_term = CONST_TERM[xbits.is_neg()];
double scale = x_sign * 2.0 * v_hi;
- double r = const_term.hi + fputil::multiply_add(scale * u, asinf_eval(u), const_term.lo + scale);
+ double r = const_term.hi + fputil::multiply_add(scale * u, asin_eval(u),
+ const_term.lo + scale);
return r;
#else
diff --git a/libc/src/__support/math/acosf.h b/libc/src/__support/math/acosf.h
index b34e89f62a644..d1bd43f164cab 100644
--- a/libc/src/__support/math/acosf.h
+++ b/libc/src/__support/math/acosf.h
@@ -84,7 +84,7 @@ LIBC_INLINE constexpr float acosf(float x) {
double xd = static_cast<double>(x);
double xsq = xd * xd;
double x3 = xd * xsq;
- double r = asinf_eval(xsq);
+ double r = asin_eval(xsq);
return static_cast<float>(fputil::multiply_add(-x3, r, M_MATH_PI_2 - xd));
}
@@ -136,7 +136,7 @@ LIBC_INLINE constexpr float acosf(float x) {
double u = fputil::multiply_add(-0.5, xd, 0.5);
double cv = 2 * fputil::sqrt<double>(u);
- double r3 = asinf_eval(u);
+ double r3 = asin_eval(u);
double r = fputil::multiply_add(cv * u, r3, cv);
return static_cast<float>(x_sign ? M_MATH_PI - r : r);
}
diff --git a/libc/src/__support/math/acospif.h b/libc/src/__support/math/acospif.h
index a9f6aae5ea4f9..f193a34f95316 100644
--- a/libc/src/__support/math/acospif.h
+++ b/libc/src/__support/math/acospif.h
@@ -53,9 +53,9 @@ LIBC_INLINE float acospif(float x) {
if (LIBC_UNLIKELY(x_abs <= 0.5)) {
double x_d = fputil::cast<double>(x);
double v2 = x_d * x_d;
- double result = x_d * fputil::multiply_add(
- v2, asin_internal::asinpif_eval(v2),
- asin_internal::ASINPIF_COEFFS[0]);
+ double result =
+ x_d * fputil::multiply_add(v2, asin_internal::asinpi_eval(v2),
+ asin_internal::ASINPIF_COEFFS[0]);
return fputil::cast<float>(0.5 - result);
}
@@ -76,16 +76,15 @@ LIBC_INLINE float acospif(float x) {
constexpr double ONE_OVER_PI_LO = -0x1.6b01ec5417056p-56;
// C0_MINUS_1OVERPI = c0 - 1/pi = DELTA_C0 + ONE_OVER_PI_LO
constexpr double C0_MINUS_1OVERPI =
- (asin_internal::ASINPIF_COEFFS[0] - ONE_OVER_PI_HI) +
- ONE_OVER_PI_LO;
+ (asin_internal::ASINPIF_COEFFS[0] - ONE_OVER_PI_HI) + ONE_OVER_PI_LO;
double u = fputil::multiply_add(-0.5, x_abs, 0.5);
double sqrt_u = fputil::sqrt<double>(u);
double neg2_sqrt_u = -2.0 * sqrt_u;
// tail = (c0 - 1/pi) + u * P1(u)
- double tail = fputil::multiply_add(
- u, asin_internal::asinpif_eval(u), C0_MINUS_1OVERPI);
+ double tail =
+ fputil::multiply_add(u, asin_internal::asinpi_eval(u), C0_MINUS_1OVERPI);
double result_hi = fputil::multiply_add(neg2_sqrt_u, ONE_OVER_PI_HI, 0.5);
double result = fputil::multiply_add(tail, neg2_sqrt_u, result_hi);
diff --git a/libc/src/__support/math/asin.h b/libc/src/__support/math/asin.h
index 3117d950ed1ea..cdf6f217e9ddf 100644
--- a/libc/src/__support/math/asin.h
+++ b/libc/src/__support/math/asin.h
@@ -73,7 +73,7 @@ LIBC_INLINE double asin(double x) {
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
double xsq = x * x;
- return fputil::multiply_add(x * xsq, asinf_eval(xsq), x);
+ return fputil::multiply_add(x * xsq, asin_eval(xsq), x);
#else
using Float128 = fputil::DyadicFloat<128>;
using DoubleDouble = fputil::DoubleDouble;
@@ -191,7 +191,8 @@ LIBC_INLINE double asin(double x) {
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
double neg2_v = -2.0 * v_hi;
- double r = x_sign * fputil::multiply_add(neg2_v * u, asinf_eval(u), PI_OVER_TWO.hi + neg2_v);
+ double r = x_sign * fputil::multiply_add(neg2_v * u, asin_eval(u),
+ PI_OVER_TWO.hi + neg2_v);
return r;
#else
diff --git a/libc/src/__support/math/asin_utils.h b/libc/src/__support/math/asin_utils.h
index fcad2259e8814..a5f14f244fd49 100644
--- a/libc/src/__support/math/asin_utils.h
+++ b/libc/src/__support/math/asin_utils.h
@@ -40,7 +40,7 @@ LIBC_INLINE_VAR constexpr double M_MATH_PI_2 = 0x1.921fb54442d18p+0;
// > dirtyinfnorm((asin(x) - x*Q)/x, [0, 0.5]);
// 0x1.feb2fcdba66447ccbe28a1a0f935b51678a718fb1p-59
// Coefficients for float-precision asin (ASINF_COEFFS excludes the leading 1
-// term; used as: asin(x) ~ x + x^3 * asinf_eval(x^2)).
+// term; used as: asin(x) ~ x + x^3 * asin_eval(x^2)).
LIBC_INLINE_VAR constexpr double ASINF_COEFFS[12] = {
0x1.555555555538p-3, 0x1.333333336fd5bp-4, 0x1.6db6db41ce4bcp-5,
0x1.f1c72c66896dep-6, 0x1.6e89f0a0ac64bp-6, 0x1.1c6c111de4074p-6,
@@ -49,8 +49,8 @@ LIBC_INLINE_VAR constexpr double ASINF_COEFFS[12] = {
};
// Evaluate P(x^2) - 1, where P(x^2) ~ asin(x)/x, for float-precision asin.
-// Used as: asin(x) ~ x + x^3 * asinf_eval(x^2).
-LIBC_INLINE double asinf_eval(double xsq) {
+// Used as: asin(x) ~ x + x^3 * asin_eval(x^2).
+LIBC_INLINE double asin_eval(double xsq) {
double x4 = xsq * xsq;
double c0 = fputil::multiply_add(xsq, ASINF_COEFFS[1], ASINF_COEFFS[0]);
double c1 = fputil::multiply_add(xsq, ASINF_COEFFS[3], ASINF_COEFFS[2]);
@@ -97,9 +97,9 @@ LIBC_INLINE_VAR constexpr double ASINPIF_COEFFS[13] = {
// Evaluates P1(v2) = c1 + c2*v2 + ... + c12*v2^11 (tail of the asinpif
// polynomial without c0) using Estrin's scheme.
-// Used as: asinpif(x) ~ x * (ASINPIF_COEFFS[0] + v2 * asinpif_eval(v2))
+// Used as: asinpif(x) ~ x * (ASINPIF_COEFFS[0] + v2 * asinpi_eval(v2))
// where v2 = x^2.
-LIBC_INLINE double asinpif_eval(double v2) {
+LIBC_INLINE double asinpi_eval(double v2) {
double v4 = v2 * v2;
double v8 = v4 * v4;
double v16 = v8 * v8;
@@ -120,7 +120,6 @@ LIBC_INLINE double asinpif_eval(double v2) {
return fputil::multiply_add(v16, q2, r0);
}
-
// The Taylor expansion of asin(x) around 0 is:
// asin(x) = x + x^3/6 + 3x^5/40 + ...
// ~ x * P(x^2).
diff --git a/libc/src/__support/math/asinbf16.h b/libc/src/__support/math/asinbf16.h
index b291852762d73..f74d7994efd33 100644
--- a/libc/src/__support/math/asinbf16.h
+++ b/libc/src/__support/math/asinbf16.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ASINBF16_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ASINBF16_H
-#include "inv_trigf_utils.h"
+#include "asin_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/bfloat16.h"
@@ -53,7 +53,7 @@ LIBC_INLINE LIBC_CONSTEXPR bfloat16 asinbf16(bfloat16 x) {
return x;
}
- float xp = fputil::cast<float>(inv_trigf_utils_internal::asin_eval(x_sq));
+ float xp = fputil::cast<float>(asin_internal::asin_eval(x_sq));
float result = xf * (fputil::multiply_add<float>(x_sq, xp, 1.0f));
return fputil::cast<bfloat16>(result);
}
@@ -68,7 +68,7 @@ LIBC_INLINE LIBC_CONSTEXPR bfloat16 asinbf16(bfloat16 x) {
float t = fputil::multiply_add<float>(xf_abs, -0.5f, 0.5f);
float t_sqrt = fputil::sqrt<float>(t);
- float tp = fputil::cast<float>(inv_trigf_utils_internal::asin_eval(t));
+ float tp = fputil::cast<float>(asin_internal::asin_eval(t));
float asin_sqrt_t = t_sqrt * (fputil::multiply_add<float>(t, tp, 1.0f));
float result = fputil::multiply_add<float>(-2.0f, asin_sqrt_t, PI_2);
return fputil::cast<bfloat16>(x_sign * result);
diff --git a/libc/src/__support/math/asinf.h b/libc/src/__support/math/asinf.h
index ceab243581d01..f013ac462a5e7 100644
--- a/libc/src/__support/math/asinf.h
+++ b/libc/src/__support/math/asinf.h
@@ -76,7 +76,7 @@ LIBC_INLINE constexpr float asinf(float x) {
double xd = static_cast<double>(x);
double xsq = xd * xd;
double x3 = xd * xsq;
- double r = asinf_eval(xsq);
+ double r = asin_eval(xsq);
return static_cast<float>(fputil::multiply_add(x3, r, xd));
}
@@ -128,7 +128,7 @@ LIBC_INLINE constexpr float asinf(float x) {
double c2 = fputil::multiply_add(sign_two, M_PI_OVER_4, c1);
double c3 = c1 * u;
- double r = asinf_eval(u);
+ double r = asin_eval(u);
return static_cast<float>(fputil::multiply_add(c3, r, c2));
}
diff --git a/libc/src/__support/math/asinpi.h b/libc/src/__support/math/asinpi.h
index 9284dc3e2d6f8..7c57dce3e189e 100644
--- a/libc/src/__support/math/asinpi.h
+++ b/libc/src/__support/math/asinpi.h
@@ -49,7 +49,7 @@ LIBC_INLINE double asinpi(double x) {
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
double xsq = x * x;
- return x * fputil::multiply_add(xsq, asin_internal::asinpif_eval(xsq),
+ return x * fputil::multiply_add(xsq, asin_internal::asinpi_eval(xsq),
asin_internal::ASINPIF_COEFFS[0]);
#else
using Float128 = fputil::DyadicFloat<128>;
@@ -197,8 +197,8 @@ LIBC_INLINE double asinpi(double x) {
#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
double neg2_v = -2.0 * v_hi;
double r = x_sign * fputil::multiply_add(
- neg2_v * u, asin_internal::asinpif_eval(u),
- 0.5 + neg2_v * asin_internal::ASINPIF_COEFFS[0]);
+ neg2_v * u, asin_internal::asinpi_eval(u),
+ 0.5 + neg2_v * asin_internal::ASINPIF_COEFFS[0]);
return r;
#else
using Float128 = fputil::DyadicFloat<128>;
diff --git a/libc/src/__support/math/asinpif.h b/libc/src/__support/math/asinpif.h
index ad521e025d1fa..0a823c2bce627 100644
--- a/libc/src/__support/math/asinpif.h
+++ b/libc/src/__support/math/asinpif.h
@@ -50,9 +50,9 @@ LIBC_INLINE float asinpif(float x) {
if (LIBC_UNLIKELY(x_abs <= 0.5)) {
double x_d = fputil::cast<double>(x);
double v2 = x_d * x_d;
- double result = x_d * fputil::multiply_add(
- v2, asin_internal::asinpif_eval(v2),
- asin_internal::ASINPIF_COEFFS[0]);
+ double result =
+ x_d * fputil::multiply_add(v2, asin_internal::asinpi_eval(v2),
+ asin_internal::ASINPIF_COEFFS[0]);
return fputil::cast<float>(result);
}
@@ -74,16 +74,15 @@ LIBC_INLINE float asinpif(float x) {
constexpr double ONE_OVER_PI_LO = -0x1.6b01ec5417056p-56;
// C0_MINUS_1OVERPI = c0 - 1/pi = DELTA_C0 + ONE_OVER_PI_LO
constexpr double C0_MINUS_1OVERPI =
- (asin_internal::ASINPIF_COEFFS[0] - ONE_OVER_PI_HI) +
- ONE_OVER_PI_LO;
+ (asin_internal::ASINPIF_COEFFS[0] - ONE_OVER_PI_HI) + ONE_OVER_PI_LO;
double u = fputil::multiply_add(-0.5, x_abs, 0.5);
double sqrt_u = fputil::sqrt<double>(u);
double neg2_sqrt_u = -2.0 * sqrt_u;
// tail = (c0 - 1/pi) + u * P1(u)
- double tail = fputil::multiply_add(
- u, asin_internal::asinpif_eval(u), C0_MINUS_1OVERPI);
+ double tail =
+ fputil::multiply_add(u, asin_internal::asinpi_eval(u), C0_MINUS_1OVERPI);
double result_hi = fputil::multiply_add(neg2_sqrt_u, ONE_OVER_PI_HI, 0.5);
double result = fputil::multiply_add(tail, neg2_sqrt_u, result_hi);
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 53f18f387e027..a8ee2148ed721 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -3168,6 +3168,7 @@ libc_support_library(
name = "__support_math_asinpi",
hdrs = ["src/__support/math/asinpi.h"],
deps = [
+ ":__support_fputil_cast",
":__support_fputil_double_double",
":__support_fputil_dyadic_float",
":__support_fputil_except_value_utils",
@@ -3175,6 +3176,7 @@ libc_support_library(
":__support_fputil_fp_bits",
":__support_fputil_multiply_add",
":__support_fputil_polyeval",
+ ":__support_fputil_rounding_mode",
":__support_fputil_sqrt",
":__support_macros_config",
":__support_macros_optimization",
More information about the libc-commits
mailing list