[libc-commits] [libc] [libc][math][c23] Add acospif16() function (PR #132754)

via libc-commits libc-commits at lists.llvm.org
Sun Apr 6 17:38:40 PDT 2025


https://github.com/amemov updated https://github.com/llvm/llvm-project/pull/132754

>From 619bc84c438882fe337460b19df626db7cca536a Mon Sep 17 00:00:00 2001
From: Anton <shepelev777 at gmail.com>
Date: Sun, 23 Mar 2025 16:50:32 -0400
Subject: [PATCH 1/7] Declared and defined acospif16 - declared acospif16
 implementation and header file - declared test files - declared in CMakeLists
 that the op needs to be checked - defined the op in math.yaml - declared in
 the index.rst that the op needs to be checked for float16 - declared an
 entrypoint for linux x86_64

---
 libc/config/linux/x86_64/entrypoints.txt    |  1 +
 libc/docs/headers/math/index.rst            |  2 +-
 libc/include/math.yaml                      |  7 +++++++
 libc/src/math/CMakeLists.txt                |  1 +
 libc/src/math/acospif16.h                   | 21 +++++++++++++++++++++
 libc/src/math/generic/CMakeLists.txt        | 20 ++++++++++++++++++++
 libc/src/math/generic/acospif16.cpp         | 20 ++++++++++++++++++++
 libc/test/src/math/CMakeLists.txt           | 11 +++++++++++
 libc/test/src/math/acospif16_test.cpp       | 12 ++++++++++++
 libc/test/src/math/smoke/CMakeLists.txt     | 11 +++++++++++
 libc/test/src/math/smoke/acospif16_test.cpp | 13 +++++++++++++
 11 files changed, 118 insertions(+), 1 deletion(-)
 create mode 100644 libc/src/math/acospif16.h
 create mode 100644 libc/src/math/generic/acospif16.cpp
 create mode 100644 libc/test/src/math/acospif16_test.cpp
 create mode 100644 libc/test/src/math/smoke/acospif16_test.cpp

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 124b80d03d846..2f1e16cd20a0e 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -654,6 +654,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     # math.h C23 _Float16 entrypoints
     libc.src.math.asinf16
     libc.src.math.acosf16
+    libc.src.math.acospif16
     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 85585f4fc5f3d..f59828f22a3a2 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -253,7 +253,7 @@ Higher Math Functions
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | acosh     | |check|          |                 |                        |                      |                        | 7.12.5.1               | F.10.2.1                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| acospi    |                  |                 |                        |                      |                        | 7.12.4.8               | F.10.1.8                   |
+| acospi    |                  |                 |                        | |check|              |                        | 7.12.4.8               | F.10.1.8                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | asin      | |check|          |                 |                        | |check|              |                        | 7.12.4.2               | F.10.1.2                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/include/math.yaml b/libc/include/math.yaml
index fbfc51348411a..dfe04732fbd03 100644
--- a/libc/include/math.yaml
+++ b/libc/include/math.yaml
@@ -21,6 +21,13 @@ functions:
     arguments:
       - type: _Float16
     guard: LIBC_TYPES_HAS_FLOAT16
+  - name: acospif16
+    standards:
+      - stdc
+    return_type: _Float16
+    arguments:
+      - type: _Float16
+    guard: LIBC_TYPES_HAS_FLOAT16
   - name: acoshf
     standards:
       - stdc
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index f18a73d46f9aa..6f22c51e06933 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -43,6 +43,7 @@ endfunction()
 add_math_entrypoint_object(acos)
 add_math_entrypoint_object(acosf)
 add_math_entrypoint_object(acosf16)
+add_math_entrypoint_object(acospif16)
 
 add_math_entrypoint_object(acosh)
 add_math_entrypoint_object(acoshf)
diff --git a/libc/src/math/acospif16.h b/libc/src/math/acospif16.h
new file mode 100644
index 0000000000000..c6903af70b393
--- /dev/null
+++ b/libc/src/math/acospif16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for acospif16 ---------------------*- 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_ACOSPIF16_H
+#define LLVM_LIBC_SRC_MATH_ACOSPIF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float16 acospif16(float16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ACOSPIF16_H
\ No newline at end of file
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index db07bd1a098cc..0825551baac25 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4054,6 +4054,26 @@ add_entrypoint_object(
     libc.src.__support.macros.properties.types  
 )
 
+add_entrypoint_object(
+  acospif16
+  SRCS
+    acospif16.cpp
+  HDRS
+    ../acospif16.h
+  DEPENDS
+    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_header_library(
   atan_utils
   HDRS
diff --git a/libc/src/math/generic/acospif16.cpp b/libc/src/math/generic/acospif16.cpp
new file mode 100644
index 0000000000000..99eb9e31f7821
--- /dev/null
+++ b/libc/src/math/generic/acospif16.cpp
@@ -0,0 +1,20 @@
+//===-- Half-precision acospif16(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/acospif16.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/macros/optimization.h"
\ No newline at end of file
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index beafa87e03a77..c52aef996b956 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2221,6 +2221,17 @@ add_fp_unittest(
     libc.src.math.acosf16  
 )
 
+add_fp_unittest(
+  acospif16_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    acospif16_test.cpp
+  DEPENDS
+    libc.src.math.acosf16  
+)
+
 add_fp_unittest(
   atanf_test
   NEED_MPFR
diff --git a/libc/test/src/math/acospif16_test.cpp b/libc/test/src/math/acospif16_test.cpp
new file mode 100644
index 0000000000000..91d668373a973
--- /dev/null
+++ b/libc/test/src/math/acospif16_test.cpp
@@ -0,0 +1,12 @@
+//===-- Exhaustive test for acospif16 -------------------------------------===//
+//
+// 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/acospif16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 94ec099ddfcbc..f6801e10ca4bc 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -3991,6 +3991,17 @@ add_fp_unittest(
     libc.src.math.acosf16  
 )
 
+add_fp_unittest(
+  acospif16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    acospif16_test.cpp
+  DEPENDS
+    libc.src.errno.errno
+    libc.src.math.acosf16  
+)
+
 add_fp_unittest(
   atanf_test
   SUITE
diff --git a/libc/test/src/math/smoke/acospif16_test.cpp b/libc/test/src/math/smoke/acospif16_test.cpp
new file mode 100644
index 0000000000000..292cc8d07e2de
--- /dev/null
+++ b/libc/test/src/math/smoke/acospif16_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for acospif16 -------------------------------------------===//
+//
+//
+// 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/acospif16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"

>From 3c83bff5753d592a54b4e800e228a762d0d599d4 Mon Sep 17 00:00:00 2001
From: amemov <shepelev777 at gmail.com>
Date: Mon, 24 Mar 2025 14:38:29 +0000
Subject: [PATCH 2/7] Implemented the function and tests - Implemented
 acospif16.cpp - Implemented acospif16_test.cpp for both unit tests and
 exhaustive tests

TODO:
- Before editing, ninja check-libc was failing the tests. Need to fix
---
 libc/src/math/acospif16.h                   |  3 ++-
 libc/src/math/generic/acospif16.cpp         | 19 ++++++-------
 libc/test/src/math/acospif16_test.cpp       | 30 +++++++++++++++++++++
 libc/test/src/math/smoke/acospif16_test.cpp | 25 +++++++++++++++++
 4 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/libc/src/math/acospif16.h b/libc/src/math/acospif16.h
index c6903af70b393..6145bf4b949ef 100644
--- a/libc/src/math/acospif16.h
+++ b/libc/src/math/acospif16.h
@@ -11,6 +11,7 @@
 
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/properties/types.h"
+#include "src/math/acosf16.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
@@ -18,4 +19,4 @@ float16 acospif16(float16 x);
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC_MATH_ACOSPIF16_H
\ No newline at end of file
+#endif // LLVM_LIBC_SRC_MATH_ACOSPIF16_H
diff --git a/libc/src/math/generic/acospif16.cpp b/libc/src/math/generic/acospif16.cpp
index 99eb9e31f7821..2fab197fff5c2 100644
--- a/libc/src/math/generic/acospif16.cpp
+++ b/libc/src/math/generic/acospif16.cpp
@@ -8,13 +8,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/math/acospif16.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/macros/optimization.h"
\ No newline at end of file
+
+namespace LIBC_NAMESPACE_DECL {
+// Generated by Sollya using the following command:
+// > round(pi, SG, RN);
+static constexpr float PI = 0x1.921fb6p1f;
+
+LLVM_LIBC_FUNCTION(float16, acospif16, (float16 x)) {
+    return fputil::cast<float16>(acosf16(x) / PI);  
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/math/acospif16_test.cpp b/libc/test/src/math/acospif16_test.cpp
index 91d668373a973..d600973489f01 100644
--- a/libc/test/src/math/acospif16_test.cpp
+++ b/libc/test/src/math/acospif16_test.cpp
@@ -10,3 +10,33 @@
 #include "test/UnitTest/FPMatcher.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcAcospif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+// Range: [0, Inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7c00U;
+
+// Range: [-Inf, 0]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xfc00U;
+
+TEST_F(LlvmLibcAcospif16Test, PositiveRange) {
+  for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
+    float16 x = FPBits(v).get_val();
+
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, x,
+                                   LIBC_NAMESPACE::acospif16(x), 0.5);
+  }
+}
+
+TEST_F(LlvmLibcAcospif16Test, NegativeRange) {
+  for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
+    float16 x = FPBits(v).get_val();
+
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, x,
+                                   LIBC_NAMESPACE::acospif16(x), 0.5);
+  }
+}
\ No newline at end of file
diff --git a/libc/test/src/math/smoke/acospif16_test.cpp b/libc/test/src/math/smoke/acospif16_test.cpp
index 292cc8d07e2de..9e39b55c4f792 100644
--- a/libc/test/src/math/smoke/acospif16_test.cpp
+++ b/libc/test/src/math/smoke/acospif16_test.cpp
@@ -11,3 +11,28 @@
 #include "src/math/acospif16.h"
 #include "test/UnitTest/FPMatcher.h"
 #include "test/UnitTest/Test.h"
+
+using LlvmLibcAcospif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+TEST_F(LlvmLibcAcospif16Test, SpecialNumbers) {
+    LIBC_NAMESPACE::libc_errno = 0;
+    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(aNaN));
+    EXPECT_MATH_ERRNO(0);
+  
+    EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acospif16(sNaN), FE_INVALID);
+    EXPECT_MATH_ERRNO(0);
+  
+    EXPECT_FP_EQ(zero, LIBC_NAMESPACE::acospif16(1.0f));
+    EXPECT_MATH_ERRNO(0);
+  
+    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(inf));
+    EXPECT_MATH_ERRNO(EDOM);
+  
+    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(neg_inf));
+    EXPECT_MATH_ERRNO(EDOM);
+  
+    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(2.0f));
+    EXPECT_MATH_ERRNO(EDOM);
+  
+    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(-2.0f));
+    EXPECT_MATH_ERRNO(EDOM);
+  }
\ No newline at end of file

