[libc-commits] [libc] [libc][mathvec] Vectorise sinf (PR #220985)

via libc-commits libc-commits at lists.llvm.org
Thu Sep 3 10:07:02 PDT 2026


https://github.com/DylanFleming-arm updated https://github.com/llvm/llvm-project/pull/220985

>From db1508c8a3227b308e286c5a6a3ed67b89b012f7 Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Thu, 3 Sep 2026 16:08:04 +0000
Subject: [PATCH 1/3] [libc][mathvec] Vectorise sinf

Replaces loop over scalar sinf with a fully vectorised implementation.
---
 libc/src/__support/mathvec/CMakeLists.txt     |  15 +-
 libc/src/__support/mathvec/sinf.h             |  80 ++++++++-
 libc/src/__support/mathvec/trig_reductionf.h  | 129 ++++++++++++++
 .../__support/mathvec/trig_reductionf_nofma.h | 168 ++++++++++++++++++
 libc/src/mathvec/generic/sinf.cpp             |   2 +-
 5 files changed, 386 insertions(+), 8 deletions(-)
 create mode 100644 libc/src/__support/mathvec/trig_reductionf.h
 create mode 100644 libc/src/__support/mathvec/trig_reductionf_nofma.h

diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
index 6e5f3bbddc1be..431ad79f10501 100644
--- a/libc/src/__support/mathvec/CMakeLists.txt
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -232,13 +232,26 @@ add_header_library(
     libc.src.__support.math.rsqrtf
 )
 
+add_header_library(
+  trig_reductionf
+  HDRS
+    trig_reductionf.h
+    trig_reductionf_nofma.h
+  DEPENDS
+    libc.src.__support.CPP.bit
+    libc.src.__support.CPP.simd
+)
+
 add_header_library(
   sinf
   HDRS
     sinf.h
   DEPENDS
+    .trig_reductionf
+    libc.src.__support.CPP.bit
     libc.src.__support.CPP.simd
-    libc.src.__support.math.sinf
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.macros.properties.cpu_features
 )
 
 add_header_library(
diff --git a/libc/src/__support/mathvec/sinf.h b/libc/src/__support/mathvec/sinf.h
index 7b2c15f8a7265..fc6e134dc0671 100644
--- a/libc/src/__support/mathvec/sinf.h
+++ b/libc/src/__support/mathvec/sinf.h
@@ -14,21 +14,89 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_MATHVEC_SINF_H
 #define LLVM_LIBC_SRC___SUPPORT_MATHVEC_SINF_H
 
+#include "src/__support/CPP/bit.h"
 #include "src/__support/CPP/simd.h"
-#define LIBC_MATH_HAS_NO_ERRNO
-#define LIBC_MATH_HAS_NO_EXCEPT
-#define LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
-#include "src/__support/math/sinf.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/properties/cpu_features.h"
+
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+#include "src/__support/mathvec/trig_reductionf.h"
+#else
+#include "src/__support/mathvec/trig_reductionf_nofma.h"
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
 
 namespace LIBC_NAMESPACE_DECL {
 
 namespace mathvec {
 
 template <size_t N>
-LIBC_INLINE cpp::simd<float, N> sinf(cpp::simd<float, N> x) {
-  return cpp::map(x, [](float a) { return math::sinf(a); });
+LIBC_INLINE cpp::simd<double, N> sinpif_poly(cpp::simd<double, N> r) {
+  // Approximate sin(pi * r) for |r| <= 0.5.
+  // These coefficients aren't produced directly via sollya, but rather
+  // are fine-tuned by iterative adjustment to remove hard to round cases.
+  // TODO: Create a tool to deterministically reproduce these coefficients.
+  // see https://github.com/llvm/llvm-project/issues/220984
+  constexpr cpp::simd<double, N> c0 = 0x1.921fb54442d15p1;
+  constexpr cpp::simd<double, N> c1 = -0x1.4abbce625bcbdp2;
+  constexpr cpp::simd<double, N> c2 = 0x1.466bc67749fe8p1;
+  constexpr cpp::simd<double, N> c3 = -0x1.32d2ccde52aaap-1;
+  constexpr cpp::simd<double, N> c4 = 0x1.5078311af79bdp-4;
+  constexpr cpp::simd<double, N> c5 = -0x1.e305b6b7642fbp-8;
+  constexpr cpp::simd<double, N> c6 = 0x1.e889fb0d0db0dp-12;
+  constexpr cpp::simd<double, N> c7 = -0x1.611a523a97eb1p-16;
+
+  cpp::simd<double, N> r2 = r * r;
+  cpp::simd<double, N> r4 = r2 * r2;
+  cpp::simd<double, N> p01 = cpp::multiply_add(r2, c1, c0);
+  cpp::simd<double, N> p23 = cpp::multiply_add(r2, c3, c2);
+  cpp::simd<double, N> p45 = cpp::multiply_add(r2, c5, c4);
+  cpp::simd<double, N> p67 = cpp::multiply_add(r2, c7, c6);
+  cpp::simd<double, N> p47 = cpp::multiply_add(r4, p67, p45);
+  cpp::simd<double, N> p27 = cpp::multiply_add(r4, p47, p23);
+  cpp::simd<double, N> p07 = cpp::multiply_add(r4, p27, p01);
+  return r * p07;
 }
 
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> sinf(cpp::simd<float, N> x) {
+  using FPBits = typename fputil::FPBits<float>;
+
+  cpp::simd<float, N> ax = cpp::abs(x);
+  cpp::simd<uint32_t, N> x_sign = cpp::bit_cast<cpp::simd<uint32_t>>(x) ^
+                                  cpp::bit_cast<cpp::simd<uint32_t>>(ax);
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+  constexpr float large_reduction_bound = 0x1.6d28ce103p+52f;
+#else
+  constexpr float large_reduction_bound = 0x1.0p+51f;
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+  cpp::simd<bool, N> has_large_reduction = (ax > large_reduction_bound);
+
+  cpp::simd<double, N> x_d = cpp::simd_cast<double>(ax);
+  Reduction<N> reduce{};
+
+  // Values at or below the large bound can use a fast Cody-Waite reduction.
+  if (LIBC_LIKELY(!cpp::all_of(has_large_reduction)))
+    reduce = fast_reduction(x_d);
+
+  // Large inputs require a more involved reduction, as well as inf handling.
+  if (LIBC_UNLIKELY(cpp::any_of(has_large_reduction))) {
+    cpp::simd<bool, N> is_finite = ax < FPBits::inf().get_val();
+    Reduction<N> large_reduce = large_reduction(x_d);
+    reduce.r = has_large_reduction ? large_reduce.r : reduce.r;
+    reduce.odd = has_large_reduction ? large_reduce.odd : reduce.odd;
+    reduce.r = is_finite ? reduce.r : FPBits::quiet_nan().get_val();
+  }
+
+  // Both reduction paths feed into a single polynomial evaluation + sign
+  // correction.
+  cpp::simd<float, N> poly = cpp::simd_cast<float>(sinpif_poly(reduce.r));
+  cpp::simd<uint32_t, N> sign = cpp::simd_cast<uint32_t>(reduce.odd) << 31;
+
+  // XORing the sign correction with the input sign preserves -0.
+  sign ^= x_sign;
+  return cpp::bit_cast<cpp::simd<float>>(
+      cpp::bit_cast<cpp::simd<uint32_t>>(poly) ^ sign);
+}
 } // namespace mathvec
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/mathvec/trig_reductionf.h b/libc/src/__support/mathvec/trig_reductionf.h
new file mode 100644
index 0000000000000..0b9f3a29e466d
--- /dev/null
+++ b/libc/src/__support/mathvec/trig_reductionf.h
@@ -0,0 +1,129 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains range reductions for single-precision trigonometric
+/// functions for targets with FMA support.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N> struct Reduction {
+  cpp::simd<double, N> r;
+  cpp::simd<int64_t, N> odd;
+};
+
+// Reduces x / pi into k + r, with k as an integer and |r| <= 0.5.
+template <size_t N>
+LIBC_INLINE Reduction<N> fast_reduction(cpp::simd<double, N> x) {
+  constexpr cpp::simd<double, N> inv_pi = 0x1.45f306dc9c883p-2;
+  constexpr cpp::simd<double, N> inv_pi_tail = -0x1.6b01ec5417056p-56;
+  constexpr cpp::simd<double, N> shift = 0x1.8p52;
+
+  // Adding shift rounds x / pi to the nearest integer k,
+  // producing z = shift + k. Therefore t = shift - z = -k.
+  cpp::simd<double, N> z = cpp::multiply_add(x, inv_pi, shift);
+  cpp::simd<double, N> t = shift - z;
+
+  // r = x/pi - k
+  cpp::simd<double, N> r;
+  r = cpp::multiply_add(x, inv_pi, t);
+  r = cpp::multiply_add(x, inv_pi_tail, r);
+
+  return {r, cpp::bit_cast<cpp::simd<int64_t, N>>(z)};
+}
+
+// Two-double expansions of 2^(8*q) / pi reduced modulo an even integer,
+// q = 3..12. Padded to a 16 length array for easier access.
+LIBC_INLINE_VAR constexpr double INV_PI_HI[16] = {
+    0,
+    0,
+    0,
+    -0x1.236377d5ac07bp-2,
+    -0x1.b1bbead603d8bp-1,
+    -0x1.bbead603d8a83p-1,
+    0x1.529fc2757d1f5p-5,
+    0x1.29fc2757d1f53p-1,
+    0x1.fc2757d1f534ep-1,
+    0x1.3abe8fa9a6eep-4,
+    -0x1.505c1596447e5p-2,
+    -0x1.70565911f924fp-4,
+    0x1.f534ddc0db629p-1,
+    0,
+    0,
+    0,
+};
+
+LIBC_INLINE_VAR constexpr double INV_PI_LO[16] = {
+    0,
+    0,
+    0,
+    -0x1.505c1596447e5p-58,
+    0x1.f47d4d377036ep-55,
+    0x1.f534ddc0db629p-57,
+    0x1.a6ee06db14acdp-60,
+    0x1.377036d8a5665p-55,
+    -0x1.1f924eb53361ep-56,
+    0x1.b6c52b3278872p-58,
+    0x1.b14acc9e21c82p-56,
+    0x1.2b32788720840p-58,
+    0x1.664f10e4107f9p-55,
+    0,
+    0,
+    0,
+};
+
+// Reduces non-negative large finite inputs x >= 0x1p49.
+// Decomposes x / pi into k + r, with k as an integer and |r| <= 0.5.
+template <size_t N>
+LIBC_INLINE Reduction<N> large_reduction(cpp::simd<double, N> x) {
+  constexpr cpp::simd<double, N> shift = 0x1.8p52;
+
+  cpp::simd<uint64_t, N> ix = cpp::bit_cast<cpp::simd<uint64_t, N>>(x);
+
+  // Compute q = floor((unbiased_exponent - 25) / 8).
+  // Since 1023 + 25 = 8 * 131, this can be calculated as (ix >> 55) - 131.
+  cpp::simd<int64_t, N> q =
+      cpp::simd_cast<int64_t>(ix >> 55) - cpp::simd<int64_t, N>(131);
+
+  // While sufficiently large x will always produce q within [3, 12],
+  // not all input lanes are guaranteed to require the large reduction,
+  // so we mask with 15 to keep all values within bounds.
+  cpp::simd<int64_t, N> idx = q & cpp::simd<int64_t, N>(15);
+  cpp::simd<double, N> c_hi =
+      cpp::gather<cpp::simd<double, N>>(true, idx, INV_PI_HI);
+  cpp::simd<double, N> c_lo =
+      cpp::gather<cpp::simd<double, N>>(true, idx, INV_PI_LO);
+
+  // xr = x * 2^(-8*q) is an integer with xr in [2^25, 2^33).
+  cpp::simd<uint64_t, N> scale = cpp::bit_cast<cpp::simd<uint64_t, N>>(q) << 55;
+  cpp::simd<double, N> xr = cpp::bit_cast<cpp::simd<double, N>>(ix - scale);
+
+  // Subtract the nearest integer from xr * c_hi, and add the tail.
+  cpp::simd<double, N> biased = cpp::multiply_add(xr, c_hi, shift);
+  cpp::simd<double, N> kd = biased - shift;
+  cpp::simd<double, N> r = cpp::multiply_add(xr, c_hi, -kd);
+  r = cpp::multiply_add(xr, c_lo, r);
+
+  return {r, cpp::bit_cast<cpp::simd<int64_t, N>>(biased)};
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_H
diff --git a/libc/src/__support/mathvec/trig_reductionf_nofma.h b/libc/src/__support/mathvec/trig_reductionf_nofma.h
new file mode 100644
index 0000000000000..26619f0f0724d
--- /dev/null
+++ b/libc/src/__support/mathvec/trig_reductionf_nofma.h
@@ -0,0 +1,168 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains range reductions for single-precision trigonometric
+/// functions for targets with no FMA support.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_NOFMA_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_NOFMA_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N> struct Reduction {
+  cpp::simd<double, N> r;
+  cpp::simd<int64_t, N> odd;
+};
+
+// Reduces x / pi into k + r, with k as an integer and |r| <= 0.5.
+template <size_t N>
+LIBC_INLINE Reduction<N> fast_reduction(cpp::simd<double, N> x) {
+  constexpr cpp::simd<double, N> inv_pi_hi = 0x1.45f306e000000p-2;
+  constexpr cpp::simd<double, N> inv_pi_mid = -0x1.b1bbead000000p-33;
+  constexpr cpp::simd<double, N> inv_pi_lo = -0x1.80f62a0b82b00p-63;
+  constexpr cpp::simd<double, N> shift = 0x1.8p52;
+
+  // Since we know the input was cast to FP64 from FP32, we can use split
+  // 1 / pi coefficients such that the products of hi and mid are exact.
+  // The low part restores the remaining precision without requiring an FMA.
+  cpp::simd<double, N> x_hi = x * inv_pi_hi;
+  cpp::simd<double, N> x_mid = x * inv_pi_mid;
+  cpp::simd<double, N> x_lo = x * inv_pi_lo;
+
+  // Adding shift rounds x / pi to the nearest integer k, producing
+  // z = shift + k. Therefore t = shift - z = -k.
+  cpp::simd<double, N> z = shift + (x_hi + x_mid);
+  cpp::simd<double, N> t = shift - z;
+
+  // Accumulate the split products from largest to smallest to recover
+  // r = x / pi - k.
+  cpp::simd<double, N> r = t + x_hi + x_mid + x_lo;
+
+  // The low bit of z's representation encodes the parity of k.
+  return {r, cpp::bit_cast<cpp::simd<int64_t, N>>(z)};
+}
+
+// Three-double expansions of 2^(8*q) / pi, reduced modulo an even integer,
+// q = 3..12. Padded to 16 length arrays for safe masked indexing.
+LIBC_INLINE_VAR constexpr double INV_PI_HI[16] = {
+    0,
+    0,
+    0,
+    -0x1.236377d000000p-2,
+    -0x1.b1bbead000000p-1,
+    -0x1.bbead60000000p-1,
+    0x1.529fc27000000p-5,
+    0x1.29fc275000000p-1,
+    0x1.fc2757d000000p-1,
+    0x1.3abe8fb000000p-4,
+    -0x1.505c159000000p-2,
+    -0x1.7056591000000p-4,
+    0x1.f534ddc000000p-1,
+    0,
+    0,
+};
+
+LIBC_INLINE_VAR constexpr double INV_PI_MID[16] = {
+    0,
+    0,
+    0,
+    -0x1.6b01ec5000000p-32,
+    -0x1.80f62a1000000p-31,
+    -0x1.ec54170000000p-32,
+    0x1.5f47d4d000000p-35,
+    0x1.f47d4d3000000p-31,
+    0x1.f534ddc000000p-33,
+    -0x1.96447e5000000p-34,
+    -0x1.911f925000000p-32,
+    -0x1.f924eb5000000p-36,
+    0x1.b6c52b3000000p-34,
+    0,
+    0,
+};
+
+LIBC_INLINE_VAR constexpr double INV_PI_LO[16] = {
+    0,
+    0,
+    0,
+    -0x1.05c1596447e50p-62,
+    0x1.1f534ddc0db80p-61,
+    -0x1.596447e493ae0p-62,
+    0x1.bb81b6c52b340p-66,
+    0x1.dc0db62959940p-61,
+    0x1.b6c52b3278800p-66,
+    0x1.b14acc9e21c80p-64,
+    0x1.4acc9e21c8200p-64,
+    -0x1.9b0ef1bef8000p-67,
+    0x1.3c439041fe400p-65,
+    0,
+    0,
+};
+
+// Reduces non-negative large finite inputs x >= 0x1p49.
+// Decomposes x / pi into k + r, with k as an integer and |r| <= 0.5.
+template <size_t N>
+LIBC_INLINE Reduction<N> large_reduction(cpp::simd<double, N> x) {
+  constexpr cpp::simd<double, N> shift = 0x1.8p52;
+
+  cpp::simd<uint64_t, N> ix = cpp::bit_cast<cpp::simd<uint64_t, N>>(x);
+
+  // Compute q = floor((unbiased_exponent - 25) / 8).
+  // Since 1023 + 25 = 8 * 131, this is (ix >> 55) - 131.
+  cpp::simd<int64_t, N> q =
+      cpp::simd_cast<int64_t>(ix >> 55) - cpp::simd<int64_t, N>(131);
+
+  // While sufficiently large x will always produce q within [3, 12],
+  // not all input lanes are guaranteed to require the large reduction,
+  // so we mask with 15 to keep all values within bounds.
+  cpp::simd<int64_t, N> idx = q & cpp::simd<int64_t, N>(15);
+  cpp::simd<double, N> c_hi =
+      cpp::gather<cpp::simd<double, N>>(true, idx, INV_PI_HI);
+  cpp::simd<double, N> c_mid =
+      cpp::gather<cpp::simd<double, N>>(true, idx, INV_PI_MID);
+  cpp::simd<double, N> c_lo =
+      cpp::gather<cpp::simd<double, N>>(true, idx, INV_PI_LO);
+
+  // xr = x * 2^(-8*q) is an integer with xr in [2^25, 2^33).
+  cpp::simd<uint64_t, N> scale = cpp::bit_cast<cpp::simd<uint64_t, N>>(q) << 55;
+  cpp::simd<double, N> xr = cpp::bit_cast<cpp::simd<double, N>>(ix - scale);
+
+  // Multiplication by the high and middle parts is exact because xr retains
+  // the 24-bit significand of its FP32 source and each coefficient has at
+  // most 29 significant bits. The low part supplies the remaining precision.
+  cpp::simd<double, N> x_hi = xr * c_hi;
+  cpp::simd<double, N> x_mid = xr * c_mid;
+  cpp::simd<double, N> x_lo = xr * c_lo;
+
+  // Add from largest to smallest before using shift to obtain the nearest
+  // integer k.
+  cpp::simd<double, N> x_sum = (x_hi + x_mid) + x_lo;
+  cpp::simd<double, N> biased = shift + x_sum;
+  cpp::simd<double, N> kd = biased - shift;
+
+  // Subtract k from the same split expansion to recover r = x / pi - k.
+  cpp::simd<double, N> r = x_hi - kd;
+  r = r + x_mid;
+  r = r + x_lo;
+
+  // The low bit of biased's representation encodes the parity of k.
+  return {r, cpp::bit_cast<cpp::simd<int64_t, N>>(biased)};
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_TRIG_REDUCTIONF_NOFMA_H
diff --git a/libc/src/mathvec/generic/sinf.cpp b/libc/src/mathvec/generic/sinf.cpp
index cb9f7967b7131..9b81acea26f67 100644
--- a/libc/src/mathvec/generic/sinf.cpp
+++ b/libc/src/mathvec/generic/sinf.cpp
@@ -11,9 +11,9 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#include "src/mathvec/sinf.h"
 #include "src/__support/mathvec/sinf.h"
 #include "src/mathvec/abi_prefix.h"
+#include "src/mathvec/sinf.h"
 
 namespace LIBC_NAMESPACE_DECL {
 

>From 9ac8a2be74624b26ba585bd80232ae8d9ff24b88 Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Thu, 3 Sep 2026 16:46:06 +0000
Subject: [PATCH 2/3] Fixed abi failure

---
 libc/src/__support/mathvec/sinf.h                  | 3 ++-
 libc/src/__support/mathvec/trig_reductionf.h       | 4 ++--
 libc/src/__support/mathvec/trig_reductionf_nofma.h | 4 ++--
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/libc/src/__support/mathvec/sinf.h b/libc/src/__support/mathvec/sinf.h
index fc6e134dc0671..671b652912a67 100644
--- a/libc/src/__support/mathvec/sinf.h
+++ b/libc/src/__support/mathvec/sinf.h
@@ -30,7 +30,8 @@ namespace LIBC_NAMESPACE_DECL {
 namespace mathvec {
 
 template <size_t N>
-LIBC_INLINE cpp::simd<double, N> sinpif_poly(cpp::simd<double, N> r) {
+LIBC_INLINE static cpp::simd<double, N>
+sinpif_poly(cpp::simd<double, N> r) {
   // Approximate sin(pi * r) for |r| <= 0.5.
   // These coefficients aren't produced directly via sollya, but rather
   // are fine-tuned by iterative adjustment to remove hard to round cases.
diff --git a/libc/src/__support/mathvec/trig_reductionf.h b/libc/src/__support/mathvec/trig_reductionf.h
index 0b9f3a29e466d..dac2506683400 100644
--- a/libc/src/__support/mathvec/trig_reductionf.h
+++ b/libc/src/__support/mathvec/trig_reductionf.h
@@ -29,7 +29,7 @@ template <size_t N> struct Reduction {
 
 // Reduces x / pi into k + r, with k as an integer and |r| <= 0.5.
 template <size_t N>
-LIBC_INLINE Reduction<N> fast_reduction(cpp::simd<double, N> x) {
+LIBC_INLINE static Reduction<N> fast_reduction(cpp::simd<double, N> x) {
   constexpr cpp::simd<double, N> inv_pi = 0x1.45f306dc9c883p-2;
   constexpr cpp::simd<double, N> inv_pi_tail = -0x1.6b01ec5417056p-56;
   constexpr cpp::simd<double, N> shift = 0x1.8p52;
@@ -90,7 +90,7 @@ LIBC_INLINE_VAR constexpr double INV_PI_LO[16] = {
 // Reduces non-negative large finite inputs x >= 0x1p49.
 // Decomposes x / pi into k + r, with k as an integer and |r| <= 0.5.
 template <size_t N>
-LIBC_INLINE Reduction<N> large_reduction(cpp::simd<double, N> x) {
+LIBC_INLINE static Reduction<N> large_reduction(cpp::simd<double, N> x) {
   constexpr cpp::simd<double, N> shift = 0x1.8p52;
 
   cpp::simd<uint64_t, N> ix = cpp::bit_cast<cpp::simd<uint64_t, N>>(x);
diff --git a/libc/src/__support/mathvec/trig_reductionf_nofma.h b/libc/src/__support/mathvec/trig_reductionf_nofma.h
index 26619f0f0724d..ac2f029922c5b 100644
--- a/libc/src/__support/mathvec/trig_reductionf_nofma.h
+++ b/libc/src/__support/mathvec/trig_reductionf_nofma.h
@@ -29,7 +29,7 @@ template <size_t N> struct Reduction {
 
 // Reduces x / pi into k + r, with k as an integer and |r| <= 0.5.
 template <size_t N>
-LIBC_INLINE Reduction<N> fast_reduction(cpp::simd<double, N> x) {
+LIBC_INLINE static Reduction<N> fast_reduction(cpp::simd<double, N> x) {
   constexpr cpp::simd<double, N> inv_pi_hi = 0x1.45f306e000000p-2;
   constexpr cpp::simd<double, N> inv_pi_mid = -0x1.b1bbead000000p-33;
   constexpr cpp::simd<double, N> inv_pi_lo = -0x1.80f62a0b82b00p-63;
@@ -114,7 +114,7 @@ LIBC_INLINE_VAR constexpr double INV_PI_LO[16] = {
 // Reduces non-negative large finite inputs x >= 0x1p49.
 // Decomposes x / pi into k + r, with k as an integer and |r| <= 0.5.
 template <size_t N>
-LIBC_INLINE Reduction<N> large_reduction(cpp::simd<double, N> x) {
+LIBC_INLINE static Reduction<N> large_reduction(cpp::simd<double, N> x) {
   constexpr cpp::simd<double, N> shift = 0x1.8p52;
 
   cpp::simd<uint64_t, N> ix = cpp::bit_cast<cpp::simd<uint64_t, N>>(x);

>From be82c3054892792595596cf98d384c5dfe6ab3b5 Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Thu, 3 Sep 2026 17:06:31 +0000
Subject: [PATCH 3/3] Corrected formatting error

---
 libc/src/__support/mathvec/sinf.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libc/src/__support/mathvec/sinf.h b/libc/src/__support/mathvec/sinf.h
index 671b652912a67..e99356165f6d3 100644
--- a/libc/src/__support/mathvec/sinf.h
+++ b/libc/src/__support/mathvec/sinf.h
@@ -30,8 +30,7 @@ namespace LIBC_NAMESPACE_DECL {
 namespace mathvec {
 
 template <size_t N>
-LIBC_INLINE static cpp::simd<double, N>
-sinpif_poly(cpp::simd<double, N> r) {
+LIBC_INLINE static cpp::simd<double, N> sinpif_poly(cpp::simd<double, N> r) {
   // Approximate sin(pi * r) for |r| <= 0.5.
   // These coefficients aren't produced directly via sollya, but rather
   // are fine-tuned by iterative adjustment to remove hard to round cases.



More information about the libc-commits mailing list