Skip to content

[libc][math] Refractor sinhf to Header only#177336

Merged
bassiounix merged 15 commits intollvm:mainfrom
an1k3sh:refractor-constexpr-sinhf
Jan 27, 2026
Merged

[libc][math] Refractor sinhf to Header only#177336
bassiounix merged 15 commits intollvm:mainfrom
an1k3sh:refractor-constexpr-sinhf

Conversation

@an1k3sh
Copy link
Copy Markdown
Contributor

@an1k3sh an1k3sh commented Jan 22, 2026

Part of #147386

Separate issue hasn't been created for the task

EDIT: Resolves #177644

@llvmbot llvmbot added libc bazel "Peripheral" support tier build system: utils/bazel labels Jan 22, 2026
@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Jan 22, 2026

@llvm/pr-subscribers-libc

Author: Anikesh Parashar (an1k3sh)

Changes

Part of #147386

Separate issue hasn't been created for the task


Full diff: https://github.com/llvm/llvm-project/pull/177336.diff

9 Files Affected:

  • (modified) libc/shared/math.h (+1)
  • (added) libc/shared/math/sinhf.h (+24)
  • (modified) libc/src/__support/math/CMakeLists.txt (+13)
  • (added) libc/src/__support/math/sinhf.h (+88)
  • (modified) libc/src/math/generic/CMakeLists.txt (+1)
  • (modified) libc/src/math/generic/sinhf.cpp (+2-66)
  • (modified) libc/test/shared/CMakeLists.txt (+1)
  • (modified) libc/test/shared/shared_math_test.cpp (+1)
  • (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+13)
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..0cc00fccdeb46 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.fenv_impl
+    libc.src.__support.FPUtil.fp_bits
+    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..a8f8c715019a8 100644
--- a/libc/src/math/generic/sinhf.cpp
+++ b/libc/src/math/generic/sinhf.cpp
@@ -7,74 +7,10 @@
 //===----------------------------------------------------------------------===//
 
 #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 {
 
-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));
-}
+LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { return math::sinhf(x); }
 
 } // 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(

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 25, 2026

✅ With the latest revision this PR passed the C/C++ code formatter.

@an1k3sh
Copy link
Copy Markdown
Contributor Author

an1k3sh commented Jan 26, 2026

@bassiounix could you review this PR?

an1k3sh and others added 3 commits January 27, 2026 02:57
Co-authored-by: Muhammad Bassiouni <60100307+bassiounix@users.noreply.github.com>
Co-authored-by: Muhammad Bassiouni <60100307+bassiounix@users.noreply.github.com>
Copy link
Copy Markdown
Member

@bassiounix bassiounix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you for the refactor.

@bassiounix bassiounix merged commit 2e99240 into llvm:main Jan 27, 2026
29 checks passed
Abdelrhmansersawy pushed a commit to Abdelrhmansersawy/llvm-project that referenced this pull request Jan 27, 2026
stomfaig pushed a commit to stomfaig/llvm-project that referenced this pull request Jan 28, 2026
sshrestha-aa pushed a commit to sshrestha-aa/llvm-project that referenced this pull request Feb 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bazel "Peripheral" support tier build system: utils/bazel libc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[libc][math] Refactor sinhf to Header Only.

3 participants