>From 7c0fa527bbec941f8311c009f607a0fa821772a5 Mon Sep 17 00:00:00 2001
From: amemov <shepelev777 at gmail.com>
Date: Mon, 24 Mar 2025 14:58:35 +0000
Subject: [PATCH 3/7] Implemented the function and tests - Implemented
 acospif16.cpp - Implemented acospif16_test.cpp for both unit tests and
 exhaustive tests

TODO:
- Before editing, ninja check-libc was failing the tests. Need to fix that or run my  tests in isolation. On the surface, looks like it should work just fine, but further work would need to be done at least on my machine.
---
 libc/src/math/acospif16.h                   | 44 +++++------
 libc/test/src/math/acosf16_test.cpp         |  2 +-
 libc/test/src/math/acospif16_test.cpp       | 82 ++++++++++-----------
 libc/test/src/math/smoke/acospif16_test.cpp | 74 +++++++++----------
 4 files changed, 101 insertions(+), 101 deletions(-)

diff --git a/libc/src/math/acospif16.h b/libc/src/math/acospif16.h
index 6145bf4b949ef..38b1fe0a66be5 100644
--- a/libc/src/math/acospif16.h
+++ b/libc/src/math/acospif16.h
@@ -1,22 +1,22 @@
-//===-- Implementation header for acospif16 ---------------------*- 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_ACOSPIF16_H
-#define LLVM_LIBC_SRC_MATH_ACOSPIF16_H
-
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/properties/types.h"
-#include "src/math/acosf16.h"
-
-namespace LIBC_NAMESPACE_DECL {
-
-float16 acospif16(float16 x);
-
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC_MATH_ACOSPIF16_H
+//===-- Implementation header for acospif16 ---------------------*- 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_ACOSPIF16_H
+#define LLVM_LIBC_SRC_MATH_ACOSPIF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+#include "src/math/acosf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float16 acospif16(float16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ACOSPIF16_H
diff --git a/libc/test/src/math/acosf16_test.cpp b/libc/test/src/math/acosf16_test.cpp
index f4890c81b0bcb..83f986bce9991 100644
--- a/libc/test/src/math/acosf16_test.cpp
+++ b/libc/test/src/math/acosf16_test.cpp
@@ -10,7 +10,7 @@
 #include "test/UnitTest/FPMatcher.h"
 #include "test/UnitTest/Test.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
-
+ 
 using LlvmLibcAcosf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
 
 namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/libc/test/src/math/acospif16_test.cpp b/libc/test/src/math/acospif16_test.cpp
index d600973489f01..cc18dc1541a33 100644
--- a/libc/test/src/math/acospif16_test.cpp
+++ b/libc/test/src/math/acospif16_test.cpp
@@ -1,42 +1,42 @@
-//===-- Exhaustive test for acospif16 -------------------------------------===//
-//
-// 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/acospif16.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include "utils/MPFRWrapper/MPFRUtils.h"
-
-using LlvmLibcAcospif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
-
-namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-
-// Range: [0, Inf]
-static constexpr uint16_t POS_START = 0x0000U;
-static constexpr uint16_t POS_STOP = 0x7c00U;
-
-// Range: [-Inf, 0]
-static constexpr uint16_t NEG_START = 0x8000U;
-static constexpr uint16_t NEG_STOP = 0xfc00U;
-
-TEST_F(LlvmLibcAcospif16Test, PositiveRange) {
-  for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
-    float16 x = FPBits(v).get_val();
-
-    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, x,
-                                   LIBC_NAMESPACE::acospif16(x), 0.5);
-  }
-}
-
-TEST_F(LlvmLibcAcospif16Test, NegativeRange) {
-  for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
-    float16 x = FPBits(v).get_val();
-
-    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, x,
-                                   LIBC_NAMESPACE::acospif16(x), 0.5);
-  }
+//===-- Exhaustive test for acospif16 -------------------------------------===//
+//
+// 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/acospif16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcAcospif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+// Range: [0, Inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7c00U;
+
+// Range: [-Inf, 0]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xfc00U;
+
+TEST_F(LlvmLibcAcospif16Test, PositiveRange) {
+  for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
+    float16 x = FPBits(v).get_val();
+
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, x,
+                                   LIBC_NAMESPACE::acospif16(x), 0.5);
+  }
+}
+
+TEST_F(LlvmLibcAcospif16Test, NegativeRange) {
+  for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
+    float16 x = FPBits(v).get_val();
+
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, x,
+                                   LIBC_NAMESPACE::acospif16(x), 0.5);
+  }
 }
