[llvm-branch-commits] [libc] [llvm] [libc][math] Implement double precision cosh correctly rounded to all rounding modes. (PR #235181)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Oct 23 19:22:00 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: lntue

<details>
<summary>Changes</summary>

Use shared `exp(x) +- exp(-x)` evaluations with `sinh` from https://github.com/llvm/llvm-project/pull/235097.

Assisted-by: Gemini for analysis and refactoring.

---

Patch is 34.05 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/235181.diff


30 Files Affected:

- (modified) libc/config/baremetal/aarch64/entrypoints.txt (+1) 
- (modified) libc/config/baremetal/arm/entrypoints.txt (+1) 
- (modified) libc/config/baremetal/riscv/entrypoints.txt (+1) 
- (modified) libc/config/darwin/aarch64/entrypoints.txt (+1) 
- (modified) libc/config/freebsd/x86_64/entrypoints.txt (+1) 
- (modified) libc/config/gpu/amdgpu/entrypoints.txt (+1) 
- (modified) libc/config/gpu/nvptx/entrypoints.txt (+1) 
- (modified) libc/config/linux/aarch64/entrypoints.txt (+1) 
- (modified) libc/config/linux/arm/entrypoints.txt (+1) 
- (modified) libc/config/linux/riscv/entrypoints.txt (+1) 
- (modified) libc/config/linux/x86_64/entrypoints.txt (+1) 
- (modified) libc/config/windows/entrypoints.txt (+1) 
- (modified) libc/docs/headers/math/index.md (+1-1) 
- (modified) libc/include/math.yaml (+6) 
- (modified) libc/shared/math.h (+1) 
- (added) libc/shared/math/cosh.h (+28) 
- (modified) libc/src/__support/math/CMakeLists.txt (+29) 
- (added) libc/src/__support/math/cosh.h (+34) 
- (added) libc/src/__support/math/cosh_double_eval.h (+94) 
- (modified) libc/src/math/generic/CMakeLists.txt (+10) 
- (added) libc/src/math/generic/cosh.cpp (+21) 
- (modified) libc/test/shared/CMakeLists.txt (+1) 
- (modified) libc/test/shared/shared_math_test.cpp (+1) 
- (modified) libc/test/src/math/CMakeLists.txt (+16) 
- (added) libc/test/src/math/cosh_test.cpp (+187) 
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+15) 
- (added) libc/test/src/math/smoke/cosh_test.cpp (+125) 
- (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+34) 
- (modified) utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel (+8) 
- (modified) utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel (+8) 


``````````diff
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index db6033e9a2c04..6ac24afcfbbcd 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -385,6 +385,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.copysignl
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.cospif
     libc.src.math.dfmal
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index e4964aa02a6ec..a71e3fc8cb1c8 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -397,6 +397,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.copysignl
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.cospif
     libc.src.math.dfmal
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index d9baaaeba8a10..1a48146147378 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -388,6 +388,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.copysignl
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.cospif
     libc.src.math.dfmal
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index cabd03e2442df..20ab7d6e18052 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -206,6 +206,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.copysignl
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.cospif
     libc.src.math.dfmal
diff --git a/libc/config/freebsd/x86_64/entrypoints.txt b/libc/config/freebsd/x86_64/entrypoints.txt
index 6d567b01571e8..4c256333d9228 100644
--- a/libc/config/freebsd/x86_64/entrypoints.txt
+++ b/libc/config/freebsd/x86_64/entrypoints.txt
@@ -140,6 +140,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.ceill
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.daddl
     libc.src.math.ddivl
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 196b6a3fd2026..880327cba1cbb 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -331,6 +331,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.copysignl
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.cospif
     libc.src.math.ddivl
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index 96305e3d1293f..1c8a02af59a83 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -327,6 +327,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.copysignl
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.cospif
     libc.src.math.ddivl
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index f78eb4d3c8a37..79626a1ad727d 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -627,6 +627,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.copysignl
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.cospif
     libc.src.math.daddl
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 3dd2eede1952d..2d8bbf275517e 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -423,6 +423,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.copysignl
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.dfmal
     libc.src.math.dsqrtl
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 689eeb8f6e3d6..a5f834f8e2c62 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -684,6 +684,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.copysignl
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.cospif
     libc.src.math.daddl
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index a42172e2cce6f..110dca3a73ab7 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -706,6 +706,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.copysignl
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.cospif
     libc.src.math.daddl
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index f38000fcddb7a..4abd600c61d1d 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -172,6 +172,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.ceill
     libc.src.math.cos
     libc.src.math.cosf
