[libc-commits] [libc] [llvm] [libc][math] Refractor sinhf to Header only (PR #177336)

Anikesh Parashar via libc-commits libc-commits at lists.llvm.org
Sat Jan 24 11:11:07 PST 2026


https://github.com/an1k3sh updated https://github.com/llvm/llvm-project/pull/177336

>From 3ceb1749a25fdedf10e8e9c80cb9d628b5506e8f Mon Sep 17 00:00:00 2001
From: Anikesh Parashar <anikeshparashar at gmail.com>
Date: Wed, 21 Jan 2026 02:19:34 +0530
Subject: [PATCH 1/6] Use constexpr for sinhf #147386

---
 libc/shared/math.h                            |  1 +
 libc/shared/math/sinhf.h                      | 24 +++++
 libc/src/__support/math/CMakeLists.txt        | 13 +++
 libc/src/__support/math/sinhf.h               | 88 +++++++++++++++++++
 libc/src/math/generic/CMakeLists.txt          |  1 +
 libc/src/math/generic/sinhf.cpp               |  7 +-
 libc/test/shared/CMakeLists.txt               |  1 +
 libc/test/shared/shared_math_test.cpp         |  1 +
 .../llvm-project-overlay/libc/BUILD.bazel     | 13 +++
 9 files changed, 143 insertions(+), 6 deletions(-)
 create mode 100644 libc/shared/math/sinhf.h
 create mode 100644 libc/src/__support/math/sinhf.h

diff --git a/libc/shared/math.h b/libc/shared/math.h
index d58238703701d..ee0f0f7441de2 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -79,5 +79,6 @@
 #include "math/rsqrtf.h"
 #include "math/rsqrtf16.h"
 #include "math/sin.h"
+#include "math/sinhf.h"
 
 #endif // LLVM_LIBC_SHARED_MATH_H
diff --git a/libc/shared/math/sinhf.h b/libc/shared/math/sinhf.h
new file mode 100644
index 0000000000000..7d24523e4b76e
--- /dev/null
+++ b/libc/shared/math/sinhf.h
@@ -0,0 +1,24 @@
+//===-- Shared sinhf function ------------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_MATH_SINHF_H
+#define LLVM_LIBC_SHARED_MATH_SINHF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/sinhf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace shared {
+using math::sinhf;
+} // namespace shared
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_SINHF_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index bf1c4463b8066..ce6acef7b06b6 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -1174,6 +1174,19 @@ add_header_library(
     libc.src.__support.macros.optimization
 )
 
