[libc-commits] [libc] [llvm] [libc][math] Fix code size issues with sinf and cosf. (PR #232843)
via libc-commits
libc-commits at lists.llvm.org
Fri Oct 16 09:55:47 PDT 2026
https://github.com/lntue created https://github.com/llvm/llvm-project/pull/232843
- Add missing "optimization.h" includes from sinf, cosf and sinf_test.
- Move function-local arrays out to namespace.
>From 93836771310a45d97b675f4d154f089eacac63a4 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Fri, 16 Oct 2026 16:51:03 +0000
Subject: [PATCH] [libc][math] Fix code size issues with sinf and cosf.
- Add missing "optimization.h" includes from sinf, cosf and sinf_test.
- Move function-local arrays out to namespace.
---
libc/src/__support/math/CMakeLists.txt | 2 +
libc/src/__support/math/cosf.h | 1 +
libc/src/__support/math/sincosf_float_eval.h | 83 ++++++++++---------
libc/src/__support/math/sinf.h | 1 +
libc/test/src/math/CMakeLists.txt | 2 +
libc/test/src/math/sinf_test.cpp | 1 +
.../llvm-project-overlay/libc/BUILD.bazel | 1 +
7 files changed, 50 insertions(+), 41 deletions(-)
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index b3a113f30b3d31..baac96e76d5435 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -2863,6 +2863,7 @@ add_header_library(
.cosf_double_eval
.cosf_float_eval
libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
libc.src.__support.macros.properties.cpu_features
)
@@ -5663,6 +5664,7 @@ add_header_library(
.sinf_double_eval
.sinf_float_eval
libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
libc.src.__support.macros.properties.cpu_features
)
diff --git a/libc/src/__support/math/cosf.h b/libc/src/__support/math/cosf.h
index 5788ee2ec86fa5..592ddbc0e4ed38 100644
--- a/libc/src/__support/math/cosf.h
+++ b/libc/src/__support/math/cosf.h
@@ -15,6 +15,7 @@
#define LLVM_LIBC_SRC___SUPPORT_MATH_COSF_H
#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/cpu_features.h"
#if defined(LIBC_MATH_HAS_SKIP_ACCURATE_PASS) && \
diff --git a/libc/src/__support/math/sincosf_float_eval.h b/libc/src/__support/math/sincosf_float_eval.h
index 195ce373c0f074..d834f3d7cf23f1 100644
--- a/libc/src/__support/math/sincosf_float_eval.h
+++ b/libc/src/__support/math/sincosf_float_eval.h
@@ -14,6 +14,7 @@
#include "src/__support/FPUtil/double_double.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
@@ -22,6 +23,45 @@ namespace math {
namespace sincosf_float_eval {
+// > for i from 0 to 13 do {
+// if i < 2 then { pi_inv = 0.25 + 2^(8*(i - 2)) / pi; }
+// else { pi_inv = 2^(8*(i-2)) / pi; };
+// pn = nearestint(pi_inv);
+// pi_frac = pi_inv - pn;
+// a = round(pi_frac, SG, RN);
+// b = round(pi_frac - a, SG, RN);
+// c = round(pi_frac - a - b, SG, RN);
+// d = round(pi_frac - a - b - c, SG, RN);
+// print("{", 2^3 * a, ",", 2^3 * b, ",", 2^3 * c, ",", 2^3 * d, "},");
+// };
+LIBC_INLINE_VAR constexpr float EIGHT_OVER_PI[14][4] = {
+ {0x1.000146p1f, -0x1.9f246cp-28f, -0x1.bbead6p-54f, -0x1.ec5418p-85f},
+ {0x1.0145f4p1f, -0x1.f246c6p-24f, -0x1.df56bp-49f, -0x1.ec5418p-77f},
+ {0x1.45f306p1f, 0x1.b9391p-24f, 0x1.529fc2p-50f, 0x1.d5f47ep-76f},
+ {0x1.f306dcp1f, 0x1.391054p-24f, 0x1.4fe13ap-49f, 0x1.7d1f54p-74f},
+ {-0x1.f246c6p0f, -0x1.df56bp-25f, -0x1.ec5418p-53f, 0x1.f534dep-78f},
+ {-0x1.236378p1f, 0x1.529fc2p-26f, 0x1.d5f47ep-52f, -0x1.65912p-77f},
+ {0x1.391054p0f, 0x1.4fe13ap-25f, 0x1.7d1f54p-50f, -0x1.6447e4p-75f},
+ {0x1.1054a8p0f, -0x1.ec5418p-29f, 0x1.f534dep-54f, -0x1.f924ecp-81f},
+ {0x1.529fc2p-2f, 0x1.d5f47ep-28f, -0x1.65912p-53f, 0x1.b6c52cp-79f},
+ {-0x1.ac07b2p1f, 0x1.5f47d4p-24f, 0x1.a6ee06p-49f, 0x1.b6295ap-74f},
+ {-0x1.ec5418p-5f, 0x1.f534dep-30f, -0x1.f924ecp-57f, 0x1.5993c4p-82f},
+ {0x1.3abe9p-1f, -0x1.596448p-27f, 0x1.b6c52cp-55f, -0x1.9b0ef2p-80f},
+ {-0x1.505c16p1f, 0x1.a6ee06p-25f, 0x1.b6295ap-50f, -0x1.b0ef1cp-76f},
+ {-0x1.70565ap-1f, 0x1.dc0db6p-26f, 0x1.4acc9ep-53f, 0x1.0e4108p-80f},
+};
+
+// sin(k * pi/8) for k = 0..15, generated by Sollya with:
+// > for k from 0 to 16 do {
+// print(round(sin(k * pi/8), SG, RN));
+// };
+LIBC_INLINE_VAR constexpr float SIN_K_PI_OVER_8[16] = {
+ 0.0f, 0x1.87de2ap-2f, 0x1.6a09e6p-1f, 0x1.d906bcp-1f,
+ 1.0f, 0x1.d906bcp-1f, 0x1.6a09e6p-1f, 0x1.87de2ap-2f,
+ 0.0f, -0x1.87de2ap-2f, -0x1.6a09e6p-1f, -0x1.d906bcp-1f,
+ -1.0f, -0x1.d906bcp-1f, -0x1.6a09e6p-1f, -0x1.87de2ap-2f,
+};
+
// Since the worst case of `x mod pi` in single precision is > 2^-28, in order
// to be bounded by 1 ULP, the range reduction accuracy will need to be at
// least 2^(-28 - 23) = 2^-51.
@@ -60,34 +100,6 @@ LIBC_INLINE unsigned sincosf_range_reduction_small(float x, float &u) {
// TODO: Add non-FMA version of large range reduction.
LIBC_INLINE unsigned sincosf_range_reduction_large(float x, float &u) {
- // > for i from 0 to 13 do {
- // if i < 2 then { pi_inv = 0.25 + 2^(8*(i - 2)) / pi; }
- // else { pi_inv = 2^(8*(i-2)) / pi; };
- // pn = nearestint(pi_inv);
- // pi_frac = pi_inv - pn;
- // a = round(pi_frac, SG, RN);
- // b = round(pi_frac - a, SG, RN);
- // c = round(pi_frac - a - b, SG, RN);
- // d = round(pi_frac - a - b - c, SG, RN);
- // print("{", 2^3 * a, ",", 2^3 * b, ",", 2^3 * c, ",", 2^3 * d, "},");
- // };
- constexpr float EIGHT_OVER_PI[14][4] = {
- {0x1.000146p1f, -0x1.9f246cp-28f, -0x1.bbead6p-54f, -0x1.ec5418p-85f},
- {0x1.0145f4p1f, -0x1.f246c6p-24f, -0x1.df56bp-49f, -0x1.ec5418p-77f},
- {0x1.45f306p1f, 0x1.b9391p-24f, 0x1.529fc2p-50f, 0x1.d5f47ep-76f},
- {0x1.f306dcp1f, 0x1.391054p-24f, 0x1.4fe13ap-49f, 0x1.7d1f54p-74f},
- {-0x1.f246c6p0f, -0x1.df56bp-25f, -0x1.ec5418p-53f, 0x1.f534dep-78f},
- {-0x1.236378p1f, 0x1.529fc2p-26f, 0x1.d5f47ep-52f, -0x1.65912p-77f},
- {0x1.391054p0f, 0x1.4fe13ap-25f, 0x1.7d1f54p-50f, -0x1.6447e4p-75f},
- {0x1.1054a8p0f, -0x1.ec5418p-29f, 0x1.f534dep-54f, -0x1.f924ecp-81f},
- {0x1.529fc2p-2f, 0x1.d5f47ep-28f, -0x1.65912p-53f, 0x1.b6c52cp-79f},
- {-0x1.ac07b2p1f, 0x1.5f47d4p-24f, 0x1.a6ee06p-49f, 0x1.b6295ap-74f},
- {-0x1.ec5418p-5f, 0x1.f534dep-30f, -0x1.f924ecp-57f, 0x1.5993c4p-82f},
- {0x1.3abe9p-1f, -0x1.596448p-27f, 0x1.b6c52cp-55f, -0x1.9b0ef2p-80f},
- {-0x1.505c16p1f, 0x1.a6ee06p-25f, 0x1.b6295ap-50f, -0x1.b0ef1cp-76f},
- {-0x1.70565ap-1f, 0x1.dc0db6p-26f, 0x1.4acc9ep-53f, 0x1.0e4108p-80f},
- };
-
using FPBits = typename fputil::FPBits<float>;
using fputil::FloatFloat;
FPBits xbits(x);
@@ -134,17 +146,6 @@ LIBC_INLINE unsigned sincosf_range_reduction_large(float x, float &u) {
}
template <bool IS_SIN> LIBC_INLINE float sincosf_eval(float x) {
- // sin(k * pi/8) for k = 0..15, generated by Sollya with:
- // > for k from 0 to 16 do {
- // print(round(sin(k * pi/8), SG, RN));
- // };
- constexpr float SIN_K_PI_OVER_8[16] = {
- 0.0f, 0x1.87de2ap-2f, 0x1.6a09e6p-1f, 0x1.d906bcp-1f,
- 1.0f, 0x1.d906bcp-1f, 0x1.6a09e6p-1f, 0x1.87de2ap-2f,
- 0.0f, -0x1.87de2ap-2f, -0x1.6a09e6p-1f, -0x1.d906bcp-1f,
- -1.0f, -0x1.d906bcp-1f, -0x1.6a09e6p-1f, -0x1.87de2ap-2f,
- };
-
using FPBits = fputil::FPBits<float>;
FPBits xbits(x);
uint32_t x_abs = cpp::bit_cast<uint32_t>(x) & 0x7fff'ffffU;
@@ -206,8 +207,8 @@ template <bool IS_SIN> LIBC_INLINE float sincosf_eval(float x) {
float s1 = fputil::multiply_add(y3, p1, y);
if constexpr (IS_SIN) {
- // sin(x) = cos(k * pi/8) * sin(y) + sin(k * pi/8) * cos(y).
- return fputil::multiply_add(cos_k, s1, sin_k * c1);
+ // sin(x) = sin(k * pi/8) * cos(y) + cos(k * pi/8) * sin(y).
+ return fputil::multiply_add(sin_k, c1, cos_k * s1);
} else {
// cos(x) = cos(k * pi/8) * cos(y) - sin(k * pi/8) * sin(y).
return fputil::multiply_add(cos_k, c1, -sin_k * s1);
diff --git a/libc/src/__support/math/sinf.h b/libc/src/__support/math/sinf.h
index 5e3aa24a42ca62..9a6f78e6a6d357 100644
--- a/libc/src/__support/math/sinf.h
+++ b/libc/src/__support/math/sinf.h
@@ -15,6 +15,7 @@
#define LLVM_LIBC_SRC___SUPPORT_MATH_SINF_H
#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/cpu_features.h"
#if defined(LIBC_MATH_HAS_SKIP_ACCURATE_PASS) && \
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index eb06075edbd8e3..921dbf220eb372 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -14,6 +14,7 @@ add_fp_unittest(
libc.src.math.cosf
libc.src.__support.math.cosf_double_eval
libc.src.__support.math.cosf_float_eval
+ libc.src.__support.macros.optimization
libc.src.__support.macros.properties.cpu_features
libc.src.__support.CPP.array
libc.src.__support.FPUtil.fp_bits
@@ -96,6 +97,7 @@ add_fp_unittest(
libc.src.math.sinf
libc.src.__support.math.sinf_double_eval
libc.src.__support.math.sinf_float_eval
+ libc.src.__support.macros.optimization
libc.src.__support.macros.properties.cpu_features
libc.src.__support.CPP.array
libc.src.__support.FPUtil.fp_bits
diff --git a/libc/test/src/math/sinf_test.cpp b/libc/test/src/math/sinf_test.cpp
index 00be6b9c8de658..f434eb3def4ada 100644
--- a/libc/test/src/math/sinf_test.cpp
+++ b/libc/test/src/math/sinf_test.cpp
@@ -10,6 +10,7 @@
#include "hdr/math_macros.h"
#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/cpu_features.h"
#include "src/__support/math/sinf_double_eval.h"
#include "src/__support/math/sinf_float_eval.h"
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 0152de660c50de..c681d8a2f9a3b5 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -11158,6 +11158,7 @@ libc_support_library(
":__support_fputil_multiply_add",
":__support_fputil_nearest_integer",
":__support_fputil_polyeval",
+ ":__support_macros_attributes",
":__support_macros_config",
":__support_macros_properties_cpu_features",
":__support_range_reduction",
More information about the libc-commits
mailing list