+    libc.src.math.cosh
     libc.src.math.coshf
     libc.src.math.daddl
     libc.src.math.ddivl
diff --git a/libc/docs/headers/math/index.md b/libc/docs/headers/math/index.md
index a4596408ee564..e0393075cd900 100644
--- a/libc/docs/headers/math/index.md
+++ b/libc/docs/headers/math/index.md
@@ -180,7 +180,7 @@ log
 | cbrt      | {{ check }}       | {{ check }}      |                         | {{ check }}           |                         | {{ check }}             | 7.12.7.1               | F.10.4.1                   |
 | compoundn |                   |                  |                         |                       |                         |                         | 7.12.7.2               | F.10.4.2                   |
 | cos       | {{ check }}       | {{ check }}      |                         | {{ check }}           |                         |                         | 7.12.4.5               | F.10.1.5                   |
-| cosh      | {{ check }}       |                  |                         | {{ check }}           |                         |                         | 7.12.5.4               | F.10.2.4                   |
+| cosh      | {{ check }}       | {{ check }}      |                         | {{ check }}           |                         |                         | 7.12.5.4               | F.10.2.4                   |
 | cospi     | {{ check }}       |                  |                         | {{ check }}           |                         |                         | 7.12.4.12              | F.10.1.12                  |
 | dsqrt     | N/A               | N/A              | {{ check }}             | N/A                   | {{ check }}\*           |                         | 7.12.14.6              | F.10.11                    |
 | erf       | {{ check }}       |                  |                         |                       |                         |                         | 7.12.8.1               | F.10.5.1                   |
diff --git a/libc/include/math.yaml b/libc/include/math.yaml
index 89e0ab4f0dac6..09668300f9ea8 100644
--- a/libc/include/math.yaml
+++ b/libc/include/math.yaml
@@ -323,6 +323,12 @@ functions:
     arguments:
       - type: _Float16
     guard: LIBC_TYPES_HAS_FLOAT16
+  - name: cosh
+    standards:
+      - stdc
+    return_type: double
+    arguments:
+      - type: double
   - name: coshf
     standards:
       - stdc
diff --git a/libc/shared/math.h b/libc/shared/math.h
index 04f85e000bd0b..1f676b8da2e4f 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -84,6 +84,7 @@
 #include "math/cos.h"
 #include "math/cosf.h"
 #include "math/cosf16.h"
+#include "math/cosh.h"
 #include "math/coshf.h"
 #include "math/coshf16.h"
 #include "math/cospif.h"
diff --git a/libc/shared/math/cosh.h b/libc/shared/math/cosh.h
new file mode 100644
index 0000000000000..7e21496ebcd9b
--- /dev/null
+++ b/libc/shared/math/cosh.h
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Shared cosh function.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_MATH_COSH_H
+#define LLVM_LIBC_SHARED_MATH_COSH_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/cosh.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::cosh;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_COSH_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 29b085e1d0c16..390220bd5a4b8 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -5772,6 +5772,35 @@ add_header_library(
     libc.src.__support.macros.properties.cpu_features
 )
 