\ No newline at end of file
diff --git a/libc/test/src/math/smoke/acospif16_test.cpp b/libc/test/src/math/smoke/acospif16_test.cpp
index 9e39b55c4f792..9316a9d4b381f 100644
--- a/libc/test/src/math/smoke/acospif16_test.cpp
+++ b/libc/test/src/math/smoke/acospif16_test.cpp
@@ -1,38 +1,38 @@
-//===-- Unittests for acospif16 -------------------------------------------===//
-//
-//
-// 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/acospif16.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-
-using LlvmLibcAcospif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
-TEST_F(LlvmLibcAcospif16Test, SpecialNumbers) {
-    LIBC_NAMESPACE::libc_errno = 0;
-    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(aNaN));
-    EXPECT_MATH_ERRNO(0);
-  
-    EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acospif16(sNaN), FE_INVALID);
-    EXPECT_MATH_ERRNO(0);
-  
-    EXPECT_FP_EQ(zero, LIBC_NAMESPACE::acospif16(1.0f));
-    EXPECT_MATH_ERRNO(0);
-  
-    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(inf));
-    EXPECT_MATH_ERRNO(EDOM);
-  
-    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(neg_inf));
-    EXPECT_MATH_ERRNO(EDOM);
-  
-    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(2.0f));
-    EXPECT_MATH_ERRNO(EDOM);
-  
-    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(-2.0f));
-    EXPECT_MATH_ERRNO(EDOM);
+//===-- Unittests for acospif16 -------------------------------------------===//
+//
+//
+// 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/acospif16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcAcospif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+TEST_F(LlvmLibcAcospif16Test, SpecialNumbers) {
+    LIBC_NAMESPACE::libc_errno = 0;
+    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(aNaN));
+    EXPECT_MATH_ERRNO(0);
+  
+    EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acospif16(sNaN), FE_INVALID);
+    EXPECT_MATH_ERRNO(0);
+  
+    EXPECT_FP_EQ(zero, LIBC_NAMESPACE::acospif16(1.0f));
+    EXPECT_MATH_ERRNO(0);
+  
+    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(inf));
+    EXPECT_MATH_ERRNO(EDOM);
+  
+    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(neg_inf));
+    EXPECT_MATH_ERRNO(EDOM);
+  
+    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(2.0f));
+    EXPECT_MATH_ERRNO(EDOM);
+  
+    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(-2.0f));
+    EXPECT_MATH_ERRNO(EDOM);
   }
