Repository: llvm/llvm-project
Pull request #130588: [libc][math][c23] Add acoshf16 C23 math function.
Author: login: harrisonGPU
Labels: name: c23
name: libc
Created: 2025-03-10T12:04:53Z | Merged: 2025-03-23T02:08:34Z

Implementation of acoshf16 function for 16-bit inputs.



Diff:
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index c1e688ea7e86b..1558209055de6 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -644,6 +644,7 @@ endif()
 if(LIBC_TYPES_HAS_FLOAT16)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float16 entrypoints
+    libc.src.math.acoshf16
     libc.src.math.canonicalizef16
     libc.src.math.ceilf16
     libc.src.math.copysignf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 3cb9ee82752b3..cfb42344e7953 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -653,6 +653,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     # math.h C23 _Float16 entrypoints
     libc.src.math.asinf16
     libc.src.math.acosf16
+    libc.src.math.acoshf16
     libc.src.math.canonicalizef16
     libc.src.math.ceilf16
     libc.src.math.copysignf16
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index 5b855ce4881c3..8dc7c8c1a0966 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -251,7 +251,7 @@ Higher Math Functions
 +===========+==================+=================+========================+======================+========================+========================+============================+
 | acos      | |check|          |                 |                        | |check|              |                        | 7.12.4.1               | F.10.1.1                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| acosh     | |check|          |                 |                        |                      |                        | 7.12.5.1               | F.10.2.1                   |
+| acosh     | |check|          |                 |                        | |check|              |                        | 7.12.5.1               | F.10.2.1                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | acospi    |                  |                 |                        |                      |                        | 7.12.4.8               | F.10.1.8                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/include/math.yaml b/libc/include/math.yaml
index a66f981030864..7fd73445cc74e 100644
--- a/libc/include/math.yaml
+++ b/libc/include/math.yaml
@@ -27,6 +27,13 @@ functions:
     return_type: float
     arguments:
       - type: float
+    name: acoshf16
+    standards:
+      - stdc
+    return_type: _Float16
+    arguments:
+      - type: _Float16
+    guard: LIBC_TYPES_HAS_FLOAT16
   - name: asin
     standards:
       - stdc
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index f18a73d46f9aa..bdf8b923416d8 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -46,6 +46,7 @@ add_math_entrypoint_object(acosf16)
 
 add_math_entrypoint_object(acosh)
 add_math_entrypoint_object(acoshf)
+add_math_entrypoint_object(acoshf16)
 
 add_math_entrypoint_object(asin)
 add_math_entrypoint_object(asinf)
diff --git a/libc/src/math/acoshf16.h b/libc/src/math/acoshf16.h
new file mode 100644
index 0000000000000..f471ecfeb6154
--- /dev/null
+++ b/libc/src/math/acoshf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for acoshf16 ----------------------*- 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_SRC_MATH_ACOSHF16_H
+#define LLVM_LIBC_SRC_MATH_ACOSHF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float16 acoshf16(float16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ACOSHF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 3114289bad486..d9650f9fd6b35 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -3944,6 +3944,27 @@ add_entrypoint_object(
     libc.src.__support.macros.optimization
 )
 
+add_entrypoint_object(
+  acoshf16
+  SRCS
+    acoshf16.cpp
+  HDRS
+    ../acoshf16.h
+  DEPENDS
+    .explogxf
+    libc.hdr.errno_macros
+    libc.hdr.fenv_macros
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.FPUtil.except_value_utils
+    libc.src.__support.FPUtil.fenv_impl
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.multiply_add
+    libc.src.__support.FPUtil.polyeval
+    libc.src.__support.FPUtil.sqrt
+    libc.src.__support.macros.optimization
+    libc.src.__support.macros.properties.types 
+)
+
 add_entrypoint_object(
   asinhf
   SRCS
diff --git a/libc/src/math/generic/acoshf16.cpp b/libc/src/math/generic/acoshf16.cpp
new file mode 100644
index 0000000000000..44783a8749ac2
--- /dev/null
+++ b/libc/src/math/generic/acoshf16.cpp
@@ -0,0 +1,110 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/PolyEval.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x <= 1.0f)) {
+    if (x == 1.0f)
+      return FPBits::zero().get_val();
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf = x;
+  // High-precision polynomial approximation for inputs close to 1.0
+  // ([1, 1.25)).
+  //
+  // Brief derivation:
+  // 1. Expand acosh(1 + delta) using Taylor series around delta=0:
+  //    acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160
+  //                     - 5*delta^3/896 + 35*delta^4/18432 + ...]
+  // 2. Truncate the series to fit accurately for delta in [0, 0.25].
+  // 3. Polynomial coefficients (from sollya) used here are:
+  //    P(delta) ≈ 1 - 0x1.555556p-4 * delta + 0x1.333334p-6 * delta^2
+  //               - 0x1.6db6dcp-8 * delta^3 + 0x1.f1c71cp-10 * delta^4
+  // 4. The Sollya commands used to generate these coefficients were:
+  //      > display = hexadecimal;
+  //      > round(1/12, SG, RN);
+  //      > round(3/160, SG, RN);
+  //      > round(5/896, SG, RN);
+  //      > round(35/18432, SG, RN);
+  //      With hexadecimal display mode enabled, the outputs were:
+  //      0x1.555556p-4
+  //      0x1.333334p-6
+  //      0x1.6db6dcp-8
+  //      0x1.f1c71cp-10
+  // 5. The maximum absolute error, estimated using:
+  //      dirtyinfnorm(acosh(1 + x) - sqrt(2*x) * P(x), [0, 0.25])
+  //    is:
+  //      0x1.d84281p-22
+  if (LIBC_UNLIKELY(x_u < 0x3D00U)) {
+    float delta = xf - 1.0f;
+    float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
+    float pe = fputil::polyeval(delta, 0x1p+0f, -0x1.555556p-4f, 0x1.333334p-6f,
+                                -0x1.6db6dcp-8f, 0x1.f1c71cp-10f);
+    float approx = sqrt_2_delta * pe;
+    return fputil::cast<float16>(approx);
+  }
+
+  // acosh(x) = log(x + sqrt(x^2 - 1))
+  float sqrt_term = fputil::sqrt<float>(fputil::multiply_add(xf, xf, -1.0f));
+  float result = static_cast<float>(log_eval(xf + sqrt_term));
+
+  return fputil::cast<float16>(result);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 032050bb06ec3..5dd53de0234a7 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2173,6 +2173,17 @@ add_fp_unittest(
     libc.src.__support.FPUtil.fp_bits
 )
 
+add_fp_unittest(
+  acoshf16_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    acoshf16_test.cpp
+  DEPENDS
+    libc.src.math.acoshf16
+)
+
 add_fp_unittest(
   asinf_test
   NEED_MPFR
diff --git a/libc/test/src/math/acoshf16_test.cpp b/libc/test/src/math/acoshf16_test.cpp
new file mode 100644
index 0000000000000..7348018396bd7
--- /dev/null
+++ b/libc/test/src/math/acoshf16_test.cpp
@@ -0,0 +1,28 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+static constexpr uint16_t START = 0x3c00U;
+static constexpr uint16_t STOP = 0x7c00;
+
+TEST_F(LlvmLibcAcoshf16Test, PositiveRange) {
+  for (uint16_t v = START; v <= STOP; ++v) {
+    float16 x = FPBits(v).get_val();
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x,
+                                   LIBC_NAMESPACE::acoshf16(x), 0.5);
+  }
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index aef7c83ba0215..13cdbd6c3f8a8 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -3945,6 +3945,18 @@ add_fp_unittest(
     libc.src.__support.FPUtil.fp_bits
 )
 
+add_fp_unittest(
+  acoshf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    acoshf16_test.cpp
+  DEPENDS
+    libc.src.errno.errno
+    libc.src.math.acoshf16
+    libc.src.__support.FPUtil.cast
+)
+
 add_fp_unittest(
   asinf_test
   SUITE
diff --git a/libc/test/src/math/smoke/acoshf16_test.cpp b/libc/test/src/math/smoke/acoshf16_test.cpp
new file mode 100644
index 0000000000000..7681c2a4e7fbc
--- /dev/null
+++ b/libc/test/src/math/smoke/acoshf16_test.cpp
@@ -0,0 +1,70 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(zero), FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero),
+                              FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf),
+                              FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(zero, LIBC_NAMESPACE::acoshf16(
+                         LIBC_NAMESPACE::fputil::cast<float16>(1.0)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(
+                         LIBC_NAMESPACE::fputil::cast<float16>(0.5)));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(
+      aNaN,
+      LIBC_NAMESPACE::acoshf16(LIBC_NAMESPACE::fputil::cast<float16>(-1.0)),
+      FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(
+      aNaN,
+      LIBC_NAMESPACE::acoshf16(LIBC_NAMESPACE::fputil::cast<float16>(-2.0)),
+      FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(
+      aNaN,
+      LIBC_NAMESPACE::acoshf16(LIBC_NAMESPACE::fputil::cast<float16>(-3.0)),
+      FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+}


Reviews:
user: login: overmighty
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-03-11T10:04:12Z
user: login: overmighty
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T10:07:21Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:21:19Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:21:27Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:21:33Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:21:39Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:21:52Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:36:00Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:36:09Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:36:22Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:36:32Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:36:39Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:36:48Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:36:56Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T12:48:00Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T13:39:11Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T13:40:54Z
user: login: overmighty
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-11T23:30:11Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-12T04:47:14Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-13T12:55:32Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-14T14:35:00Z
user: login: lntue
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T14:39:38Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-14T15:16:19Z
user: login: overmighty
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-16T16:54:57Z
user: login: overmighty
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-16T16:55:19Z
user: login: overmighty
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-03-16T17:27:49Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:03:43Z
user: login: jhuber6
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T16:05:11Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:05:45Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:05:57Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:06:05Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:06:12Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:07:12Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:08:04Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:08:14Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:08:23Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:08:31Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:11:32Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:12:59Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:19:51Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:25:55Z
user: login: overmighty
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:49:35Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-17T16:54:02Z
user: login: overmighty
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-03-17T18:34:02Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T13:49:45Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T13:52:38Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T14:20:31Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T14:21:00Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T14:21:09Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T14:21:16Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T14:22:17Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T14:29:36Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T16:15:09Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T16:17:15Z
user: login: overmighty
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T17:09:13Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-19T01:31:11Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-19T01:40:31Z
user: login: lntue
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T14:16:44Z
user: login: lntue
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T14:19:01Z
user: login: lntue
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T14:22:14Z
user: login: lntue
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T14:22:57Z
user: login: lntue
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T14:23:42Z
user: login: lntue
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T14:24:25Z
user: login: lntue
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T14:38:01Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T16:37:40Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T16:37:52Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T16:38:25Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T16:38:32Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T16:38:41Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T16:39:03Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T16:39:14Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-21T02:45:55Z
user: login: lntue
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T03:11:09Z
user: login: lntue
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T15:51:44Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-22T10:09:18Z
user: login: lntue
body: LGTM.  Please wait to see if @overmighty has any other comments.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-22T14:32:59Z
user: login: overmighty
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-03-22T15:39:26Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-22T16:03:30Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-22T16:03:56Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-22T16:04:28Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-22T16:04:52Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-22T16:05:12Z
user: login: harrisonGPU
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-22T16:29:39Z
user: login: overmighty
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-22T18:20:18Z

Review comments:
diff_hunk: @@ -0,0 +1,21 @@
+//===-- Implementation header for acoshf16 -----------------------*- C++ -*-===//
path: libc/src/math/acoshf16.h
user: login: overmighty
body: Nit: column limit.

```suggestion
//===-- Implementation header for acoshf16 ----------------------*- C++ -*-===//
```

You can use https://github.com/overmighty/llvm-dev-utils/blob/master/llvm_libc_add_math_function.py to generate some of the boilerplate for new math functions.
created_at: 2025-03-11T09:40:56Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 function -----------------------------------===//
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Nit: column limit.

```suggestion
//===-- Half-precision acoshf16 function ----------------------------------===//
```
created_at: 2025-03-11T09:41:33Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: ```suggestion
      fputil::raise_except_if_required(FE_INVALID);
```
created_at: 2025-03-11T09:43:13Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: ```suggestion
      fputil::raise_except_if_required(FE_INVALID);
```
created_at: 2025-03-11T09:43:22Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: ```suggestion
    fputil::raise_except_if_required(FE_INVALID);
```
created_at: 2025-03-11T09:43:39Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(xbits.uintval() == 0x3c00U))
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: - You can reuse `x_u` instead of using `xbits.uintval()`.
- Nit: inconsistent use of `U` literal suffix.
created_at: 2025-03-11T09:45:10Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(xbits.uintval() == 0x3c00U))
+    return float16(0.0f);
+
+  float xf32 = static_cast<float>(x);
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Nit: unnecessary `static_cast`.
created_at: 2025-03-11T09:45:46Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(xbits.uintval() == 0x3c00U))
+    return float16(0.0f);
+
+  float xf32 = static_cast<float>(x);
+
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2 = fputil::sqrt<float>(2.0f * delta);
+    float sqrt_2d = fputil::sqrt<float>(2.0f * delta);
+    float d32 = delta * fputil::sqrt<float>(delta);
+    float term2 = d32 / (6.0f * fputil::sqrt<float>(2.0f));
+    float d52 = d32 * delta;
+    float term3 = 3.0f * d52 / (80.0f * sqrt_2);
+    float d72 = d52 * delta;
+    float term4 = 5.0f * d72 / (1792.0f * sqrt_2);
+    float result = sqrt_2d - term2 + term3 - term4;
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: How did you arrive at this algorithm?
created_at: 2025-03-11T09:47:42Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(xbits.uintval() == 0x3c00U))
+    return float16(0.0f);
+
+  float xf32 = static_cast<float>(x);
+
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2 = fputil::sqrt<float>(2.0f * delta);
+    float sqrt_2d = fputil::sqrt<float>(2.0f * delta);
+    float d32 = delta * fputil::sqrt<float>(delta);
+    float term2 = d32 / (6.0f * fputil::sqrt<float>(2.0f));
+    float d52 = d32 * delta;
+    float term3 = 3.0f * d52 / (80.0f * sqrt_2);
+    float d72 = d52 * delta;
+    float term4 = 5.0f * d72 / (1792.0f * sqrt_2);
+    float result = sqrt_2d - term2 + term3 - term4;
+    return fputil::cast<float16>(result);
+  }
+
+  // Special optimization for large input values.
+  if (LIBC_UNLIKELY(xf32 >= 32.0f)) {
+    float result = static_cast<float>(log_eval(2.0f * xf32));
+    return fputil::cast<float16>(result);
+  }
+
+  // Standard computation for general case.
+  float sqrt_term = fputil::sqrt<float>(fputil::multiply_add(xf32, xf32, -1.0f));
+  float result = static_cast<float>(log_eval(xf32 + sqrt_term));
+
+  return fputil::cast<float16>(result);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Nit: missing final newline, as shown by GitHub with the red icon.
created_at: 2025-03-11T09:50:57Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,82 @@
+//===-- Unittests for acoshf16 ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(float16(0.0f),
+                            LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAcoshf16Test, InFloat16Range) {
+  constexpr uint32_t COUNT = 100'000;
path: libc/test/src/math/acoshf16_test.cpp
user: login: overmighty
body: There aren't 100k possible `float16` values. For `float16`, the MPFR unit tests we write are just exhaustive tests. See libc/test/src/math/expf16_test.cpp for an example of what this test file should look like.
created_at: 2025-03-11T09:55:59Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(zero));
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: overmighty
body: We should probably also check that the `FE_INVALID` exception is raised here. Same for the other test cases below that should also raise that exception.
created_at: 2025-03-11T09:59:24Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(float16(0.0f), LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
+}
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: overmighty
body: Nit: missing final newline.
created_at: 2025-03-11T10:00:38Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,82 @@
+//===-- Unittests for acoshf16 ----------------------------------------------===//
path: libc/test/src/math/acoshf16_test.cpp
user: login: overmighty
body: Nit: column limit.