+add_header_library(
+  sinhf
+  HDRS
+    sinhf.h
+  DEPENDS
+    libc.src.__support.FPUtil.FEnvImpl
+    libc.src.__support.FPUtil.FPBits
+    libc.src.__support.FPUtil.rounding_mode
+    libc.src.__support.macros.config
+    libc.src.__support.macros.optimization
+    libc.src.__support.math.sinhfcoshf_utils
+)
+
 add_header_library(
   dfmal
   HDRS
diff --git a/libc/src/__support/math/sinhf.h b/libc/src/__support/math/sinhf.h
new file mode 100644
index 0000000000000..aafcbf0748a10
--- /dev/null
+++ b/libc/src/__support/math/sinhf.h
@@ -0,0 +1,88 @@
+//===-- Single-precision sinh function ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_SINHF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_SINHF_H
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math/sinhfcoshf_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+static constexpr float sinhf(float x) {
+  using FPBits = typename fputil::FPBits<float>;
+  FPBits xbits(x);
+  uint32_t x_abs = xbits.abs().uintval();
+
+  // When |x| >= 90, or x is inf or nan
+  if (LIBC_UNLIKELY(x_abs >= 0x42b4'0000U || x_abs <= 0x3da0'0000U)) {
+    // |x| <= 0.078125
+    if (x_abs <= 0x3da0'0000U) {
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+      // |x| = 0.0005589424981735646724700927734375
+      if (LIBC_UNLIKELY(x_abs == 0x3a12'85ffU)) {
+        if (fputil::fenv_is_round_to_nearest())
+          return x;
+      }
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+      // |x| <= 2^-26
+      if (LIBC_UNLIKELY(x_abs <= 0x3280'0000U)) {
+        return static_cast<float>(
+            LIBC_UNLIKELY(x_abs == 0) ? x : (x + 0.25 * x * x * x));
+      }
+
+      double xdbl = x;
+      double x2 = xdbl * xdbl;
+      // Sollya: fpminimax(sinh(x),[|3,5,7|],[|D...|],[-1/16-1/64;1/16+1/64],x);
+      // Sollya output: x * (0x1p0 + x^0x1p1 * (0x1.5555555556583p-3 + x^0x1p1
+      //                  * (0x1.111110d239f1fp-7
+      //                  + x^0x1p1 * 0x1.a02b5a284013cp-13)))
+      // Therefore, output of Sollya = x * pe;
+      double pe = fputil::polyeval(x2, 0.0, 0x1.5555555556583p-3,
+                                   0x1.111110d239f1fp-7, 0x1.a02b5a284013cp-13);
+      return static_cast<float>(fputil::multiply_add(xdbl, pe, xdbl));
+    }
+
+    if (xbits.is_nan())
+      return x + 1.0f; // sNaN to qNaN + signal
+
+    if (xbits.is_inf())
+      return x;
+
+    int rounding = fputil::quick_get_round();
+    if (xbits.is_neg()) {
+      if (LIBC_UNLIKELY(rounding == FE_UPWARD || rounding == FE_TOWARDZERO))
+        return -FPBits::max_normal().get_val();
+    } else {
+      if (LIBC_UNLIKELY(rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO))
+        return FPBits::max_normal().get_val();
+    }
+
+    fputil::set_errno_if_required(ERANGE);
+    fputil::raise_except_if_required(FE_OVERFLOW);
+
+    return x + FPBits::inf(xbits.sign()).get_val();
+  }
+
+  // sinh(x) = (e^x - e^(-x)) / 2.
+  return static_cast<float>(
+      math::sinhfcoshf_internal::exp_pm_eval</*is_sinh*/ true>(x));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_SINHF_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index b578d1805f2a8..f3890d0a188bf 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4197,6 +4197,7 @@ add_entrypoint_object(
     libc.src.__support.FPUtil.rounding_mode
     libc.src.__support.macros.optimization
     libc.src.__support.math.sinhfcoshf_utils
+    libc.src.__support.math.sinhf
 )
 
 add_entrypoint_object(
diff --git a/libc/src/math/generic/sinhf.cpp b/libc/src/math/generic/sinhf.cpp
index 5f2d0b5d9c71c..c03b22259c91a 100644
--- a/libc/src/math/generic/sinhf.cpp
+++ b/libc/src/math/generic/sinhf.cpp
@@ -7,12 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/math/sinhf.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/rounding_mode.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include "src/__support/math/sinhfcoshf_utils.h"
+#include "src/__support/math/sinhf.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index cfc2eda1aaec9..6932acda8f174 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -75,4 +75,5 @@ add_fp_unittest(
     libc.src.__support.math.rsqrtf
     libc.src.__support.math.rsqrtf16
     libc.src.__support.math.sin
+    libc.src.__support.math.sinhf
 )
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 88e6ecc98a0a7..7bfcbf0177949 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -73,6 +73,7 @@ TEST(LlvmLibcSharedMathTest, AllFloat) {
   EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::exp2f(0.0f));
   EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::expm1f(0.0f));
   EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::hypotf(0.0f, 0.0f));
+  EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::sinhf(0.0f));
 
   EXPECT_FP_EQ_ALL_ROUNDING(0.75f,
                             LIBC_NAMESPACE::shared::frexpf(24.0f, &exponent));
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 90b1da0e3376e..cb510dce46b77 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -3345,6 +3345,19 @@ libc_support_library(
     ],
 )
 