\ No newline at end of file

>From 286384f3aa4f3b6bd606ff52c09c3a2179488560 Mon Sep 17 00:00:00 2001
From: amemov <shepelev777 at gmail.com>
Date: Mon, 24 Mar 2025 17:27:07 +0000
Subject: [PATCH 4/7] Addressed the issue in testfiles: - Fixed the warnings
 from testfiles due to lack of \n character at the end of file - Updated the
 dependencies in CMakeLists for both exhaustive and unit tests

---
 libc/test/src/math/CMakeLists.txt           | 1 +
 libc/test/src/math/acospif16_test.cpp       | 2 +-
 libc/test/src/math/smoke/CMakeLists.txt     | 3 ++-
 libc/test/src/math/smoke/acospif16_test.cpp | 3 ++-
 4 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index c52aef996b956..b24d4a663693e 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2229,6 +2229,7 @@ add_fp_unittest(
   SRCS
     acospif16_test.cpp
   DEPENDS
+    libc.src.math.acospif16
     libc.src.math.acosf16  
 )
 
diff --git a/libc/test/src/math/acospif16_test.cpp b/libc/test/src/math/acospif16_test.cpp
index cc18dc1541a33..1998dfb38a55e 100644
--- a/libc/test/src/math/acospif16_test.cpp
+++ b/libc/test/src/math/acospif16_test.cpp
@@ -39,4 +39,4 @@ TEST_F(LlvmLibcAcospif16Test, NegativeRange) {
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, x,
                                    LIBC_NAMESPACE::acospif16(x), 0.5);
   }
-}
\ No newline at end of file
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index f6801e10ca4bc..c7b88a33d37b9 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -3999,7 +3999,8 @@ add_fp_unittest(
     acospif16_test.cpp
   DEPENDS
     libc.src.errno.errno
-    libc.src.math.acosf16  
+    libc.src.math.acospif16  
+    libc.src.math.acosf16 
 )
 
 add_fp_unittest(
diff --git a/libc/test/src/math/smoke/acospif16_test.cpp b/libc/test/src/math/smoke/acospif16_test.cpp
index 9316a9d4b381f..d704af607291e 100644
--- a/libc/test/src/math/smoke/acospif16_test.cpp
+++ b/libc/test/src/math/smoke/acospif16_test.cpp
@@ -35,4 +35,5 @@ TEST_F(LlvmLibcAcospif16Test, SpecialNumbers) {
   
     EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(-2.0f));
     EXPECT_MATH_ERRNO(EDOM);
-  }
\ No newline at end of file
+  }
+  
\ No newline at end of file