```suggestion
//===-- Unittests for acoshf16 --------------------------------------------===//
```
created_at: 2025-03-11T10:01:17Z
author_association: MEMBER
diff_hunk: @@ -3944,6 +3944,28 @@ add_entrypoint_object(
     libc.src.__support.macros.optimization
 )
 
+add_entrypoint_object(
+  acoshf16
+  SRCS
+    acoshf16.cpp
+  HDRS
+    ../acoshf16.h
+  DEPENDS
+    .common_constants
+    .explogxf
+    libc.hdr.errno_macros
+    libc.hdr.fenv_macros
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.FPUtil.except_value_utils
path: libc/src/math/generic/CMakeLists.txt
user: login: overmighty
body: `except_value_utils` is currently unused.
created_at: 2025-03-11T10:02:36Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,82 @@
+//===-- Unittests for acoshf16 ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(float16(0.0f),
+                            LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAcoshf16Test, InFloat16Range) {
+  constexpr uint32_t COUNT = 100'000;
+  constexpr uint32_t STEP = UINT32_MAX / COUNT;
+
+  for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+    LIBC_NAMESPACE::fputil::FPBits<float> bits(v);
+    float xf32 = bits.get_val();
+    if (bits.is_nan() || bits.is_inf())
+      continue;
+    if (xf32 < 1.0f)
+      continue;
+    float16 xh = LIBC_NAMESPACE::fputil::cast<float16>(xf32);
+
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, xh,
+                                   LIBC_NAMESPACE::acoshf16(xh), 3.0);
path: libc/test/src/math/acoshf16_test.cpp
user: login: overmighty
body: Also, to answer your question, setting the ULP tolerance to 3.0 is indeed not right. It needs to be 0.5 to check for correct rounding.
created_at: 2025-03-11T10:07:21Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,21 @@
+//===-- Implementation header for acoshf16 -----------------------*- C++ -*-===//
path: libc/src/math/acoshf16.h
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:21:19Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 function -----------------------------------===//
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:21:27Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:21:33Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:21:39Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:21:52Z
author_association: MEMBER
diff_hunk: @@ -3944,6 +3944,28 @@ add_entrypoint_object(
     libc.src.__support.macros.optimization
 )
 
+add_entrypoint_object(
+  acoshf16
+  SRCS
+    acoshf16.cpp
+  HDRS
+    ../acoshf16.h
+  DEPENDS
+    .common_constants
+    .explogxf
+    libc.hdr.errno_macros
+    libc.hdr.fenv_macros
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.FPUtil.except_value_utils
path: libc/src/math/generic/CMakeLists.txt
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:36:00Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,82 @@
+//===-- Unittests for acoshf16 ----------------------------------------------===//
path: libc/test/src/math/acoshf16_test.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:36:09Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(float16(0.0f), LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
+}
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:36:22Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,82 @@
+//===-- Unittests for acoshf16 ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(float16(0.0f),
+                            LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAcoshf16Test, InFloat16Range) {
+  constexpr uint32_t COUNT = 100'000;
path: libc/test/src/math/acoshf16_test.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:36:32Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(xbits.uintval() == 0x3c00U))
+    return float16(0.0f);
+
+  float xf32 = static_cast<float>(x);
+
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2 = fputil::sqrt<float>(2.0f * delta);
+    float sqrt_2d = fputil::sqrt<float>(2.0f * delta);
+    float d32 = delta * fputil::sqrt<float>(delta);
+    float term2 = d32 / (6.0f * fputil::sqrt<float>(2.0f));
+    float d52 = d32 * delta;
+    float term3 = 3.0f * d52 / (80.0f * sqrt_2);
+    float d72 = d52 * delta;
+    float term4 = 5.0f * d72 / (1792.0f * sqrt_2);
+    float result = sqrt_2d - term2 + term3 - term4;
+    return fputil::cast<float16>(result);
+  }
+
+  // Special optimization for large input values.
+  if (LIBC_UNLIKELY(xf32 >= 32.0f)) {
+    float result = static_cast<float>(log_eval(2.0f * xf32));
+    return fputil::cast<float16>(result);
+  }
+
+  // Standard computation for general case.
+  float sqrt_term = fputil::sqrt<float>(fputil::multiply_add(xf32, xf32, -1.0f));
+  float result = static_cast<float>(log_eval(xf32 + sqrt_term));
+
+  return fputil::cast<float16>(result);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:36:39Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(xbits.uintval() == 0x3c00U))
+    return float16(0.0f);
+
+  float xf32 = static_cast<float>(x);
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:36:48Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(xbits.uintval() == 0x3c00U))
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-11T12:36:56Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(xbits.uintval() == 0x3c00U))
+    return float16(0.0f);
+
+  float xf32 = static_cast<float>(x);
+
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2 = fputil::sqrt<float>(2.0f * delta);
+    float sqrt_2d = fputil::sqrt<float>(2.0f * delta);
+    float d32 = delta * fputil::sqrt<float>(delta);
+    float term2 = d32 / (6.0f * fputil::sqrt<float>(2.0f));
+    float d52 = d32 * delta;
+    float term3 = 3.0f * d52 / (80.0f * sqrt_2);
+    float d72 = d52 * delta;
+    float term4 = 5.0f * d72 / (1792.0f * sqrt_2);
+    float result = sqrt_2d - term2 + term3 - term4;
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: I used a 5th-order Taylor series expansion to calculate acoshf.
I'm currently trying to reduce precision errors, but it doesn't seem to work.

created_at: 2025-03-11T12:48:00Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,82 @@
+//===-- Unittests for acoshf16 ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(float16(0.0f),
+                            LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAcoshf16Test, InFloat16Range) {
+  constexpr uint32_t COUNT = 100'000;
+  constexpr uint32_t STEP = UINT32_MAX / COUNT;
+
+  for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+    LIBC_NAMESPACE::fputil::FPBits<float> bits(v);
+    float xf32 = bits.get_val();
+    if (bits.is_nan() || bits.is_inf())
+      continue;
+    if (xf32 < 1.0f)
+      continue;
+    float16 xh = LIBC_NAMESPACE::fputil::cast<float16>(xf32);
+
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, xh,
+                                   LIBC_NAMESPACE::acoshf16(xh), 3.0);
path: libc/test/src/math/acoshf16_test.cpp
user: login: harrisonGPU
body: Thanks Nicolas, I will try to explore it. :-)
created_at: 2025-03-11T13:39:11Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(zero));
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: harrisonGPU
body: Do you mean change `EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(zero));` to `EXPECT_FP_EQ_WITH_EXCEPTION` ?
created_at: 2025-03-11T13:40:54Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(xbits.uintval() == 0x3c00U))
+    return float16(0.0f);
+
+  float xf32 = static_cast<float>(x);
+
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2 = fputil::sqrt<float>(2.0f * delta);
+    float sqrt_2d = fputil::sqrt<float>(2.0f * delta);
+    float d32 = delta * fputil::sqrt<float>(delta);
+    float term2 = d32 / (6.0f * fputil::sqrt<float>(2.0f));
+    float d52 = d32 * delta;
+    float term3 = 3.0f * d52 / (80.0f * sqrt_2);
+    float d72 = d52 * delta;
+    float term4 = 5.0f * d72 / (1792.0f * sqrt_2);
+    float result = sqrt_2d - term2 + term3 - term4;
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: We often use minimax polynomial approximations. Search for `fpminimax` in other files in libc/src/math/generic/ for examples of Sollya commands to generate some.