+add_header_library(
+  cosh_double_eval
+  HDRS
+    cosh_double_eval.h
+  DEPENDS
+    .sinhcosh_utils
+    libc.hdr.errno_macros
+    libc.hdr.fenv_macros
+    libc.src.__support.FPUtil.except_value_utils
+    libc.src.__support.FPUtil.fenv_impl
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.rounding_mode
+    libc.src.__support.common
+    libc.src.__support.macros.attributes
+    libc.src.__support.macros.config
+    libc.src.__support.macros.optimization
+)
+
+add_header_library(
+  cosh
+  HDRS
+    cosh.h
+  DEPENDS
+    .cosh_double_eval
+    libc.src.__support.common
+    libc.src.__support.macros.config
+    libc.src.__support.macros.optimization
+)
+
 add_header_library(
   sinh_double_eval
   HDRS
diff --git a/libc/src/__support/math/cosh.h b/libc/src/__support/math/cosh.h
new file mode 100644
index 0000000000000..07248d0b0023b
--- /dev/null
+++ b/libc/src/__support/math/cosh.h
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Implementation header for cosh.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COSH_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_COSH_H
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+
+#include "src/__support/math/cosh_double_eval.h"
+#define LIBC_MATH_COSH_IMPL double_eval
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+
+using LIBC_MATH_COSH_IMPL::cosh;
+
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#undef LIBC_MATH_COSH_IMPL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSH_H
diff --git a/libc/src/__support/math/cosh_double_eval.h b/libc/src/__support/math/cosh_double_eval.h
new file mode 100644
index 0000000000000..0511cee00cdaa
--- /dev/null
+++ b/libc/src/__support/math/cosh_double_eval.h
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Double-precision implementation of cosh.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_COSH_DOUBLE_EVAL_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_COSH_DOUBLE_EVAL_H
+
+#include "hdr/errno_macros.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/math/sinhcosh_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace double_eval {
+
+// Handle tiny (|x| <= 2^-27), overflow (|x| >= 0x1.633ce8fb9f87ep+9), inf, and
+// nan for cosh(x):
+LIBC_NOINLINE LIBC_INLINE double cosh_exceptional(double x) {
+  using FPBits = fputil::FPBits<double>;
+  FPBits xbits(x);
+
+  // Tiny and subnormal range: |x| <= 2^-27.
+  // For 0 < |x| <= 2^-27:
+  //   0 < cosh(x) - 1 ~ x^2 / 2 < 2^-55 < 0.5 * ulp(1.0),
+  // so cosh(x) rounds to 1.0 + 2^-52 when rounding mode is FE_UPWARD and to
+  // 1.0 otherwise, with FE_INEXACT raised for all x != 0.
+  if (xbits.abs().uintval() <= 0x3e40'0000'0000'0000ULL) {
+    if (LIBC_UNLIKELY(x == 0.0))
+      return 1.0;
+    return fputil::round_result_slightly_up(1.0);
+  }
+
+  if (xbits.is_nan())
+    return x + 1.0;
+
+  if (xbits.is_inf())
+    return FPBits::inf().get_val();
+
+  fputil::set_errno_if_required(ERANGE);
+  fputil::raise_overflow_except_if_required<double>();
+
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+  int rounding = fputil::quick_get_round();
+  if (LIBC_UNLIKELY(rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO))
+    return FPBits::max_normal().get_val();
+#endif // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+
+  return FPBits::inf().get_val();
+}
+
+LIBC_ALWAYS_INLINE double cosh(double x) {
+  using FPBits = fputil::FPBits<double>;
+  FPBits xbits(x);
+
+  uint64_t x_abs = xbits.abs().uintval();
+
+  // Bound constants (with biased exponent and mantissa bits):
+  // - Tiny bound: 2^-27 = 0x1.0p-27
+  constexpr uint64_t TINY_BOUND = 0x3e40'0000'0000'0000ULL;
+  // - Overflow bound:
+  //   > round(acosh(2^1023 * (2 - 2^-52)), D, RU) = 0x1.633ce8fb9f87ep+9
+  //   > round(acosh(2^1023 * (2 - 2^-52)), D, RD) = 0x1.633ce8fb9f87dp+9
+  //   > round(cosh(0x1.633ce8fb9f87dp+9), D, RN)  = 0x1.ffffffffffd3bp+1023
+  //   > round(cosh(0x1.633ce8fb9f87ep+9), D, RN)  = +inf
+  constexpr uint64_t OVERFLOW_BOUND = 0x4086'33ce'8fb9'f87eULL;
+
+  if (LIBC_UNLIKELY(x_abs <= TINY_BOUND || x_abs >= OVERFLOW_BOUND))
+    return cosh_exceptional(x);
+
+  return exp_pm_eval(xbits.abs().get_val(), /*is_sinh=*/false);
+}
+
+} // namespace double_eval
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSH_DOUBLE_EVAL_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 6b025c4fa6062..9f0325832248e 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -3733,6 +3733,16 @@ add_entrypoint_object(
     libc.src.__support.math.ufromfpxbf16
 )
 