>From a920dfc130927995353d9959014a6b99fce58280 Mon Sep 17 00:00:00 2001
From: amemov <shepelev777 at gmail.com>
Date: Tue, 25 Mar 2025 17:15:12 +0000
Subject: [PATCH 5/7] Added support for mpfr_acospi in MPFRWrapper: - Updated
 the corresponding files in MPFRWrapper to make mpfr::Operation::Acospi work
 for testing

Revised exhaustive testfile:
- Replaced mpfr::Operation::Acos with mpfr::Operation::Acospi for correct expected behavior

Ran clang-format on modified .cpp and .h files

TODO: Revise acospif16.cpp to work independently of acosf16
---
 libc/test/src/math/acospif16_test.cpp       |  4 +-
 libc/test/src/math/smoke/acospif16_test.cpp | 46 ++++++++++-----------
 libc/utils/MPFRWrapper/MPCommon.cpp         |  6 +++
 libc/utils/MPFRWrapper/MPCommon.h           |  1 +
 libc/utils/MPFRWrapper/MPFRUtils.cpp        |  2 +
 libc/utils/MPFRWrapper/MPFRUtils.h          |  1 +
 6 files changed, 35 insertions(+), 25 deletions(-)

diff --git a/libc/test/src/math/acospif16_test.cpp b/libc/test/src/math/acospif16_test.cpp
index 1998dfb38a55e..e15449b1067e8 100644
--- a/libc/test/src/math/acospif16_test.cpp
+++ b/libc/test/src/math/acospif16_test.cpp
@@ -27,7 +27,7 @@ TEST_F(LlvmLibcAcospif16Test, PositiveRange) {
   for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
     float16 x = FPBits(v).get_val();
 
-    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, x,
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acospi, x,
                                    LIBC_NAMESPACE::acospif16(x), 0.5);
   }
 }
@@ -36,7 +36,7 @@ TEST_F(LlvmLibcAcospif16Test, NegativeRange) {
   for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
     float16 x = FPBits(v).get_val();
 
-    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, x,
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acospi, x,
                                    LIBC_NAMESPACE::acospif16(x), 0.5);
   }
 }
diff --git a/libc/test/src/math/smoke/acospif16_test.cpp b/libc/test/src/math/smoke/acospif16_test.cpp
index d704af607291e..dbae2c93c78e6 100644
--- a/libc/test/src/math/smoke/acospif16_test.cpp
+++ b/libc/test/src/math/smoke/acospif16_test.cpp
@@ -14,26 +14,26 @@
 
 using LlvmLibcAcospif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
 TEST_F(LlvmLibcAcospif16Test, SpecialNumbers) {
-    LIBC_NAMESPACE::libc_errno = 0;
-    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(aNaN));
-    EXPECT_MATH_ERRNO(0);
-  
-    EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acospif16(sNaN), FE_INVALID);
-    EXPECT_MATH_ERRNO(0);
-  
-    EXPECT_FP_EQ(zero, LIBC_NAMESPACE::acospif16(1.0f));
-    EXPECT_MATH_ERRNO(0);
-  
-    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(inf));
-    EXPECT_MATH_ERRNO(EDOM);
-  
-    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(neg_inf));
-    EXPECT_MATH_ERRNO(EDOM);
-  
-    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(2.0f));
-    EXPECT_MATH_ERRNO(EDOM);
-  
-    EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(-2.0f));
-    EXPECT_MATH_ERRNO(EDOM);
-  }
-  
\ No newline at end of file
+  LIBC_NAMESPACE::libc_errno = 0;
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acospif16(sNaN),
+                              FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(zero, LIBC_NAMESPACE::acospif16(1.0f));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(inf));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(neg_inf));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(2.0f));
+  EXPECT_MATH_ERRNO(EDOM);
+
+  EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acospif16(-2.0f));
+  EXPECT_MATH_ERRNO(EDOM);
+}
diff --git a/libc/utils/MPFRWrapper/MPCommon.cpp b/libc/utils/MPFRWrapper/MPCommon.cpp
index ac8cde2f97221..1edc4332a9c6f 100644
--- a/libc/utils/MPFRWrapper/MPCommon.cpp
+++ b/libc/utils/MPFRWrapper/MPCommon.cpp
@@ -70,6 +70,12 @@ MPFRNumber MPFRNumber::acosh() const {
   return result;
 }
 