You can read about these in *Handbook of Floating-Point Arithmetic* by the way.
created_at: 2025-03-11T23:30:11Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,98 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/common_constants.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+//   if (LIBC_UNLIKELY(x <= 1.0f)) {
+//     if (x == 1.0f)
+//       return 0.0f;
+//     // x < 1.
+//     fputil::set_errno_if_required(EDOM);
+//     fputil::raise_except_if_required(FE_INVALID);
+//     return FPBits::quiet_nan().get_val();
+//   }
+  
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(xbits.uintval() == 0x3c00U))
+    return float16(0.0f);
+
+  float xf32 = static_cast<float>(x);
+
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2 = fputil::sqrt<float>(2.0f * delta);
+    float sqrt_2d = fputil::sqrt<float>(2.0f * delta);
+    float d32 = delta * fputil::sqrt<float>(delta);
+    float term2 = d32 / (6.0f * fputil::sqrt<float>(2.0f));
+    float d52 = d32 * delta;
+    float term3 = 3.0f * d52 / (80.0f * sqrt_2);
+    float d72 = d52 * delta;
+    float term4 = 5.0f * d72 / (1792.0f * sqrt_2);
+    float result = sqrt_2d - term2 + term3 - term4;
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Thanks, Nicolas, I will consider it.
created_at: 2025-03-12T04:47:14Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,82 @@
+//===-- Unittests for acoshf16 ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(float16(0.0f),
+                            LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAcoshf16Test, InFloat16Range) {
+  constexpr uint32_t COUNT = 100'000;
+  constexpr uint32_t STEP = UINT32_MAX / COUNT;
+
+  for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+    LIBC_NAMESPACE::fputil::FPBits<float> bits(v);
+    float xf32 = bits.get_val();
+    if (bits.is_nan() || bits.is_inf())
+      continue;
+    if (xf32 < 1.0f)
+      continue;
+    float16 xh = LIBC_NAMESPACE::fputil::cast<float16>(xf32);
+
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, xh,
+                                   LIBC_NAMESPACE::acoshf16(xh), 3.0);
path: libc/test/src/math/acoshf16_test.cpp
user: login: harrisonGPU
body: Now I have already changed to 0.5 ULP.
created_at: 2025-03-13T12:55:32Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(zero));
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: harrisonGPU
body: Ping @overmighty 
created_at: 2025-03-14T14:35:00Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
+    float x2 = delta;
+    float pe = fputil::polyeval(x2, 0x1.0000000000000p+0f,
+                                -0x1.55551a83a9472p-4f, 0x1.331601c4b8ecfp-6f,
+                                -0x1.6890f49eb0acbp-8f, 0x1.8f3a617040a6ap-10f);
path: libc/src/math/generic/acoshf16.cpp
user: login: lntue
body: nit: these constants are printed with much higher precision than float.
created_at: 2025-03-14T14:39:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
+    float x2 = delta;
+    float pe = fputil::polyeval(x2, 0x1.0000000000000p+0f,
+                                -0x1.55551a83a9472p-4f, 0x1.331601c4b8ecfp-6f,
+                                -0x1.6890f49eb0acbp-8f, 0x1.8f3a617040a6ap-10f);
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Okay, I have updated it. Please review again.
created_at: 2025-03-14T15:16:19Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,82 @@
+//===-- Unittests for acoshf16 ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(float16(0.0f),
+                            LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAcoshf16Test, InFloat16Range) {
+  constexpr uint32_t COUNT = 100'000;
path: libc/test/src/math/acoshf16_test.cpp
user: login: overmighty
body: The `SpecialNumbers` test should only be in the smoke test, and there's no need for the `SpecificBitPatterns` test since there's the `PositiveRange` exhaustive test. You can just copy the MPFR unit test for another `float16` function such as libc/test/src/math/expf16_test.cpp, delete the `NegativeRange` test and negative range constants, adjust `POS_START`, and replace occurrences of `exp`/`Exp` with `acosh`/`Acosh`.
created_at: 2025-03-16T16:54:57Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(zero));
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: overmighty
body: Yes.
created_at: 2025-03-16T16:55:19Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Nit: this formatting is not great.

```suggestion
static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
    // (input, RZ output, RU offset, RD offset, RN offset)
    {0x41B7, 0x3ED8, 1, 0, 0},
    {0x3CE4, 0x393E, 1, 0, 1},
}};
```

It would also be nice to add a comment for each value. For example, in expf16.cpp we have:

```cpp
static constexpr fputil::ExceptValues<float16, 2> EXPF16_EXCEPTS_LO = {{
    // (input, RZ output, RU offset, RD offset, RN offset)
    // x = 0x1.de4p-8, expf16(x) = 0x1.01cp+0 (RZ)
    {0x1f79U, 0x3c07U, 1U, 0U, 0U},
    // x = 0x1.73cp-6, expf16(x) = 0x1.05cp+0 (RZ)
    {0x25cfU, 0x3c17U, 1U, 0U, 0U},
}};
```
created_at: 2025-03-16T17:02:18Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Nit: I don't think this use of function-style casts is common across the LLVM libc codebase. I think we mostly use them when dealing with type template parameters.

```suggestion
    return FPBits::zero().get_val();;
```
created_at: 2025-03-16T17:07:28Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Nit: for consistency with the other function implementations:

```suggestion
  float xf = x;
```
created_at: 2025-03-16T17:08:26Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Is 1.25f the exact upper bound?
created_at: 2025-03-16T17:09:43Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
+    float x2 = delta;
+    float pe =
+        fputil::polyeval(x2, 0x1.000000p+0f, -0x1.55551ap-4f, 0x1.33160cp-6f,
+                         -0x1.6890f4p-8f, 0x1.8f3a62p-10f);
+    float approx = sqrt_2_delta * pe;
+    return fputil::cast<float16>(approx);
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Could you add comments to explain your algorithm/give your formula and give the Sollya commands you used to generate this polynomial?

I don't see the point of the `x2` variable. Also, for the first coefficient, you can just write `0x1p+0f`.
created_at: 2025-03-16T17:13:42Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
+    float x2 = delta;
+    float pe =
+        fputil::polyeval(x2, 0x1.000000p+0f, -0x1.55551ap-4f, 0x1.33160cp-6f,
+                         -0x1.6890f4p-8f, 0x1.8f3a62p-10f);
+    float approx = sqrt_2_delta * pe;
+    return fputil::cast<float16>(approx);
+  }
+
+  // Standard computation for general case.
+  float sqrt_term =
+      fputil::sqrt<float>(fputil::multiply_add(xf32, xf32, -1.0f));
+  float result = static_cast<float>(log_eval(xf32 + sqrt_term));
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: A comment here might be nice too. You can just copy the one in acoshf.cpp (`// acosh(x) = log(x + sqrt(x^2 - 1))`).
created_at: 2025-03-16T17:19:08Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Should probably use this header instead, so that the architecture-specific optimized `sqrt<float>` implementations can be used. You already wrote `libc.src.__support.FPUtil.sqrt` instead of `libc.src.__support.FPUtil.generic.sqrt` in the CMakeLists.txt btw.  

```suggestion
#include "src/__support/FPUtil/sqrt.h"
```
created_at: 2025-03-16T17:23:15Z
author_association: MEMBER
diff_hunk: @@ -3944,6 +3944,27 @@ add_entrypoint_object(
     libc.src.__support.macros.optimization
 )
 
+add_entrypoint_object(
+  acoshf16
+  SRCS
+    acoshf16.cpp
+  HDRS
+    ../acoshf16.h
+  DEPENDS
+    .common_constants
path: libc/src/math/generic/CMakeLists.txt
user: login: overmighty
body: Unused dependency.

```suggestion
```
created_at: 2025-03-16T17:25:51Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: ```suggestion
#include "src/math/acoshf16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
```
created_at: 2025-03-16T17:27:00Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Good catch! 1.25f isn't a strict upper bound—it's more of an empirical choice. Beyond this point, the normal calculation works just fine, but we can always tweak it if needed. :-)
created_at: 2025-03-17T16:03:42Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
path: libc/src/math/generic/acoshf16.cpp
user: login: jhuber6
body: ChatGPT?
created_at: 2025-03-17T16:05:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(zero));
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-17T16:05:45Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-17T16:05:57Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-17T16:06:05Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-17T16:06:12Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: I just set 1.25, it is not strict upper bound
created_at: 2025-03-17T16:07:11Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
+    float x2 = delta;
+    float pe =
+        fputil::polyeval(x2, 0x1.000000p+0f, -0x1.55551ap-4f, 0x1.33160cp-6f,
+                         -0x1.6890f4p-8f, 0x1.8f3a62p-10f);
+    float approx = sqrt_2_delta * pe;
+    return fputil::cast<float16>(approx);
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-17T16:08:04Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
+    float x2 = delta;
+    float pe =
+        fputil::polyeval(x2, 0x1.000000p+0f, -0x1.55551ap-4f, 0x1.33160cp-6f,
+                         -0x1.6890f4p-8f, 0x1.8f3a62p-10f);
+    float approx = sqrt_2_delta * pe;
+    return fputil::cast<float16>(approx);
+  }
+
+  // Standard computation for general case.
+  float sqrt_term =
+      fputil::sqrt<float>(fputil::multiply_add(xf32, xf32, -1.0f));
+  float result = static_cast<float>(log_eval(xf32 + sqrt_term));
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-17T16:08:14Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-17T16:08:23Z
author_association: MEMBER
diff_hunk: @@ -3944,6 +3944,27 @@ add_entrypoint_object(
     libc.src.__support.macros.optimization
 )
 
+add_entrypoint_object(
+  acoshf16
+  SRCS
+    acoshf16.cpp
+  HDRS
+    ../acoshf16.h
+  DEPENDS
+    .common_constants
path: libc/src/math/generic/CMakeLists.txt
user: login: harrisonGPU
body: Done.
created_at: 2025-03-17T16:08:31Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
+    float x2 = delta;
+    float pe =
+        fputil::polyeval(x2, 0x1.000000p+0f, -0x1.55551ap-4f, 0x1.33160cp-6f,
+                         -0x1.6890f4p-8f, 0x1.8f3a62p-10f);
+    float approx = sqrt_2_delta * pe;
+    return fputil::cast<float16>(approx);
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: I didn't use Sollya; I wrote a Python script to calculate the Taylor expansion coefficients.
created_at: 2025-03-17T16:11:32Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: I have added these header files, but they are not used, right?
created_at: 2025-03-17T16:12:58Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: > ChatGPT?

Yes, I used chatgpt to check my English grammer, I am worry about I said is not right. :-)
But I just set 1.25, it is not strict upper bound
created_at: 2025-03-17T16:19:50Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,82 @@
+//===-- Unittests for acoshf16 ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(float16(0.0f),
+                            LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAcoshf16Test, InFloat16Range) {
+  constexpr uint32_t COUNT = 100'000;
path: libc/test/src/math/acoshf16_test.cpp
user: login: harrisonGPU
body: Okay, I just noticed `acoshf_test.cpp` do same tests. :-)
created_at: 2025-03-17T16:25:55Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: They provide `EDOM` and `FE_INVALID` respectively.
created_at: 2025-03-17T16:49:35Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Okay, thanks, I got it, please review again. :-)
created_at: 2025-03-17T16:54:02Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,120 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Nit: we usually use relative paths when the included header is in the same directory.

