[libc][math] Refractor sinhf to Header only#177336
Merged
bassiounix merged 15 commits intollvm:mainfrom Jan 27, 2026
Merged
Conversation
Member
|
@llvm/pr-subscribers-libc Author: Anikesh Parashar (an1k3sh) ChangesPart 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:
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(
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Contributor
Author
|
@bassiounix could you review this PR? |
bassiounix
requested changes
Jan 26, 2026
Co-authored-by: Muhammad Bassiouni <60100307+bassiounix@users.noreply.github.com>
Co-authored-by: Muhammad Bassiouni <60100307+bassiounix@users.noreply.github.com>
bassiounix
requested changes
Jan 27, 2026
bassiounix
approved these changes
Jan 27, 2026
Member
bassiounix
left a comment
There was a problem hiding this comment.
LGTM. Thank you for the refactor.
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #147386
Separate issue hasn't been created for the task
EDIT: Resolves #177644