+MPFRNumber MPFRNumber::acospi() const {
+  MPFRNumber result(*this);
+  mpfr_acospi(result.value, value, mpfr_rounding);
+  return result;
+}
+
 MPFRNumber MPFRNumber::add(const MPFRNumber &b) const {
   MPFRNumber result(*this);
   mpfr_add(result.value, value, b.value, mpfr_rounding);
diff --git a/libc/utils/MPFRWrapper/MPCommon.h b/libc/utils/MPFRWrapper/MPCommon.h
index eaa512e30bc86..99cb7ec66a2ca 100644
--- a/libc/utils/MPFRWrapper/MPCommon.h
+++ b/libc/utils/MPFRWrapper/MPCommon.h
@@ -181,6 +181,7 @@ class MPFRNumber {
   MPFRNumber abs() const;
   MPFRNumber acos() const;
   MPFRNumber acosh() const;
+  MPFRNumber acospi() const;
   MPFRNumber add(const MPFRNumber &b) const;
   MPFRNumber asin() const;
   MPFRNumber asinh() const;
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index fc260f4abed49..de50d25c6f250 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -32,6 +32,8 @@ unary_operation(Operation op, InputType input, unsigned int precision,
     return mpfrInput.acos();
   case Operation::Acosh:
     return mpfrInput.acosh();
+  case Operation::Acospi:
+    return mpfrInput.acospi();
   case Operation::Asin:
     return mpfrInput.asin();
   case Operation::Asinh:
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.h b/libc/utils/MPFRWrapper/MPFRUtils.h
index bc65f87c6b5ab..c77a6aa3adeae 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.h
+++ b/libc/utils/MPFRWrapper/MPFRUtils.h
@@ -28,6 +28,7 @@ enum class Operation : int {
   Abs,
   Acos,
   Acosh,
+  Acospi,
   Asin,
   Asinh,
   Atan,

>From 909b8c1bb50448c410dae7f2507e5496e3daea2b Mon Sep 17 00:00:00 2001
From: Anton <shepelev777 at gmail.com>
Date: Fri, 4 Apr 2025 11:19:19 -0400
Subject: [PATCH 6/7] Rewrote the implementation for acospif16: - Essentially
 follows the same structure. For cases 0, (1 / -1) returns corresponding
 values - Polynomials - same, computes just like acospi, but the end result is
 multiplied with 1/pi obtained from Sollya

---
 libc/src/math/acospif16.h           |   1 -
 libc/src/math/generic/acospif16.cpp | 131 +++++++++++++++++++++++++++-
 2 files changed, 128 insertions(+), 4 deletions(-)

diff --git a/libc/src/math/acospif16.h b/libc/src/math/acospif16.h
index 38b1fe0a66be5..d579c42b19706 100644
--- a/libc/src/math/acospif16.h
+++ b/libc/src/math/acospif16.h
@@ -11,7 +11,6 @@
 
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/properties/types.h"
-#include "src/math/acosf16.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/src/math/generic/acospif16.cpp b/libc/src/math/generic/acospif16.cpp
index 2fab197fff5c2..6adf69cbe39eb 100644
--- a/libc/src/math/generic/acospif16.cpp
+++ b/libc/src/math/generic/acospif16.cpp
@@ -8,14 +8,139 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/math/acospif16.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/macros/optimization.h" // remove unnecessary includes
 
 namespace LIBC_NAMESPACE_DECL {
+
 // Generated by Sollya using the following command:
-// > round(pi, SG, RN);
-static constexpr float PI = 0x1.921fb6p1f;
+// > round(2/pi, SG, RN);
+// > round(1/pi, SG, RN);
+static constexpr float TWO_DIV_PI = 0x1.45f306p-1f;
+static constexpr float PI_INV = 0x1.45f306p-2f;
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+static constexpr size_t N_EXCEPTS = 2;
 
 LLVM_LIBC_FUNCTION(float16, acospif16, (float16 x)) {
-    return fputil::cast<float16>(acosf16(x) / PI);  
+  using FPBits = fputil::FPBits<float16>;
+  FPBits xbits(x);
+
+  uint16_t x_u = xbits.uintval();
+  uint16_t x_abs = x_u & 0x7fff;
+  uint16_t x_sign = x_u >> 15;
+
+  // |x| > 0x1p0, |x| > 1, or x is NaN.
+  if (LIBC_UNLIKELY(x_abs > 0x3c00)) {
+    // acospif16(NaN) = NaN
+    if (xbits.is_nan()) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+        return FPBits::quiet_nan().get_val();
+      }
+
+      return x;
+    }
+
+    // 1 < |x| <= +/-inf
+    fputil::raise_except_if_required(FE_INVALID);
+    fputil::set_errno_if_required(EDOM);
+
+    return FPBits::quiet_nan().get_val();
+  }
+
+  // TODO: handling for exception values
+
+  // |x| == 0x1p0, x is 1 or -1
+  // if x is (-)1, return 1
+  // if x is (+)1, return 0
+  if (LIBC_UNLIKELY(x_abs == 0x3c00))
+    return fputil::cast<float16>(x_sign ? 1.0f : 0.0f);
+
+  float xf = x;
+  float xsq = xf * xf;
+
+  // |x| <= 0x1p-1, |x| <= 0.5
+  if (x_abs <= 0x3800) {
+    // if x is 0, return 0.5
+    if (LIBC_UNLIKELY(x_abs == 0))
+      return fputil::cast<float16>(0.5f);
+
+    // Note that: acos(x) = pi/2 + asin(-x) = pi/2 - asin(x), then
+    //            acospi(x) = 0.5 - asin(x)*(INVERSE_PI)
+    // Degree-6 minimax polynomial of asin(x) generated by Sollya with:
+    // > P = fpminimax(asin(x)/(x), [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
+    float xf_divided = xf * PI_INV;
+    float interm =
+        fputil::polyeval(xsq, 0x1.000002p0f, 0x1.554c2ap-3f, 0x1.3541ccp-4f,
+                         0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
+
+    // Same as acos(x), but devided the expression with pi
+    return fputil::cast<float16>(
+        fputil::multiply_add(-xf_divided, interm, 0.5f));
+  }
+
+  // When |x| > 0.5, assume that 0.5 < |x| <= 1
+  //
+  // Step-by-step range-reduction proof:
+  // 1:  Let y = asin(x), such that, x = sin(y)
+  // 2:  From complimentary angle identity:
+  //       x = sin(y) = cos(pi/2 - y)
+  // 3:  Let z = pi/2 - y, such that x = cos(z)
+  // 4:  From double angle formula; cos(2A) = 1 - 2 * sin^2(A):
+  //       z = 2A, z/2 = A
+  //       cos(z) = 1 - 2 * sin^2(z/2)
+  // 5:  Make sin(z/2) subject of the formula:
+  //       sin(z/2) = sqrt((1 - cos(z))/2)
+  // 6:  Recall [3]; x = cos(z). Therefore:
+  //       sin(z/2) = sqrt((1 - x)/2)
+  // 7:  Let u = (1 - x)/2
+  // 8:  Therefore:
+  //       asin(sqrt(u)) = z/2
+  //       2 * asin(sqrt(u)) = z
+  // 9:  Recall [3]; z = pi/2 - y. Therefore:
+  //       y = pi/2 - z
+  //       y = pi/2 - 2 * asin(sqrt(u))
+  // 10: Recall [1], y = asin(x). Therefore:
+  //       asin(x) = pi/2 - 2 * asin(sqrt(u))
+  // 11: Recall that: acos(x) = pi/2 + asin(-x) = pi/2 - asin(x)
+  //     Therefore:
+  //       acos(x) = pi/2 - (pi/2 - 2 * asin(sqrt(u)))
+  //       acos(x) = 2 * asin(sqrt(u))
+  //
+  // THE RANGE REDUCTION, HOW?
+  // 12: Recall [7], u = (1 - x)/2
+  // 13: Since 0.5 < x <= 1, therefore:
+  //       0 <= u <= 0.25 and 0 <= sqrt(u) <= 0.5
+  //
+  // Hence, we can reuse the same [0, 0.5] domain polynomial approximation for
+  // Step [11] as `sqrt(u)` is in range.
+  // When -1 < x <= -0.5, the identity:
+  //       acos(x) = pi - acos(-x)
+  // allows us to compute for the negative x value (lhs)
+  // with a positive x value instead (rhs).
+
+  float xf_abs = (xf < 0 ? -xf : xf);
+  float u = fputil::multiply_add(-0.5f, xf_abs, 0.5f);
+  float sqrt_u = fputil::sqrt<float>(u);
+
+  // Degree-6 minimax polynomial of asin(x) generated by Sollya with:
+  // > P = fpminimax(asin(x)/(x), [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
+  float asin_sqrt_u =
+      sqrt_u * fputil::polyeval(u, 0x1.000002p0f, 0x1.554c2ap-3f,
+                                0x1.3541ccp-4f, 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
+
+  // Same as acos(x), but devided the expression with pi
+  return fputil::cast<float16>(
+      x_sign ? fputil::multiply_add(-TWO_DIV_PI, asin_sqrt_u, 1.0f)
+             : TWO_DIV_PI * asin_sqrt_u);
 }
 } // namespace LIBC_NAMESPACE_DECL

>From a2b39786b29843e8353a9e5cd383905e9298df72 Mon Sep 17 00:00:00 2001
From: amemov <shepelev777 at gmail.com>
Date: Sun, 6 Apr 2025 23:42:06 +0000
Subject: [PATCH 7/7] Addressed the comments: - Deleted irrelevant declarations
 - Changed polynomial for asin(x)/(x*pi) - Relocated polynomial coefficients
 into constexpr array of floats - Changed the comments where polynomials used

---
 libc/config/linux/x86_64/entrypoints.txt |  3 ++
 libc/src/math/generic/acospif16.cpp      | 41 +++++++++---------------
 2 files changed, 19 insertions(+), 25 deletions(-)

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 2f1e16cd20a0e..269cb06b72511 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -655,6 +655,9 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.asinf16
     libc.src.math.acosf16
     libc.src.math.acospif16
+    libc.src.math.acoshf16
+    libc.src.math.asinf16
+    libc.src.math.asinhf16
     libc.src.math.canonicalizef16
     libc.src.math.ceilf16
     libc.src.math.copysignf16
diff --git a/libc/src/math/generic/acospif16.cpp b/libc/src/math/generic/acospif16.cpp
index 6adf69cbe39eb..59f851b8675a3 100644
--- a/libc/src/math/generic/acospif16.cpp
+++ b/libc/src/math/generic/acospif16.cpp
@@ -21,15 +21,6 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-// Generated by Sollya using the following command:
-// > round(2/pi, SG, RN);
-// > round(1/pi, SG, RN);
-static constexpr float TWO_DIV_PI = 0x1.45f306p-1f;
-static constexpr float PI_INV = 0x1.45f306p-2f;
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-static constexpr size_t N_EXCEPTS = 2;
-
 LLVM_LIBC_FUNCTION(float16, acospif16, (float16 x)) {
   using FPBits = fputil::FPBits<float16>;
   FPBits xbits(x);
@@ -57,8 +48,6 @@ LLVM_LIBC_FUNCTION(float16, acospif16, (float16 x)) {
     return FPBits::quiet_nan().get_val();
   }
 
-  // TODO: handling for exception values
-
   // |x| == 0x1p0, x is 1 or -1
   // if x is (-)1, return 1
   // if x is (+)1, return 0
@@ -67,7 +56,9 @@ LLVM_LIBC_FUNCTION(float16, acospif16, (float16 x)) {
 
   float xf = x;
   float xsq = xf * xf;
-
+  constexpr float poly_coeffs[5] = {0x1.45f308p-2f, 0x1.b2900cp-5f,
+                                    0x1.897e36p-6f, 0x1.9efafcp-7f,
+                                    0x1.06d884p-6f};
   // |x| <= 0x1p-1, |x| <= 0.5
   if (x_abs <= 0x3800) {
     // if x is 0, return 0.5
@@ -75,17 +66,15 @@ LLVM_LIBC_FUNCTION(float16, acospif16, (float16 x)) {
       return fputil::cast<float16>(0.5f);
 
     // Note that: acos(x) = pi/2 + asin(-x) = pi/2 - asin(x), then
-    //            acospi(x) = 0.5 - asin(x)*(INVERSE_PI)
+    //            acospi(x) = 0.5 - asin(x)/pi
     // Degree-6 minimax polynomial of asin(x) generated by Sollya with:
-    // > P = fpminimax(asin(x)/(x), [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
-    float xf_divided = xf * PI_INV;
+    // > P = fpminimax(asin(x)/(pi * x), [|0, 2, 4, 6, 8|], [|SG...|], [0,
+    // 0.5]);
     float interm =
-        fputil::polyeval(xsq, 0x1.000002p0f, 0x1.554c2ap-3f, 0x1.3541ccp-4f,
-                         0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
+        fputil::polyeval(xsq, poly_coeffs[0], poly_coeffs[1], poly_coeffs[2],
+                         poly_coeffs[3], poly_coeffs[4]);
 
-    // Same as acos(x), but devided the expression with pi
-    return fputil::cast<float16>(
-        fputil::multiply_add(-xf_divided, interm, 0.5f));
+    return fputil::cast<float16>(fputil::multiply_add(-xf, interm, 0.5f));
   }
 
   // When |x| > 0.5, assume that 0.5 < |x| <= 1
@@ -115,6 +104,7 @@ LLVM_LIBC_FUNCTION(float16, acospif16, (float16 x)) {
   //     Therefore:
   //       acos(x) = pi/2 - (pi/2 - 2 * asin(sqrt(u)))
   //       acos(x) = 2 * asin(sqrt(u))
+  //       acospi(x) = 2 * (asin(sqrt(u)) / pi)
   //
   // THE RANGE REDUCTION, HOW?
   // 12: Recall [7], u = (1 - x)/2
@@ -125,6 +115,7 @@ LLVM_LIBC_FUNCTION(float16, acospif16, (float16 x)) {
   // Step [11] as `sqrt(u)` is in range.
   // When -1 < x <= -0.5, the identity:
   //       acos(x) = pi - acos(-x)
+  //       acospi(x) = 1 - acos(-x)/pi
   // allows us to compute for the negative x value (lhs)
   // with a positive x value instead (rhs).
 
@@ -133,14 +124,14 @@ LLVM_LIBC_FUNCTION(float16, acospif16, (float16 x)) {
   float sqrt_u = fputil::sqrt<float>(u);
 
   // Degree-6 minimax polynomial of asin(x) generated by Sollya with:
-  // > P = fpminimax(asin(x)/(x), [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
+  // > P = fpminimax(asin(x)/(pi * x), [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
   float asin_sqrt_u =
-      sqrt_u * fputil::polyeval(u, 0x1.000002p0f, 0x1.554c2ap-3f,
-                                0x1.3541ccp-4f, 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
+      sqrt_u * fputil::polyeval(u, poly_coeffs[0], poly_coeffs[1],
+                                poly_coeffs[2], poly_coeffs[3], poly_coeffs[4]);
 
   // Same as acos(x), but devided the expression with pi
   return fputil::cast<float16>(
-      x_sign ? fputil::multiply_add(-TWO_DIV_PI, asin_sqrt_u, 1.0f)
-             : TWO_DIV_PI * asin_sqrt_u);
+      x_sign ? fputil::multiply_add(-2.0f, asin_sqrt_u, 1.0f)
+             : 2.0f * asin_sqrt_u);
 }
 } // namespace LIBC_NAMESPACE_DECL



More information about the libc-commits mailing list