```suggestion
#include "explogxf.h"
```
created_at: 2025-03-17T17:07:37Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,120 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6ep+1, acoshf16(x) = 0x1.dbp+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.c8p+0, acoshf16(x) = 0x1.27cp-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: These comments are wrong.

```suggestion
    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
    {0x41b7U, 0x3ed8U, 1, 0, 0},
    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
    {0x3ce4U, 0x393eU, 1, 0, 1},
```
created_at: 2025-03-17T17:15:12Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,120 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6ep+1, acoshf16(x) = 0x1.dbp+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.c8p+0, acoshf16(x) = 0x1.27cp-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return FPBits::zero().get_val();
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf = x;
+  // High precision polynomial approximation for inputs very close to 1.0
+  // Specifically, for inputs within the range [1, 1.25), we employ the
+  // following step-by-step Taylor expansion derivation to maintain numerical
+  // accuracy:
+  //
+  // Step-by-step derivation:
+  // 1. Define y = acosh(x), thus by definition x = cosh(y).
+  //
+  // 2. Expand cosh(y) using exponential identities:
+  //      cosh(y) = (e^y + e^{-y}) / 2
+  //      For small y, let us set y ≈ sqrt(2 * delta), thus:
+  //      x ≈ cosh(y) ≈ 1 + delta, for small delta
+  //      hence delta = x - 1.
+  //
+  // 3. Express y explicitly in terms of delta (for small delta):
+  //      y = acosh(1 + delta) ≈ sqrt(2 * delta) for very small delta.
+  //
+  // 4. Use Taylor expansion around delta = 0 to obtain a more accurate
+  // polynomial:
+  //      acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160 -
+  //      5*delta^3/896 + 35*delta^4/18432 + ...] For practical computation and
+  //      precision, truncate and fit the polynomial precisely in the range [0,
+  //      0.25].
+  //
+  // 5. The implemented polynomial approximation (coefficients obtained from
+  // careful numerical fitting) is:
+  //      P(delta) ≈ 1 - 0x1.55551ap-4 * delta + 0x1.33160cp-6 * delta^2 -
+  //      0x1.6890f4p-8 * delta^3 + 0x1.8f3a62p-10 * delta^4
+  //
+  // Since delta = x - 1, and 0 <= delta < 0.25, this approximation achieves
+  // high precision and numerical stability.
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Was this generated by an LLM?

>  (coefficients obtained from careful numerical fitting)

I don't understand this. This is what I get when I round the coefficients myself:

```
~ ➜ sollya
> display = hexadecimal;
round(1/12, SG, RN);
round(3/160, SG, RN);
round(5/896, SG, RN);
round(35/18432, SG, RN);
Display mode is hexadecimal numbers.
> 0x1.555556p-4
> 0x1.333334p-6
> 0x1.6db6dcp-8
> 0x1.f1c71cp-10
>
```
created_at: 2025-03-17T17:17:53Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,29 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+static constexpr uint16_t START = 0x3c00U;
+static constexpr uint16_t STOP = 0x7bffU;
path: libc/test/src/math/acoshf16_test.cpp
user: login: overmighty
body: Why 0x7bffU instead of 0x7c00U? `acoshf16` is defined for +infinity.
created_at: 2025-03-17T18:10:34Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(zero), FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: overmighty
body: You can also check for `FE_INVALID` with `acoshf16(neg_zero)` and `acoshf16(neg_inf)`.
created_at: 2025-03-17T18:11:36Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(zero), FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(float16(0.0f), LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: overmighty
body: Maybe it would be better to use `fputil::cast<float16>(...)` here instead of a function-style cast (`float16(...)`). I don't remember if we somehow also had issues when casting constants, but it probably wouldn't hurt to stick to `fputil::cast` for consistency at least.  Remember to include `"src/__support/FPUtil/cast.h"` and update CMakeLists.txt. For `float16(0.0f)` you can just use `zero` instead.
created_at: 2025-03-17T18:17:09Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,29 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
path: libc/test/src/math/acoshf16_test.cpp
user: login: overmighty
body: The `FPBits` used below is actually a `using` that comes from `FPTest`, so we can just rely on FPMatcher.h. cast.h is just unused. We should probably still directly include Test.h since we directly use `TEST_F`.

```suggestion
#include "src/errno/libc_errno.h"
#include "src/math/acoshf16.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
#include <stdint.h>
```
created_at: 2025-03-17T18:24:21Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,120 @@
+//===-- Half-precision acoshf16 function ----------------------------------===//
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Nit:

```suggestion
//===-- Half-precision acosh(x) function ----------------------------------===//
```
created_at: 2025-03-17T18:26:01Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,29 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+static constexpr uint16_t START = 0x3c00U;
+static constexpr uint16_t STOP = 0x7bffU;
path: libc/test/src/math/acoshf16_test.cpp
user: login: harrisonGPU
body: I know 0x7c00 is +inf, but I searched IEEE-754 half-precision the max value is 65,504(0x7bffU).
created_at: 2025-03-18T13:49:44Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,120 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6ep+1, acoshf16(x) = 0x1.dbp+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.c8p+0, acoshf16(x) = 0x1.27cp-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: How can you calculate it? I really want to know?
created_at: 2025-03-18T13:52:38Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,120 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6ep+1, acoshf16(x) = 0x1.dbp+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.c8p+0, acoshf16(x) = 0x1.27cp-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return FPBits::zero().get_val();
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf = x;
+  // High precision polynomial approximation for inputs very close to 1.0
+  // Specifically, for inputs within the range [1, 1.25), we employ the
+  // following step-by-step Taylor expansion derivation to maintain numerical
+  // accuracy:
+  //
+  // Step-by-step derivation:
+  // 1. Define y = acosh(x), thus by definition x = cosh(y).
+  //
+  // 2. Expand cosh(y) using exponential identities:
+  //      cosh(y) = (e^y + e^{-y}) / 2
+  //      For small y, let us set y ≈ sqrt(2 * delta), thus:
+  //      x ≈ cosh(y) ≈ 1 + delta, for small delta
+  //      hence delta = x - 1.
+  //
+  // 3. Express y explicitly in terms of delta (for small delta):
+  //      y = acosh(1 + delta) ≈ sqrt(2 * delta) for very small delta.
+  //
+  // 4. Use Taylor expansion around delta = 0 to obtain a more accurate
+  // polynomial:
+  //      acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160 -
+  //      5*delta^3/896 + 35*delta^4/18432 + ...] For practical computation and
+  //      precision, truncate and fit the polynomial precisely in the range [0,
+  //      0.25].
+  //
+  // 5. The implemented polynomial approximation (coefficients obtained from
+  // careful numerical fitting) is:
+  //      P(delta) ≈ 1 - 0x1.55551ap-4 * delta + 0x1.33160cp-6 * delta^2 -
+  //      0x1.6890f4p-8 * delta^3 + 0x1.8f3a62p-10 * delta^4
+  //
+  // Since delta = x - 1, and 0 <= delta < 0.25, this approximation achieves
+  // high precision and numerical stability.
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: I used a Python script to compute the floating-point coefficients and then converted them into hexadecimal (0x) format. I did not use Sollya (before this patch, I had never used Sollya). I have updated it, please review again.
created_at: 2025-03-18T14:20:31Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(zero), FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(float16(0.0f), LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-18T14:21:00Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,29 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
path: libc/test/src/math/acoshf16_test.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-18T14:21:09Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,120 @@
+//===-- Half-precision acoshf16 function ----------------------------------===//
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.

created_at: 2025-03-18T14:21:16Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,120 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-18T14:22:17Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(zero), FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: harrisonGPU
body: I have added these tests, please review again.
created_at: 2025-03-18T14:29:36Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,29 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+static constexpr uint16_t START = 0x3c00U;
+static constexpr uint16_t STOP = 0x7bffU;
path: libc/test/src/math/acoshf16_test.cpp
user: login: harrisonGPU
body: Sorry, I think you're right, I was wrong.
created_at: 2025-03-18T16:15:08Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,29 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+static constexpr uint16_t START = 0x3c00U;
+static constexpr uint16_t STOP = 0x7bffU;
path: libc/test/src/math/acoshf16_test.cpp
user: login: harrisonGPU
body: I have updated it. Thanks.
created_at: 2025-03-18T16:17:15Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,120 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6ep+1, acoshf16(x) = 0x1.dbp+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.c8p+0, acoshf16(x) = 0x1.27cp-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: You can use this website: https://float.exposed/0x41b7.

I have also written Zsh functions to generate a C++ source file that does a bitcast and calls `printf`, compile it with Clang, and run it.
created_at: 2025-03-18T17:09:13Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,120 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6ep+1, acoshf16(x) = 0x1.dbp+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.c8p+0, acoshf16(x) = 0x1.27cp-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Okay, thanks
created_at: 2025-03-19T01:31:11Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,120 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6ep+1, acoshf16(x) = 0x1.dbp+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.c8p+0, acoshf16(x) = 0x1.27cp-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: I have updated it.
created_at: 2025-03-19T01:40:31Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,102 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return FPBits::zero().get_val();
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf = x;
+  // High-precision polynomial approximation for inputs close to 1.0
+  // ([1, 1.25)).
+  //
+  // Brief derivation:
+  // 1. Start from the definition: acosh(x) = y means x = cosh(y).
+  // 2. Set x = 1 + delta. For small delta, y ≈ sqrt(2 * delta).
path: libc/src/math/generic/acoshf16.cpp
user: login: lntue
body: Point 1 and 2 can be removed
created_at: 2025-03-20T14:16:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,102 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return FPBits::zero().get_val();
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf = x;
+  // High-precision polynomial approximation for inputs close to 1.0
+  // ([1, 1.25)).
+  //
+  // Brief derivation:
+  // 1. Start from the definition: acosh(x) = y means x = cosh(y).
+  // 2. Set x = 1 + delta. For small delta, y ≈ sqrt(2 * delta).
+  // 3. Expand acosh(1 + delta) using Taylor series around delta=0:
+  //    acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160
+  //                     - 5*delta^3/896 + 35*delta^4/18432 + ...]
+  // 4. Truncate the series to fit accurately for delta in [0, 0.25].
+  // 5. Polynomial coefficients (from sollya) used here are:
path: libc/src/math/generic/acoshf16.cpp
user: login: lntue
body: Can you add to the comment the Sollya command that you used to generate the polynomial?  Also add Sollya estimation for the errors, with something like:
```
> dirtyinfnorm(acosh(1 + x) - sqrt(2*x) * P(x), [0, 0.25]);
```
created_at: 2025-03-20T14:19:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,102 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
path: libc/src/math/generic/acoshf16.cpp
user: login: lntue
body: Domain errors for all `x < 1.0`, not just `|x| < 1.0`.
created_at: 2025-03-20T14:22:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,102 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
path: libc/src/math/generic/acoshf16.cpp
user: login: lntue
body: Combine inf and nan cases into 1 outer `if` check.
created_at: 2025-03-20T14:22:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,102 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return FPBits::zero().get_val();
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf = x;
+  // High-precision polynomial approximation for inputs close to 1.0
+  // ([1, 1.25)).
+  //
+  // Brief derivation:
+  // 1. Start from the definition: acosh(x) = y means x = cosh(y).
+  // 2. Set x = 1 + delta. For small delta, y ≈ sqrt(2 * delta).
+  // 3. Expand acosh(1 + delta) using Taylor series around delta=0:
+  //    acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160
+  //                     - 5*delta^3/896 + 35*delta^4/18432 + ...]
+  // 4. Truncate the series to fit accurately for delta in [0, 0.25].
+  // 5. Polynomial coefficients (from sollya) used here are:
+  //    P(delta) ≈ 1 - 0x1.555556p-4 * delta + 0x1.333334p-6 * delta^2
+  //               - 0x1.6db6dcp-8 * delta^3 + 0x1.f1c71cp-10 * delta^4
+  if (LIBC_UNLIKELY(xf < 1.25f)) {
path: libc/src/math/generic/acoshf16.cpp
user: login: lntue
body: You can change this condition to use the bit pattern of `x` instead:  `x_u < ...`.
created_at: 2025-03-20T14:23:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,52 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(zero), FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero),
+                              FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf),
+                              FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(zero, LIBC_NAMESPACE::acoshf16(
+                         LIBC_NAMESPACE::fputil::cast<float16>(1.0)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(
+                         LIBC_NAMESPACE::fputil::cast<float16>(0.5)));
+  EXPECT_MATH_ERRNO(EDOM);
+}
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: lntue
body: Add some test cases for -1, -2, -3.
created_at: 2025-03-20T14:24:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -653,6 +653,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     # math.h C23 _Float16 entrypoints
     libc.src.math.asinf16
     libc.src.math.acosf16
+    libc.src.math.acoshf16
path: libc/config/linux/x86_64/entrypoints.txt
user: login: lntue
body: Can you also add entrypoints for linux/aarch64 and linux/riscv?
created_at: 2025-03-20T14:38:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -653,6 +653,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     # math.h C23 _Float16 entrypoints
     libc.src.math.asinf16
     libc.src.math.acosf16
+    libc.src.math.acoshf16
path: libc/config/linux/x86_64/entrypoints.txt
user: login: harrisonGPU
body: Done.
created_at: 2025-03-20T16:37:40Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,52 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(zero), FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero),
+                              FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf),
+                              FE_INVALID);
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(zero, LIBC_NAMESPACE::acoshf16(
+                         LIBC_NAMESPACE::fputil::cast<float16>(1.0)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(
+                         LIBC_NAMESPACE::fputil::cast<float16>(0.5)));
+  EXPECT_MATH_ERRNO(EDOM);
+}
path: libc/test/src/math/smoke/acoshf16_test.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-20T16:37:52Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,102 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return FPBits::zero().get_val();
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf = x;
+  // High-precision polynomial approximation for inputs close to 1.0
+  // ([1, 1.25)).
+  //
+  // Brief derivation:
+  // 1. Start from the definition: acosh(x) = y means x = cosh(y).
+  // 2. Set x = 1 + delta. For small delta, y ≈ sqrt(2 * delta).
+  // 3. Expand acosh(1 + delta) using Taylor series around delta=0:
+  //    acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160
+  //                     - 5*delta^3/896 + 35*delta^4/18432 + ...]
+  // 4. Truncate the series to fit accurately for delta in [0, 0.25].
+  // 5. Polynomial coefficients (from sollya) used here are:
+  //    P(delta) ≈ 1 - 0x1.555556p-4 * delta + 0x1.333334p-6 * delta^2
+  //               - 0x1.6db6dcp-8 * delta^3 + 0x1.f1c71cp-10 * delta^4
+  if (LIBC_UNLIKELY(xf < 1.25f)) {
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-20T16:38:25Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,102 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-20T16:38:32Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,102 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-20T16:38:41Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,102 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return FPBits::zero().get_val();
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf = x;
+  // High-precision polynomial approximation for inputs close to 1.0
+  // ([1, 1.25)).
+  //
+  // Brief derivation:
+  // 1. Start from the definition: acosh(x) = y means x = cosh(y).
+  // 2. Set x = 1 + delta. For small delta, y ≈ sqrt(2 * delta).
+  // 3. Expand acosh(1 + delta) using Taylor series around delta=0:
+  //    acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160
+  //                     - 5*delta^3/896 + 35*delta^4/18432 + ...]
+  // 4. Truncate the series to fit accurately for delta in [0, 0.25].
+  // 5. Polynomial coefficients (from sollya) used here are:
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: I have updated it, what do you think about it?
created_at: 2025-03-20T16:39:03Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,102 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return FPBits::zero().get_val();
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf = x;
+  // High-precision polynomial approximation for inputs close to 1.0
+  // ([1, 1.25)).
+  //
+  // Brief derivation:
+  // 1. Start from the definition: acosh(x) = y means x = cosh(y).
+  // 2. Set x = 1 + delta. For small delta, y ≈ sqrt(2 * delta).
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-20T16:39:14Z
author_association: MEMBER
diff_hunk: @@ -653,6 +653,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     # math.h C23 _Float16 entrypoints
     libc.src.math.asinf16
     libc.src.math.acosf16
+    libc.src.math.acoshf16
path: libc/config/linux/x86_64/entrypoints.txt
user: login: harrisonGPU
body: I noticed risc-v have not LIBC_TYPES_HAS_FLOAT16, should I create it? @lntue 
created_at: 2025-03-21T02:45:55Z
author_association: MEMBER
diff_hunk: @@ -653,6 +653,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     # math.h C23 _Float16 entrypoints
     libc.src.math.asinf16
     libc.src.math.acosf16
+    libc.src.math.acoshf16
path: libc/config/linux/x86_64/entrypoints.txt
user: login: lntue
body: I think there was some issue with the compiler runtimes on RISCV (maybe 32).  Did we resolve it? @overmighty 
created_at: 2025-03-21T03:11:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -74,16 +66,29 @@ LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
   // ([1, 1.25)).
   //
   // Brief derivation:
-  // 1. Start from the definition: acosh(x) = y means x = cosh(y).
-  // 2. Set x = 1 + delta. For small delta, y ≈ sqrt(2 * delta).
-  // 3. Expand acosh(1 + delta) using Taylor series around delta=0:
+  // 1. Expand acosh(1 + delta) using Taylor series around delta=0:
   //    acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160
   //                     - 5*delta^3/896 + 35*delta^4/18432 + ...]
-  // 4. Truncate the series to fit accurately for delta in [0, 0.25].
-  // 5. Polynomial coefficients (from sollya) used here are:
+  // 2. Truncate the series to fit accurately for delta in [0, 0.25].
+  // 3. Polynomial coefficients (from sollya) used here are:
   //    P(delta) ≈ 1 - 0x1.555556p-4 * delta + 0x1.333334p-6 * delta^2
   //               - 0x1.6db6dcp-8 * delta^3 + 0x1.f1c71cp-10 * delta^4
-  if (LIBC_UNLIKELY(xf < 1.25f)) {
+  // 4. The Sollya commands used to generate these coefficients were:
+  //      > display = hexadecimal;
+  //      > round(1/12, SG, RN);
+  //      > round(3/160, SG, RN);
+  //      > round(5/896, SG, RN);
+  //      > round(35/18432, SG, RN);
+  //      With hexadecimal display mode enabled, the outputs were:
+  //      0x1.555556p-4
+  //      0x1.333334p-6
+  //      0x1.6db6dcp-8
+  //      0x1.f1c71cp-10
+  // 5. The maximum absolute error, estimated using:
+  //      dirtyinfnorm(acosh(1 + x) - sqrt(2*x) * P(x), [0, 0.25])
+  //    is:
+  //      0x1.d84281p-22
+  if (LIBC_UNLIKELY(x_u < 1.25f)) {
path: libc/src/math/generic/acoshf16.cpp
user: login: lntue
body: Using `x_u` as bit pattern, you will need to compare to the bit pattern of `1.25` in half precision.
created_at: 2025-03-21T15:51:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -74,16 +66,29 @@ LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
   // ([1, 1.25)).
   //
   // Brief derivation:
-  // 1. Start from the definition: acosh(x) = y means x = cosh(y).
-  // 2. Set x = 1 + delta. For small delta, y ≈ sqrt(2 * delta).
-  // 3. Expand acosh(1 + delta) using Taylor series around delta=0:
+  // 1. Expand acosh(1 + delta) using Taylor series around delta=0:
   //    acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160
   //                     - 5*delta^3/896 + 35*delta^4/18432 + ...]
-  // 4. Truncate the series to fit accurately for delta in [0, 0.25].
-  // 5. Polynomial coefficients (from sollya) used here are:
+  // 2. Truncate the series to fit accurately for delta in [0, 0.25].
+  // 3. Polynomial coefficients (from sollya) used here are:
   //    P(delta) ≈ 1 - 0x1.555556p-4 * delta + 0x1.333334p-6 * delta^2
   //               - 0x1.6db6dcp-8 * delta^3 + 0x1.f1c71cp-10 * delta^4
-  if (LIBC_UNLIKELY(xf < 1.25f)) {
+  // 4. The Sollya commands used to generate these coefficients were:
+  //      > display = hexadecimal;
+  //      > round(1/12, SG, RN);
+  //      > round(3/160, SG, RN);
+  //      > round(5/896, SG, RN);
+  //      > round(35/18432, SG, RN);
+  //      With hexadecimal display mode enabled, the outputs were:
+  //      0x1.555556p-4
+  //      0x1.333334p-6
+  //      0x1.6db6dcp-8
+  //      0x1.f1c71cp-10
+  // 5. The maximum absolute error, estimated using:
+  //      dirtyinfnorm(acosh(1 + x) - sqrt(2*x) * P(x), [0, 0.25])
+  //    is:
+  //      0x1.d84281p-22
+  if (LIBC_UNLIKELY(x_u < 1.25f)) {
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Okay, I have updated it. @lntue  :-)
created_at: 2025-03-22T10:09:18Z
author_association: MEMBER
diff_hunk: @@ -397,6 +397,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     # math.h entrypoints
     libc.src.math.acosf
     libc.src.math.acoshf
+    libc.src.math.acoshf16
path: libc/config/linux/riscv/entrypoints.txt
user: login: overmighty
body: We haven't (re-)enabled float16 support for RISC-V yet.

```suggestion
```
created_at: 2025-03-22T14:51:48Z
author_association: MEMBER
diff_hunk: @@ -653,6 +653,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     # math.h C23 _Float16 entrypoints
     libc.src.math.asinf16
     libc.src.math.acosf16
+    libc.src.math.acoshf16
path: libc/config/linux/x86_64/entrypoints.txt
user: login: overmighty
body: There's https://github.com/llvm/llvm-project/pull/109700. I should test again, on both RV32 and RV64.
created_at: 2025-03-22T15:28:50Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,107 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: For `fputil::polyeval`.

```suggestion
#include "src/__support/FPUtil/PolyEval.h"
#include "src/__support/FPUtil/cast.h"
```
created_at: 2025-03-22T15:29:49Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,107 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: For `LIBC_NAMESPACE_DECL` and `LLVM_LIBC_FUNCTION`.

```suggestion
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
```
created_at: 2025-03-22T15:29:58Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,107 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x <= 1.0f)) {
+    if (x == 1.0f)
+      return FPBits::zero().get_val();
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) {
path: libc/src/math/generic/acoshf16.cpp
user: login: overmighty
body: Should move the `if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))` above the `if (LIBC_UNLIKELY(x <= 1.0f))`. We should check for NaNs before doing any kind of floating-point operation.

Even just comparing a quiet NaN could raise `FE_INVALID`: https://godbolt.org/z/M1GfPnPGa, although in this case it didn't happen when I tested on my machine, seemingly because Clang generated a `vucomiss` instruction instead of a `comiss` one. 
created_at: 2025-03-22T15:35:01Z
author_association: MEMBER
diff_hunk: @@ -3944,6 +3944,26 @@ add_entrypoint_object(
     libc.src.__support.macros.optimization
 )
 
+add_entrypoint_object(
+  acoshf16
+  SRCS
+    acoshf16.cpp
+  HDRS
+    ../acoshf16.h
+  DEPENDS
+    .explogxf
+    libc.hdr.errno_macros
+    libc.hdr.fenv_macros
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.FPUtil.fenv_impl
path: libc/src/math/generic/CMakeLists.txt
user: login: overmighty
body: ```suggestion
    libc.src.__support.FPUtil.except_value_utils
    libc.src.__support.FPUtil.fenv_impl
```
created_at: 2025-03-22T15:36:56Z
author_association: MEMBER
diff_hunk: @@ -397,6 +397,7 @@ set(TARGET_LIBM_ENTRYPOINTS
     # math.h entrypoints
     libc.src.math.acosf
     libc.src.math.acoshf
+    libc.src.math.acoshf16
path: libc/config/linux/riscv/entrypoints.txt
user: login: harrisonGPU
body: Okay, I removed it.
created_at: 2025-03-22T16:03:30Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,107 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-22T16:03:56Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,107 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Done.
created_at: 2025-03-22T16:04:28Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,107 @@
+//===-- Half-precision acosh(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "explogxf.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/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+    {0x41B7, 0x3ED8, 1, 0, 0},
+    // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+    {0x3CE4, 0x393E, 1, 0, 1},
+}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x <= 1.0f)) {
+    if (x == 1.0f)
+      return FPBits::zero().get_val();
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) {
path: libc/src/math/generic/acoshf16.cpp
user: login: harrisonGPU
body: Thanks, I have updated it.
created_at: 2025-03-22T16:04:52Z
author_association: MEMBER
diff_hunk: @@ -3944,6 +3944,26 @@ add_entrypoint_object(
     libc.src.__support.macros.optimization
 )
 
+add_entrypoint_object(
+  acoshf16
+  SRCS
+    acoshf16.cpp
+  HDRS
+    ../acoshf16.h
+  DEPENDS
+    .explogxf
+    libc.hdr.errno_macros
+    libc.hdr.fenv_macros
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.FPUtil.fenv_impl
path: libc/src/math/generic/CMakeLists.txt
user: login: harrisonGPU
body: Done.
created_at: 2025-03-22T16:05:12Z
author_association: MEMBER
diff_hunk: @@ -3944,6 +3944,26 @@ add_entrypoint_object(
     libc.src.__support.macros.optimization
 )
 
+add_entrypoint_object(
+  acoshf16
+  SRCS
+    acoshf16.cpp
+  HDRS
+    ../acoshf16.h
+  DEPENDS
+    .explogxf
+    libc.hdr.errno_macros
+    libc.hdr.fenv_macros
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.FPUtil.fenv_impl
path: libc/src/math/generic/CMakeLists.txt
user: login: harrisonGPU
body: <img width="1111" alt="image" src="https://github.com/user-attachments/assets/965e6894-3eab-4e7c-9361-bad9950c1f5c" />
Haha, You said it is not used. :-) @overmighty 
created_at: 2025-03-22T16:29:39Z
author_association: MEMBER
diff_hunk: @@ -3944,6 +3944,26 @@ add_entrypoint_object(
     libc.src.__support.macros.optimization
 )
 
+add_entrypoint_object(
+  acoshf16
+  SRCS
+    acoshf16.cpp
+  HDRS
+    ../acoshf16.h
+  DEPENDS
+    .explogxf
+    libc.hdr.errno_macros
+    libc.hdr.fenv_macros
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.FPUtil.fenv_impl
path: libc/src/math/generic/CMakeLists.txt
user: login: overmighty
body: Right, because except_value_utils.h wasn't included back then, and there was no reason for it to be: https://github.com/llvm/llvm-project/blob/2c140519f3f4f89fbc254f4300e2b319495077f3/libc/src/math/generic/acoshf16.cpp.
created_at: 2025-03-22T18:17:58Z
author_association: MEMBER

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-10T12:09:13Z
body: <!--LLVM CODE FORMAT COMMENT: {clang-format}-->

:white_check_mark: With the latest revision this PR passed the C/C++ code formatter.
author_association: NONE
user: login: llvmbot
created_at: 2025-03-13T12:54:56Z
body: 
<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Harrison Hao (harrisonGPU)

<details>
<summary>Changes</summary>

Implementation of acoshf16 function for 16-bit inputs.


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


11 Files Affected:

- (modified) libc/config/linux/x86_64/entrypoints.txt (+1) 
- (modified) libc/docs/headers/math/index.rst (+1-1) 
- (modified) libc/include/math.yaml (+7) 
- (modified) libc/src/math/CMakeLists.txt (+1) 
- (added) libc/src/math/acoshf16.h (+21) 
- (modified) libc/src/math/generic/CMakeLists.txt (+21) 
- (added) libc/src/math/generic/acoshf16.cpp (+88) 
- (modified) libc/test/src/math/CMakeLists.txt (+11) 
- (added) libc/test/src/math/acoshf16_test.cpp (+76) 
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+11) 
- (added) libc/test/src/math/smoke/acoshf16_test.cpp (+41) 


``````````diff
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 12dc87bf945fd..b705d81fff79c 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -653,6 +653,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     # math.h C23 _Float16 entrypoints
     libc.src.math.asinf16
     libc.src.math.acosf16
+    libc.src.math.acoshf16
     libc.src.math.canonicalizef16
     libc.src.math.ceilf16
     libc.src.math.copysignf16
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index 5b855ce4881c3..8dc7c8c1a0966 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -251,7 +251,7 @@ Higher Math Functions
 +===========+==================+=================+========================+======================+========================+========================+============================+
 | acos      | |check|          |                 |                        | |check|              |                        | 7.12.4.1               | F.10.1.1                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| acosh     | |check|          |                 |                        |                      |                        | 7.12.5.1               | F.10.2.1                   |
+| acosh     | |check|          |                 |                        | |check|              |                        | 7.12.5.1               | F.10.2.1                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | acospi    |                  |                 |                        |                      |                        | 7.12.4.8               | F.10.1.8                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/include/math.yaml b/libc/include/math.yaml
index a66f981030864..7fd73445cc74e 100644
--- a/libc/include/math.yaml
+++ b/libc/include/math.yaml
@@ -27,6 +27,13 @@ functions:
     return_type: float
     arguments:
       - type: float
+    name: acoshf16
+    standards:
+      - stdc
+    return_type: _Float16
+    arguments:
+      - type: _Float16
+    guard: LIBC_TYPES_HAS_FLOAT16
   - name: asin
     standards:
       - stdc
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index f18a73d46f9aa..bdf8b923416d8 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -46,6 +46,7 @@ add_math_entrypoint_object(acosf16)
 
 add_math_entrypoint_object(acosh)
 add_math_entrypoint_object(acoshf)
+add_math_entrypoint_object(acoshf16)
 
 add_math_entrypoint_object(asin)
 add_math_entrypoint_object(asinf)
diff --git a/libc/src/math/acoshf16.h b/libc/src/math/acoshf16.h
new file mode 100644
index 0000000000000..f471ecfeb6154
--- /dev/null
+++ b/libc/src/math/acoshf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for acoshf16 ----------------------*- 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_SRC_MATH_ACOSHF16_H
+#define LLVM_LIBC_SRC_MATH_ACOSHF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float16 acoshf16(float16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ACOSHF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 3114289bad486..fd5ecd72b765f 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -3944,6 +3944,27 @@ add_entrypoint_object(
     libc.src.__support.macros.optimization
 )
 
+add_entrypoint_object(
+  acoshf16
+  SRCS
+    acoshf16.cpp
+  HDRS
+    ../acoshf16.h
+  DEPENDS
+    .common_constants
+    .explogxf
+    libc.hdr.errno_macros
+    libc.hdr.fenv_macros
+    libc.src.__support.FPUtil.cast
+    libc.src.__support.FPUtil.fenv_impl
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.multiply_add
+    libc.src.__support.FPUtil.polyeval
+    libc.src.__support.FPUtil.sqrt
+    libc.src.__support.macros.optimization
+    libc.src.__support.macros.properties.types 
+)
+
 add_entrypoint_object(
   asinhf
   SRCS
diff --git a/libc/src/math/generic/acoshf16.cpp b/libc/src/math/generic/acoshf16.cpp
new file mode 100644
index 0000000000000..1a4f68987ee6b
--- /dev/null
+++ b/libc/src/math/generic/acoshf16.cpp
@@ -0,0 +1,88 @@
+//===-- Half-precision acoshf16 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/acoshf16.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/generic/sqrt.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+#include "src/math/generic/explogxf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr size_t N_EXCEPTS = 2;
+static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{
+    {// (input, RZ output, RU offset, RD offset, RN offset)
+     {0x41B7, 0x3ED8, 1, 0, 0},
+     {0x3CE4, 0x393E, 1, 0, 1}}};
+
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+
+  // Check for NaN input first.
+  if (LIBC_UNLIKELY(xbits.is_nan())) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Check for infinite inputs.
+  if (LIBC_UNLIKELY(xbits.is_inf())) {
+    if (xbits.is_neg()) {
+      fputil::set_errno_if_required(EDOM);
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    return x;
+  }
+
+  // Domain error for inputs less than 1.0.
+  if (LIBC_UNLIKELY(x_abs < 0x3c00U)) {
+    fputil::set_errno_if_required(EDOM);
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // acosh(1.0) exactly equals 0.0
+  if (LIBC_UNLIKELY(x_u == 0x3c00U))
+    return float16(0.0f);
+
+  if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+      LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  float xf32 = x;
+  // High precision for inputs very close to 1.0
+  if (LIBC_UNLIKELY(xf32 < 1.25f)) {
+    float delta = xf32 - 1.0f;
+    float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
+    float x2 = delta;
+    float pe = fputil::polyeval(x2, 0x1.0000000000000p+0f,
+                                -0x1.55551a83a9472p-4f, 0x1.331601c4b8ecfp-6f,
+                                -0x1.6890f49eb0acbp-8f, 0x1.8f3a617040a6ap-10f);
+    float approx = sqrt_2_delta * pe;
+    return fputil::cast<float16>(approx);
+  }
+
+  // Standard computation for general case.
+  float sqrt_term =
+      fputil::sqrt<float>(fputil::multiply_add(xf32, xf32, -1.0f));
+  float result = static_cast<float>(log_eval(xf32 + sqrt_term));
+
+  return fputil::cast<float16>(result);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 53ddd301900c0..311d56a2a33ab 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2173,6 +2173,17 @@ add_fp_unittest(
     libc.src.__support.FPUtil.fp_bits
 )
 
+add_fp_unittest(
+  acoshf16_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    acoshf16_test.cpp
+  DEPENDS
+    libc.src.math.acoshf16
+)
+
 add_fp_unittest(
   asinf_test
   NEED_MPFR
diff --git a/libc/test/src/math/acoshf16_test.cpp b/libc/test/src/math/acoshf16_test.cpp
new file mode 100644
index 0000000000000..a779d3110f329
--- /dev/null
+++ b/libc/test/src/math/acoshf16_test.cpp
@@ -0,0 +1,76 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include <stdint.h>
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+static constexpr uint16_t START = 0x3c00U;
+static constexpr uint16_t STOP = 0x7bffU;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(float16(0.0f),
+                            LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAcoshf16Test, PositiveRange) {
+  for (uint16_t v = START; v <= STOP; ++v) {
+    float16 x = FPBits(v).get_val();
+
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x,
+                                   LIBC_NAMESPACE::acoshf16(x), 0.5);
+  }
+}
+
+TEST_F(LlvmLibcAcoshf16Test, SpecificBitPatterns) {
+  constexpr int N = 12;
+  constexpr uint16_t INPUTS[N] = {
+      0x3C00, // x = 1.0
+      0x3C01, // x = just above 1.0 (minimally larger than 1)
+      0x3E00, // x = 1.5
+      0x4200, // x = 3.0
+      0x4500, // x = 5.0
+      0x4900, // x = 10.0
+      0x51FF, // x = ~47.94
+      0x5CB0, // x = ~300.0
+      0x643F, // x = ~1087.6
+      0x77FF, // x = just below next exponent interval (max for exponent 0x1D)
+      0x7801, // x = just above previous value (min for exponent 0x1E)
+      0x7BFF  // x = 65504.0 (max finite half)
+  };
+  for (int i = 0; i < N; ++i) {
+    float16 x = FPBits(INPUTS[i]).get_val();
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x,
+                                   LIBC_NAMESPACE::acoshf16(x), 0.5);
+  }
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 6f94440d826d9..4303afd242e22 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -3945,6 +3945,17 @@ add_fp_unittest(
     libc.src.__support.FPUtil.fp_bits
 )
 
+add_fp_unittest(
+  acoshf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    acoshf16_test.cpp
+  DEPENDS
+    libc.src.errno.errno
+    libc.src.math.acoshf16  
+)
+
 add_fp_unittest(
   asinf_test
   SUITE
diff --git a/libc/test/src/math/smoke/acoshf16_test.cpp b/libc/test/src/math/smoke/acoshf16_test.cpp
new file mode 100644
index 0000000000000..b8d13b9fe88c3
--- /dev/null
+++ b/libc/test/src/math/smoke/acoshf16_test.cpp
@@ -0,0 +1,41 @@
+//===-- Unittests for acoshf16 --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/libc_errno.h"
+#include "src/math/acoshf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_zero));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(inf, LIBC_NAMESPACE::acoshf16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(float16(0.0f), LIBC_NAMESPACE::acoshf16(float16(1.0f)));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
+  EXPECT_MATH_ERRNO(EDOM);
+}

``````````

</details>

author_association: MEMBER
user: login: overmighty
created_at: 2025-03-17T16:51:58Z
body: You don't need to force-push if you didn't rebase btw.
author_association: MEMBER
user: login: harrisonGPU
created_at: 2025-03-17T16:54:40Z
body: > You don't need to force-push if you didn't rebase btw.

Yes, I did rebase.
author_association: MEMBER
user: login: harrisonGPU
created_at: 2025-03-20T13:47:51Z
body: ping @overmighty 
author_association: MEMBER
user: login: llvm-ci
created_at: 2025-03-23T02:09:44Z
body: LLVM Buildbot has detected a new failure on builder `libc-aarch64-ubuntu-fullbuild-dbg` running on `libc-aarch64-ubuntu` while building `libc` at step 4 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/71/builds/18786

<details>
<summary>Here is the relevant piece of the build log for the reference</summary>

```
Step 4 (annotate) failure: 'python ../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py ...' (failure)
...
[ RUN      ] LlvmLibcFMaxTest.InfArg
[       OK ] LlvmLibcFMaxTest.InfArg (2 us)
[ RUN      ] LlvmLibcFMaxTest.NegInfArg
[       OK ] LlvmLibcFMaxTest.NegInfArg (1 us)
[ RUN      ] LlvmLibcFMaxTest.BothZero
[       OK ] LlvmLibcFMaxTest.BothZero (1 us)
[ RUN      ] LlvmLibcFMaxTest.Range
[       OK ] LlvmLibcFMaxTest.Range (29 ms)
Ran 5 tests.  PASS: 5  FAIL: 0
[536/960] Running unit test libc.test.src.math.smoke.acoshf16_test.__unit__
FAILED: libc/test/src/math/smoke/CMakeFiles/libc.test.src.math.smoke.acoshf16_test.__unit__ 
cd /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/build/libc/test/src/math/smoke && /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/build/libc/test/src/math/smoke/libc.test.src.math.smoke.acoshf16_test.__unit__.__build__
[==========] Running 1 test from 1 test suite.
[ RUN      ] LlvmLibcAcoshf16Test.SpecialNumbers
/home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/llvm-project/libc/test/src/math/smoke/acoshf16_test.cpp:22: FAILURE
      Expected: __llvm_libc_20_0_0_git::fputil::test_except( static_cast<int>((0x1 | 0x2 | 0x4 | 0x8 | 0x10))) & ((0x4) ? (0x4) : static_cast<int>((0x1 | 0x2 | 0x4 | 0x8 | 0x10)))
      Which is: 0
To be equal to: (0x4)
      Which is: 4
[  FAILED  ] LlvmLibcAcoshf16Test.SpecialNumbers
Ran 1 tests.  PASS: 0  FAIL: 1
[537/960] Running unit test libc.test.src.math.smoke.ilogbf128_test.__unit__
[==========] Running 5 tests from 1 test suite.
[ RUN      ] LlvmLibcIntLogbTest.SpecialNumbers
[       OK ] LlvmLibcIntLogbTest.SpecialNumbers (4 us)
[ RUN      ] LlvmLibcIntLogbTest.PowersOfTwo
[       OK ] LlvmLibcIntLogbTest.PowersOfTwo (6 us)
[ RUN      ] LlvmLibcIntLogbTest.SomeIntegers
[       OK ] LlvmLibcIntLogbTest.SomeIntegers (4 us)
[ RUN      ] LlvmLibcIntLogbTest.SubnormalRange
[       OK ] LlvmLibcIntLogbTest.SubnormalRange (6 ms)
[ RUN      ] LlvmLibcIntLogbTest.NormalRange
[       OK ] LlvmLibcIntLogbTest.NormalRange (6 ms)
Ran 5 tests.  PASS: 5  FAIL: 0
[538/960] Running unit test libc.test.src.math.smoke.fmax_test.__unit__.__NO_MISC_MATH_BASIC_OPS_OPT
[==========] Running 5 tests from 1 test suite.
[ RUN      ] LlvmLibcFMaxTest.NaN
[       OK ] LlvmLibcFMaxTest.NaN (3 us)
[ RUN      ] LlvmLibcFMaxTest.InfArg
[       OK ] LlvmLibcFMaxTest.InfArg (2 us)
[ RUN      ] LlvmLibcFMaxTest.NegInfArg
[       OK ] LlvmLibcFMaxTest.NegInfArg (1 us)
[ RUN      ] LlvmLibcFMaxTest.BothZero
[       OK ] LlvmLibcFMaxTest.BothZero (1 us)
[ RUN      ] LlvmLibcFMaxTest.Range
[       OK ] LlvmLibcFMaxTest.Range (30 ms)
Ran 5 tests.  PASS: 5  FAIL: 0
[539/960] Running unit test libc.test.src.math.smoke.fmaxf_test.__unit__.__NO_MISC_MATH_BASIC_OPS_OPT
[==========] Running 5 tests from 1 test suite.
Step 8 (libc-unit-tests) failure: libc-unit-tests (failure)
...
[ RUN      ] LlvmLibcFMaxTest.InfArg
[       OK ] LlvmLibcFMaxTest.InfArg (2 us)
[ RUN      ] LlvmLibcFMaxTest.NegInfArg
[       OK ] LlvmLibcFMaxTest.NegInfArg (1 us)
[ RUN      ] LlvmLibcFMaxTest.BothZero
[       OK ] LlvmLibcFMaxTest.BothZero (1 us)
[ RUN      ] LlvmLibcFMaxTest.Range
[       OK ] LlvmLibcFMaxTest.Range (29 ms)
Ran 5 tests.  PASS: 5  FAIL: 0
[536/960] Running unit test libc.test.src.math.smoke.acoshf16_test.__unit__
FAILED: libc/test/src/math/smoke/CMakeFiles/libc.test.src.math.smoke.acoshf16_test.__unit__ 
cd /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/build/libc/test/src/math/smoke && /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/build/libc/test/src/math/smoke/libc.test.src.math.smoke.acoshf16_test.__unit__.__build__
[==========] Running 1 test from 1 test suite.
[ RUN      ] LlvmLibcAcoshf16Test.SpecialNumbers
/home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/llvm-project/libc/test/src/math/smoke/acoshf16_test.cpp:22: FAILURE
      Expected: __llvm_libc_20_0_0_git::fputil::test_except( static_cast<int>((0x1 | 0x2 | 0x4 | 0x8 | 0x10))) & ((0x4) ? (0x4) : static_cast<int>((0x1 | 0x2 | 0x4 | 0x8 | 0x10)))
      Which is: 0
To be equal to: (0x4)
      Which is: 4
[  FAILED  ] LlvmLibcAcoshf16Test.SpecialNumbers
Ran 1 tests.  PASS: 0  FAIL: 1
[537/960] Running unit test libc.test.src.math.smoke.ilogbf128_test.__unit__
[==========] Running 5 tests from 1 test suite.
[ RUN      ] LlvmLibcIntLogbTest.SpecialNumbers
[       OK ] LlvmLibcIntLogbTest.SpecialNumbers (4 us)
[ RUN      ] LlvmLibcIntLogbTest.PowersOfTwo
[       OK ] LlvmLibcIntLogbTest.PowersOfTwo (6 us)
[ RUN      ] LlvmLibcIntLogbTest.SomeIntegers
[       OK ] LlvmLibcIntLogbTest.SomeIntegers (4 us)
[ RUN      ] LlvmLibcIntLogbTest.SubnormalRange
[       OK ] LlvmLibcIntLogbTest.SubnormalRange (6 ms)
[ RUN      ] LlvmLibcIntLogbTest.NormalRange
[       OK ] LlvmLibcIntLogbTest.NormalRange (6 ms)
Ran 5 tests.  PASS: 5  FAIL: 0
[538/960] Running unit test libc.test.src.math.smoke.fmax_test.__unit__.__NO_MISC_MATH_BASIC_OPS_OPT
[==========] Running 5 tests from 1 test suite.
[ RUN      ] LlvmLibcFMaxTest.NaN
[       OK ] LlvmLibcFMaxTest.NaN (3 us)
[ RUN      ] LlvmLibcFMaxTest.InfArg
[       OK ] LlvmLibcFMaxTest.InfArg (2 us)
[ RUN      ] LlvmLibcFMaxTest.NegInfArg
[       OK ] LlvmLibcFMaxTest.NegInfArg (1 us)
[ RUN      ] LlvmLibcFMaxTest.BothZero
[       OK ] LlvmLibcFMaxTest.BothZero (1 us)
[ RUN      ] LlvmLibcFMaxTest.Range
[       OK ] LlvmLibcFMaxTest.Range (30 ms)
Ran 5 tests.  PASS: 5  FAIL: 0
[539/960] Running unit test libc.test.src.math.smoke.fmaxf_test.__unit__.__NO_MISC_MATH_BASIC_OPS_OPT
[==========] Running 5 tests from 1 test suite.

```

</details>
author_association: NONE
user: login: llvm-ci
created_at: 2025-03-23T02:09:45Z
body: LLVM Buildbot has detected a new failure on builder `libc-aarch64-ubuntu-dbg` running on `libc-aarch64-ubuntu` while building `libc` at step 4 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/104/builds/18785

<details>
<summary>Here is the relevant piece of the build log for the reference</summary>

```
Step 4 (annotate) failure: 'python ../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py ...' (failure)
...
[       OK ] LlvmLibcTotalOrderMagTest.QuietVsSignalingNaN (1 us)
[ RUN      ] LlvmLibcTotalOrderMagTest.NaNPayloads
[       OK ] LlvmLibcTotalOrderMagTest.NaNPayloads (2 us)
Ran 7 tests.  PASS: 7  FAIL: 0
[767/1023] Running unit test libc.test.src.math.smoke.tanhf_test.__unit__
[==========] Running 1 test from 1 test suite.
[ RUN      ] LlvmLibcTanhfTest.SpecialNumbers
[       OK ] LlvmLibcTanhfTest.SpecialNumbers (5 us)
Ran 1 tests.  PASS: 1  FAIL: 0
[768/1023] Running unit test libc.test.src.math.smoke.acoshf16_test.__unit__
FAILED: libc/test/src/math/smoke/CMakeFiles/libc.test.src.math.smoke.acoshf16_test.__unit__ 
cd /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu/build/libc/test/src/math/smoke && /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu/build/libc/test/src/math/smoke/libc.test.src.math.smoke.acoshf16_test.__unit__.__build__
[==========] Running 1 test from 1 test suite.
[ RUN      ] LlvmLibcAcoshf16Test.SpecialNumbers
/home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu/llvm-project/libc/test/src/math/smoke/acoshf16_test.cpp:22: FAILURE
      Expected: __llvm_libc_20_0_0_git::fputil::test_except( static_cast<int>((1 | 2 | 4 | 8 | 16))) & ((1) ? (1) : static_cast<int>((1 | 2 | 4 | 8 | 16)))
      Which is: 0
To be equal to: (1)
      Which is: 1
[  FAILED  ] LlvmLibcAcoshf16Test.SpecialNumbers
Ran 1 tests.  PASS: 0  FAIL: 1
[769/1023] Running unit test libc.test.src.math.smoke.nextupf16_test.__unit__
[==========] Running 2 tests from 1 test suite.
[ RUN      ] LlvmLibcNextUpTest.TestNaN
[       OK ] LlvmLibcNextUpTest.TestNaN (3 us)
[ RUN      ] LlvmLibcNextUpTest.TestBoundaries
[       OK ] LlvmLibcNextUpTest.TestBoundaries (3 us)
Ran 2 tests.  PASS: 2  FAIL: 0
[770/1023] Running unit test libc.test.src.math.smoke.ddivf128_test.__unit__
[==========] Running 5 tests from 1 test suite.
[ RUN      ] LlvmLibcDivTest.SpecialNumbers
[       OK ] LlvmLibcDivTest.SpecialNumbers (10 us)
[ RUN      ] LlvmLibcDivTest.DivisionByZero
[       OK ] LlvmLibcDivTest.DivisionByZero (4 us)
[ RUN      ] LlvmLibcDivTest.InvalidOperations
[       OK ] LlvmLibcDivTest.InvalidOperations (11 us)
[ RUN      ] LlvmLibcDivTest.RangeErrors
[       OK ] LlvmLibcDivTest.RangeErrors (33 us)
[ RUN      ] LlvmLibcDivTest.InexactResults
[       OK ] LlvmLibcDivTest.InexactResults (2 us)
Ran 5 tests.  PASS: 5  FAIL: 0
[771/1023] Running unit test libc.test.src.math.smoke.fabsf_test.__unit__.__NO_MISC_MATH_BASIC_OPS_OPT
[==========] Running 1 test from 1 test suite.
[ RUN      ] LlvmLibcFAbsTest.SpecialNumbers
[       OK ] LlvmLibcFAbsTest.SpecialNumbers (8 us)
Ran 1 tests.  PASS: 1  FAIL: 0
[772/1023] Running unit test libc.test.src.math.smoke.fma_test.__unit__
[==========] Running 1 test from 1 test suite.
[ RUN      ] LlvmLibcFmaTest.SpecialNumbers
Step 7 (libc-unit-tests) failure: libc-unit-tests (failure)
...
[       OK ] LlvmLibcTotalOrderMagTest.QuietVsSignalingNaN (1 us)
[ RUN      ] LlvmLibcTotalOrderMagTest.NaNPayloads
[       OK ] LlvmLibcTotalOrderMagTest.NaNPayloads (2 us)
Ran 7 tests.  PASS: 7  FAIL: 0
[767/1023] Running unit test libc.test.src.math.smoke.tanhf_test.__unit__
[==========] Running 1 test from 1 test suite.
[ RUN      ] LlvmLibcTanhfTest.SpecialNumbers
[       OK ] LlvmLibcTanhfTest.SpecialNumbers (5 us)
Ran 1 tests.  PASS: 1  FAIL: 0
[768/1023] Running unit test libc.test.src.math.smoke.acoshf16_test.__unit__
FAILED: libc/test/src/math/smoke/CMakeFiles/libc.test.src.math.smoke.acoshf16_test.__unit__ 
cd /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu/build/libc/test/src/math/smoke && /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu/build/libc/test/src/math/smoke/libc.test.src.math.smoke.acoshf16_test.__unit__.__build__
[==========] Running 1 test from 1 test suite.
[ RUN      ] LlvmLibcAcoshf16Test.SpecialNumbers
/home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu/llvm-project/libc/test/src/math/smoke/acoshf16_test.cpp:22: FAILURE
      Expected: __llvm_libc_20_0_0_git::fputil::test_except( static_cast<int>((1 | 2 | 4 | 8 | 16))) & ((1) ? (1) : static_cast<int>((1 | 2 | 4 | 8 | 16)))
      Which is: 0
To be equal to: (1)
      Which is: 1
[  FAILED  ] LlvmLibcAcoshf16Test.SpecialNumbers
Ran 1 tests.  PASS: 0  FAIL: 1
[769/1023] Running unit test libc.test.src.math.smoke.nextupf16_test.__unit__
[==========] Running 2 tests from 1 test suite.
[ RUN      ] LlvmLibcNextUpTest.TestNaN
[       OK ] LlvmLibcNextUpTest.TestNaN (3 us)
[ RUN      ] LlvmLibcNextUpTest.TestBoundaries
[       OK ] LlvmLibcNextUpTest.TestBoundaries (3 us)
Ran 2 tests.  PASS: 2  FAIL: 0
[770/1023] Running unit test libc.test.src.math.smoke.ddivf128_test.__unit__
[==========] Running 5 tests from 1 test suite.
[ RUN      ] LlvmLibcDivTest.SpecialNumbers
[       OK ] LlvmLibcDivTest.SpecialNumbers (10 us)
[ RUN      ] LlvmLibcDivTest.DivisionByZero
[       OK ] LlvmLibcDivTest.DivisionByZero (4 us)
[ RUN      ] LlvmLibcDivTest.InvalidOperations
[       OK ] LlvmLibcDivTest.InvalidOperations (11 us)
[ RUN      ] LlvmLibcDivTest.RangeErrors
[       OK ] LlvmLibcDivTest.RangeErrors (33 us)
[ RUN      ] LlvmLibcDivTest.InexactResults
[       OK ] LlvmLibcDivTest.InexactResults (2 us)
Ran 5 tests.  PASS: 5  FAIL: 0
[771/1023] Running unit test libc.test.src.math.smoke.fabsf_test.__unit__.__NO_MISC_MATH_BASIC_OPS_OPT
[==========] Running 1 test from 1 test suite.
[ RUN      ] LlvmLibcFAbsTest.SpecialNumbers
[       OK ] LlvmLibcFAbsTest.SpecialNumbers (8 us)
Ran 1 tests.  PASS: 1  FAIL: 0
[772/1023] Running unit test libc.test.src.math.smoke.fma_test.__unit__
[==========] Running 1 test from 1 test suite.
[ RUN      ] LlvmLibcFmaTest.SpecialNumbers

```

</details>
author_association: NONE
user: login: lntue
created_at: 2025-03-23T02:53:11Z
body: @harrisonGPU aarch64 failure:
```
FAILED: libc/test/src/math/smoke/CMakeFiles/libc.test.src.math.smoke.acoshf16_test.__unit__ 
cd /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/build/libc/test/src/math/smoke && /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/build/libc/test/src/math/smoke/libc.test.src.math.smoke.acoshf16_test.__unit__.__build__
[==========] Running 1 test from 1 test suite.
[ RUN      ] LlvmLibcAcoshf16Test.SpecialNumbers
/home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/llvm-project/libc/test/src/math/smoke/acoshf16_test.cpp:22: FAILURE
      Expected: __llvm_libc_20_0_0_git::fputil::test_except( static_cast<int>((0x1 | 0x2 | 0x4 | 0x8 | 0x10))) & ((0x4) ? (0x4) : static_cast<int>((0x1 | 0x2 | 0x4 | 0x8 | 0x10)))
      Which is: 0
To be equal to: (0x4)
      Which is: 4
```
Can you investigate to see if it can be fixed quickly, or temporarily disable the assertion statement if you need more time?
author_association: CONTRIBUTOR
user: login: harrisonGPU
created_at: 2025-03-23T02:55:20Z
body: > @harrisonGPU aarch64 failure:
> 
> ```
> FAILED: libc/test/src/math/smoke/CMakeFiles/libc.test.src.math.smoke.acoshf16_test.__unit__ 
> cd /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/build/libc/test/src/math/smoke && /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/build/libc/test/src/math/smoke/libc.test.src.math.smoke.acoshf16_test.__unit__.__build__
> [==========] Running 1 test from 1 test suite.
> [ RUN      ] LlvmLibcAcoshf16Test.SpecialNumbers
> /home/libc-buildbot/libc-aarch64-ubuntu/libc-aarch64-ubuntu-fullbuild-dbg/llvm-project/libc/test/src/math/smoke/acoshf16_test.cpp:22: FAILURE
>       Expected: __llvm_libc_20_0_0_git::fputil::test_except( static_cast<int>((0x1 | 0x2 | 0x4 | 0x8 | 0x10))) & ((0x4) ? (0x4) : static_cast<int>((0x1 | 0x2 | 0x4 | 0x8 | 0x10)))
>       Which is: 0
> To be equal to: (0x4)
>       Which is: 4
> ```
> 
> Can you investigate to see if it can be fixed quickly, or temporarily disable the assertion statement if you need more time?

I will try to investigate this failing test, and for now, I have temporarily disabled it. #132580 
author_association: MEMBER