+add_entrypoint_object(
+  cosh
+  SRCS
+    cosh.cpp
+  HDRS
+    ../cosh.h
+  DEPENDS
+    libc.src.__support.math.cosh
+)
+
 add_entrypoint_object(
   coshf
   SRCS
diff --git a/libc/src/math/generic/cosh.cpp b/libc/src/math/generic/cosh.cpp
new file mode 100644
index 0000000000000..3d34c90f1a54c
--- /dev/null
+++ b/libc/src/math/generic/cosh.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Double-precision cosh(x) function.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/math/cosh.h"
+#include "src/__support/math/cosh.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(double, cosh, (double x)) { return math::cosh(x); }
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index 80c3eb1e1a8f2..f902fa553e49e 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -93,6 +93,7 @@ else()
       libc.src.__support.math.cos
       libc.src.__support.math.cosf
       libc.src.__support.math.cosf16
+      libc.src.__support.math.cosh
       libc.src.__support.math.coshf
       libc.src.__support.math.coshf16
       libc.src.__support.math.cospif
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 1d70b4d357820..73a5cb45ed2b9 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -337,6 +337,7 @@ TEST(LlvmLibcSharedMathTest, AllDouble) {
   EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::atan2(0.0, 0.0));
   EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::cbrt(0.0));
   EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::shared::cos(0.0));
+  EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::shared::cosh(0.0));
   EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::shared::exp(0.0));
   EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::shared::exp2(0.0));
   EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::shared::exp10(0.0));
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 394f347782807..9ec8422b57f08 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2568,6 +2568,22 @@ add_fp_unittest(
     libc.src.__support.FPUtil.fp_bits
 )
 
+add_fp_unittest(
+  cosh_test
+  NEED_MPFR
+  SUITE
+    libc-math-tests
+  SRCS
+    cosh_test.cpp
+  DEPENDS
+    libc.hdr.fenv_macros
+    libc.src.math.cosh
+    libc.src.__support.math.cosh_double_eval
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.macros.attributes
+    libc.src.__support.macros.optimization
+)
+
 add_fp_unittest(
   coshf_test
   NEED_MPFR
diff --git a/libc/test/src/math/cosh_test.cpp b/libc/test/src/math/cosh_test.cpp
new file mode 100644
index 0000000000000..150528bb0e572
--- /dev/null
+++ b/libc/test/src/math/cosh_test.cpp
@@ -0,0 +1,187 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 unittests for cosh.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/fenv_macros.h"
+#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/math/cosh_double_eval.h"
+#include "src/math/cosh.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+#define TOLERANCE 1
+#else // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+#define TOLERANCE 0
+#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+#ifdef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+#define ALL_ROUNDING false
+#else
+#define ALL_ROUNDING true
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+using LIBC_NAMESPACE::testing::tlog;
+
+LIBC_NOINLINE double cosh_double_eval(double x) {
+  return LIBC_NAMESPACE::math::double_eval::cosh(x);
+}
+
+class CoshTest : public LIBC_NAMESPACE::testing::FPTest<double> {
+public:
+  void test_special_numbers(double (*func)(double)) {
+    EXPECT_FP_EQ(aNaN, func(aNaN));
+    EXPECT_FP_EQ(inf, func(inf));
+    EXPECT_FP_EQ_ALL_ROUNDING(inf, func(neg_inf));
+    EXPECT_FP_EQ_ALL_ROUNDING(1.0, func(0.0));
+    EXPECT_FP_EQ_ALL_ROUNDING(1.0, func(-0.0));
+  }
+
+  void test_overflow(double (*func)(double)) {
+    EXPECT_FP_EQ_WI...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/235181


More information about the llvm-branch-commits mailing list