+libc_support_library(
+    name = "__support_math_sinhf",
+    hdrs = ["src/__support/math/sinhf.h"],
+    deps = [
+        ":__support_fputil_fenv_impl",
+        ":__support_fputil_fp_bits",
+        ":__support_fputil_rounding_mode",
+        ":__support_macros_config",
+        ":__support_macros_optimization",
+        ":__support_math_sinhfcoshf_utils",
+    ],
+)
+
 ############################### complex targets ################################
 
 libc_function(

>From 1f181102fa72933a89a193b785a0ebe3b0f051e5 Mon Sep 17 00:00:00 2001
From: Anikesh Parashar <anikeshparashar at gmail.com>
Date: Wed, 21 Jan 2026 16:36:02 +0530
Subject: [PATCH 2/6] correct bug in __support/math/CMakeLists

---
 libc/src/__support/math/CMakeLists.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index ce6acef7b06b6..0cc00fccdeb46 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -1179,8 +1179,8 @@ add_header_library(
   HDRS
     sinhf.h
   DEPENDS
-    libc.src.__support.FPUtil.FEnvImpl
-    libc.src.__support.FPUtil.FPBits
+    libc.src.__support.FPUtil.fenv_impl
+    libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.rounding_mode
     libc.src.__support.macros.config
     libc.src.__support.macros.optimization

>From ec6084f71ef90524a229b3092990ddf19d0ec431 Mon Sep 17 00:00:00 2001
From: Anikesh Parashar <anikeshparashar at gmail.com>
Date: Wed, 21 Jan 2026 17:20:39 +0530
Subject: [PATCH 3/6] use header implementation for sinhf

---
 libc/src/math/generic/sinhf.cpp | 59 +--------------------------------
 1 file changed, 1 insertion(+), 58 deletions(-)

diff --git a/libc/src/math/generic/sinhf.cpp b/libc/src/math/generic/sinhf.cpp
index c03b22259c91a..81e26f9517ea9 100644
--- a/libc/src/math/generic/sinhf.cpp
+++ b/libc/src/math/generic/sinhf.cpp
@@ -12,64 +12,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(float, sinhf, (float x)) {
-  using FPBits = typename fputil::FPBits<float>;
-  FPBits xbits(x);
-  uint32_t x_abs = xbits.abs().uintval();
-
-  // When |x| >= 90, or x is inf or nan
-  if (LIBC_UNLIKELY(x_abs >= 0x42b4'0000U || x_abs <= 0x3da0'0000U)) {
-    // |x| <= 0.078125
-    if (x_abs <= 0x3da0'0000U) {
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-      // |x| = 0.0005589424981735646724700927734375
-      if (LIBC_UNLIKELY(x_abs == 0x3a12'85ffU)) {
-        if (fputil::fenv_is_round_to_nearest())
-          return x;
-      }
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-      // |x| <= 2^-26
-      if (LIBC_UNLIKELY(x_abs <= 0x3280'0000U)) {
-        return static_cast<float>(
-            LIBC_UNLIKELY(x_abs == 0) ? x : (x + 0.25 * x * x * x));
-      }
-
-      double xdbl = x;
-      double x2 = xdbl * xdbl;
-      // Sollya: fpminimax(sinh(x),[|3,5,7|],[|D...|],[-1/16-1/64;1/16+1/64],x);
-      // Sollya output: x * (0x1p0 + x^0x1p1 * (0x1.5555555556583p-3 + x^0x1p1
-      //                  * (0x1.111110d239f1fp-7
-      //                  + x^0x1p1 * 0x1.a02b5a284013cp-13)))
-      // Therefore, output of Sollya = x * pe;
-      double pe = fputil::polyeval(x2, 0.0, 0x1.5555555556583p-3,
-                                   0x1.111110d239f1fp-7, 0x1.a02b5a284013cp-13);
-      return static_cast<float>(fputil::multiply_add(xdbl, pe, xdbl));
-    }
-
-    if (xbits.is_nan())
-      return x + 1.0f; // sNaN to qNaN + signal
-
-    if (xbits.is_inf())
-      return x;
-
-    int rounding = fputil::quick_get_round();
-    if (xbits.is_neg()) {
-      if (LIBC_UNLIKELY(rounding == FE_UPWARD || rounding == FE_TOWARDZERO))
-        return -FPBits::max_normal().get_val();
-    } else {
-      if (LIBC_UNLIKELY(rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO))
-        return FPBits::max_normal().get_val();
-    }
-
-    fputil::set_errno_if_required(ERANGE);
-    fputil::raise_except_if_required(FE_OVERFLOW);
-
-    return x + FPBits::inf(xbits.sign()).get_val();
-  }
-
-  // sinh(x) = (e^x - e^(-x)) / 2.
-  return static_cast<float>(
-      math::sinhfcoshf_internal::exp_pm_eval</*is_sinh*/ true>(x));
+  return math::sinhf(x);
 }
 
 } // namespace LIBC_NAMESPACE_DECL

>From c923684946ae7d77f5d28e1772a38b57f0d99b70 Mon Sep 17 00:00:00 2001
From: Anikesh Parashar <anikeshparashar at gmail.com>
Date: Wed, 21 Jan 2026 17:27:38 +0530
Subject: [PATCH 4/6] use header implementation for sinhf

---
 libc/src/math/generic/sinhf.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/libc/src/math/generic/sinhf.cpp b/libc/src/math/generic/sinhf.cpp
index 81e26f9517ea9..a8f8c715019a8 100644
--- a/libc/src/math/generic/sinhf.cpp
+++ b/libc/src/math/generic/sinhf.cpp
@@ -11,8 +11,6 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LLVM_LIBC_FUNCTION(float, sinhf, (float x)) {
-  return math::sinhf(x);
-}
+LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { return math::sinhf(x); }
 
 } // namespace LIBC_NAMESPACE_DECL

>From 9ad0531128f344501803914042ee03da56c61d3b Mon Sep 17 00:00:00 2001
From: Anikesh Parashar <anikeshparashar at gmail.com>
Date: Sun, 25 Jan 2026 00:39:34 +0530
Subject: [PATCH 5/6] update dependency list and file structures

---
 libc/shared/math/sinhf.h             | 4 ++--
 libc/src/__support/math/sinhf.h      | 2 +-
 libc/src/math/generic/CMakeLists.txt | 4 ----
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/libc/shared/math/sinhf.h b/libc/shared/math/sinhf.h
index 7d24523e4b76e..62ce05196e64b 100644
--- a/libc/shared/math/sinhf.h
+++ b/libc/shared/math/sinhf.h
@@ -14,11 +14,11 @@
 #include "src/__support/math/sinhf.h"
 
 namespace LIBC_NAMESPACE_DECL {
-
 namespace shared {
+
 using math::sinhf;
-} // namespace shared
 
+} // namespace shared
 } // namespace LIBC_NAMESPACE_DECL
 
 #endif // LLVM_LIBC_SHARED_MATH_SINHF_H
diff --git a/libc/src/__support/math/sinhf.h b/libc/src/__support/math/sinhf.h
index aafcbf0748a10..0658c192dd1a7 100644
--- a/libc/src/__support/math/sinhf.h
+++ b/libc/src/__support/math/sinhf.h
@@ -14,7 +14,7 @@
 #include "src/__support/FPUtil/rounding_mode.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include "src/__support/math/sinhfcoshf_utils.h"
+#include "sinhfcoshf_utils.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index f3890d0a188bf..e9b171d66b53a 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4193,10 +4193,6 @@ add_entrypoint_object(
   HDRS
     ../sinhf.h
   DEPENDS
-    libc.src.__support.FPUtil.fp_bits
-    libc.src.__support.FPUtil.rounding_mode
-    libc.src.__support.macros.optimization
-    libc.src.__support.math.sinhfcoshf_utils
     libc.src.__support.math.sinhf
 )
 

>From 9c6eaa6a9152a19bcd63782dc70184bebbe55d70 Mon Sep 17 00:00:00 2001
From: Anikesh Parashar <anikeshparashar at gmail.com>
Date: Sun, 25 Jan 2026 00:40:53 +0530
Subject: [PATCH 6/6] update bazel build file

---
 utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index cb510dce46b77..ca6a96b4b02bb 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -3349,12 +3349,7 @@ libc_support_library(
     name = "__support_math_sinhf",
     hdrs = ["src/__support/math/sinhf.h"],
     deps = [
-        ":__support_fputil_fenv_impl",
-        ":__support_fputil_fp_bits",
-        ":__support_fputil_rounding_mode",
-        ":__support_macros_config",
-        ":__support_macros_optimization",
-        ":__support_math_sinhfcoshf_utils",
+        ":__support_math_sinhf",
     ],
 )
 



More information about the libc-commits mailing list