llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-libc Author: Muhammad Bassiouni (bassiounix) <details> <summary>Changes</summary> Part of #<!-- -->147386 in preparation for: https://discourse.llvm.org/t/rfc-make-clang-builtin-math-functions-constexpr-with-llvm-libc-to-support-c-23-constexpr-math-functions/86450 --- Full diff: https://github.com/llvm/llvm-project/pull/150849.diff 10 Files Affected: - (modified) libc/shared/math.h (+1) - (modified) libc/shared/math/asinf16.h (+1-1) - (added) libc/shared/math/asinhf16.h (+28) - (modified) libc/src/__support/math/CMakeLists.txt (+18) - (added) libc/src/__support/math/asinhf16.h (+123) - (modified) libc/src/math/generic/CMakeLists.txt (+1-12) - (modified) libc/src/math/generic/asinhf16.cpp (+2-94) - (modified) libc/test/shared/CMakeLists.txt (+1) - (modified) libc/test/shared/shared_math_test.cpp (+1) - (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+25) ``````````diff diff --git a/libc/shared/math.h b/libc/shared/math.h index e0f00f52e9dc3..26e33ecd45d73 100644 --- a/libc/shared/math.h +++ b/libc/shared/math.h @@ -21,6 +21,7 @@ #include "math/asinf.h" #include "math/asinf16.h" #include "math/asinhf.h" +#include "math/asinhf16.h" #include "math/erff.h" #include "math/exp.h" #include "math/exp10.h" diff --git a/libc/shared/math/asinf16.h b/libc/shared/math/asinf16.h index d545e269a6402..af5b2ec179233 100644 --- a/libc/shared/math/asinf16.h +++ b/libc/shared/math/asinf16.h @@ -25,4 +25,4 @@ using math::asinf16; #endif // LIBC_TYPES_HAS_FLOAT16 -#endif // LLVM_LIBC_SHARED_MATH_ASINF_H +#endif // LLVM_LIBC_SHARED_MATH_ASINF16_H diff --git a/libc/shared/math/asinhf16.h b/libc/shared/math/asinhf16.h new file mode 100644 index 0000000000000..1a0525b6a9b8b --- /dev/null +++ b/libc/shared/math/asinhf16.h @@ -0,0 +1,28 @@ +//===-- Shared asinhf16 function ---------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SHARED_MATH_ASINHF16_H +#define LLVM_LIBC_SHARED_MATH_ASINHF16_H + +#include "shared/libc_common.h" + +#ifdef LIBC_TYPES_HAS_FLOAT16 + +#include "src/__support/math/asinhf16.h" + +namespace LIBC_NAMESPACE_DECL { +namespace shared { + +using math::asinhf16; + +} // namespace shared +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_FLOAT16 + +#endif // LLVM_LIBC_SHARED_MATH_ASINHF16_H diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt index 13f46a13fe0d7..be208f946024a 100644 --- a/libc/src/__support/math/CMakeLists.txt +++ b/libc/src/__support/math/CMakeLists.txt @@ -154,6 +154,24 @@ add_header_library( libc.src.__support.macros.optimization ) +add_header_library( + asinhf16 + HDRS + asinhf16.h +DEPENDS + .acoshf_utils + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.except_value_utils + libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.rounding_mode + libc.src.__support.FPUtil.sqrt + libc.src.__support.macros.config + libc.src.__support.macros.optimization +) + add_header_library( asinf HDRS diff --git a/libc/src/__support/math/asinhf16.h b/libc/src/__support/math/asinhf16.h new file mode 100644 index 0000000000000..81657b8db97b0 --- /dev/null +++ b/libc/src/__support/math/asinhf16.h @@ -0,0 +1,123 @@ +//===-- Implementation header for asinhf16 ----------------------*- 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___SUPPORT_MATH_ASINHF16_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_ASINHF16_H + +#include "include/llvm-libc-macros/float16-macros.h" + +#ifdef LIBC_TYPES_HAS_FLOAT16 + +#include "acoshf_utils.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/rounding_mode.h" +#include "src/__support/FPUtil/sqrt.h" +#include "src/__support/macros/config.h" +#include "src/__support/macros/optimization.h" + +namespace LIBC_NAMESPACE_DECL { + +namespace math { + +LIBC_INLINE static constexpr float16 asinhf16(float16 x) { + +#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS + constexpr size_t N_EXCEPTS = 8; + + constexpr fputil::ExceptValues<float16, N_EXCEPTS> ASINHF16_EXCEPTS{{ + // (input, RZ output, RU offset, RD offset, RN offset) + + // x = 0x1.da4p-2, asinhf16(x) = 0x1.ca8p-2 (RZ) + {0x3769, 0x372a, 1, 0, 1}, + // x = 0x1.d6cp-1, asinhf16(x) = 0x1.a58p-1 (RZ) + {0x3b5b, 0x3a96, 1, 0, 0}, + // x = 0x1.c7cp+3, asinhf16(x) = 0x1.accp+1 (RZ) + {0x4b1f, 0x42b3, 1, 0, 0}, + // x = 0x1.26cp+4, asinhf16(x) = 0x1.cd8p+1 (RZ) + {0x4c9b, 0x4336, 1, 0, 1}, + // x = -0x1.da4p-2, asinhf16(x) = -0x1.ca8p-2 (RZ) + {0xb769, 0xb72a, 0, 1, 1}, + // x = -0x1.d6cp-1, asinhf16(x) = -0x1.a58p-1 (RZ) + {0xbb5b, 0xba96, 0, 1, 0}, + // x = -0x1.c7cp+3, asinhf16(x) = -0x1.accp+1 (RZ) + {0xcb1f, 0xc2b3, 0, 1, 0}, + // x = -0x1.26cp+4, asinhf16(x) = -0x1.cd8p+1 (RZ) + {0xcc9b, 0xc336, 0, 1, 1}, +}}; +#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS + + using namespace acoshf_internal; + using FPBits = fputil::FPBits<float16>; + FPBits xbits(x); + + uint16_t x_u = xbits.uintval(); + uint16_t x_abs = x_u & 0x7fff; + + 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(); + } + + return x; + } + +#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS + // Handle exceptional values + if (auto r = ASINHF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value())) + return r.value(); +#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS + + float xf = x; + const float SIGN[2] = {1.0f, -1.0f}; + float x_sign = SIGN[x_u >> 15]; + + // |x| <= 0.25 + if (LIBC_UNLIKELY(x_abs <= 0x3400)) { + // when |x| < 0x1.718p-5, asinhf16(x) = x. Adjust by 1 ULP for certain + // rounding types. + if (LIBC_UNLIKELY(x_abs < 0x29c6)) { + int rounding = fputil::quick_get_round(); + if ((rounding == FE_UPWARD || rounding == FE_TOWARDZERO) && xf < 0) + return fputil::cast<float16>(xf + 0x1p-24f); + if ((rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO) && xf > 0) + return fputil::cast<float16>(xf - 0x1p-24f); + return fputil::cast<float16>(xf); + } + + float x_sq = xf * xf; + // Generated by Sollya with: + // > P = fpminimax(asinh(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 2^-2]); + // The last coefficient 0x1.bd114ep-6f has been changed to 0x1.bd114ep-5f + // for better accuracy. + float p = fputil::polyeval(x_sq, 1.0f, -0x1.555552p-3f, 0x1.332f6ap-4f, + -0x1.6c53dep-5f, 0x1.bd114ep-5f); + + return fputil::cast<float16>(xf * p); + } + + // General case: asinh(x) = ln(x + sqrt(x^2 + 1)) + float sqrt_term = fputil::sqrt<float>(fputil::multiply_add(xf, xf, 1.0f)); + return fputil::cast<float16>( + x_sign * log_eval(fputil::multiply_add(xf, x_sign, sqrt_term))); + + +} + +} // namespace math + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_FLOAT16 + +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ASINHF16_H diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index f91feacbff54d..025b0290bfe70 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -3899,18 +3899,7 @@ add_entrypoint_object( HDRS ../asinhf16.h DEPENDS - .explogxf - 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.rounding_mode - libc.src.__support.FPUtil.sqrt - libc.src.__support.macros.optimization - libc.src.__support.macros.properties.types + libc.src.__support.math.asinhf16 ) add_entrypoint_object( diff --git a/libc/src/math/generic/asinhf16.cpp b/libc/src/math/generic/asinhf16.cpp index 0a0b471d87ecc..d517e633f7bea 100644 --- a/libc/src/math/generic/asinhf16.cpp +++ b/libc/src/math/generic/asinhf16.cpp @@ -7,102 +7,10 @@ //===----------------------------------------------------------------------===// #include "src/math/asinhf16.h" -#include "explogxf.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/rounding_mode.h" -#include "src/__support/FPUtil/sqrt.h" -#include "src/__support/common.h" -#include "src/__support/macros/config.h" -#include "src/__support/macros/optimization.h" +#include "src/__support/math/asinhf16.h" namespace LIBC_NAMESPACE_DECL { -#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS -static constexpr size_t N_EXCEPTS = 8; - -static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ASINHF16_EXCEPTS{{ - // (input, RZ output, RU offset, RD offset, RN offset) - - // x = 0x1.da4p-2, asinhf16(x) = 0x1.ca8p-2 (RZ) - {0x3769, 0x372a, 1, 0, 1}, - // x = 0x1.d6cp-1, asinhf16(x) = 0x1.a58p-1 (RZ) - {0x3b5b, 0x3a96, 1, 0, 0}, - // x = 0x1.c7cp+3, asinhf16(x) = 0x1.accp+1 (RZ) - {0x4b1f, 0x42b3, 1, 0, 0}, - // x = 0x1.26cp+4, asinhf16(x) = 0x1.cd8p+1 (RZ) - {0x4c9b, 0x4336, 1, 0, 1}, - // x = -0x1.da4p-2, asinhf16(x) = -0x1.ca8p-2 (RZ) - {0xb769, 0xb72a, 0, 1, 1}, - // x = -0x1.d6cp-1, asinhf16(x) = -0x1.a58p-1 (RZ) - {0xbb5b, 0xba96, 0, 1, 0}, - // x = -0x1.c7cp+3, asinhf16(x) = -0x1.accp+1 (RZ) - {0xcb1f, 0xc2b3, 0, 1, 0}, - // x = -0x1.26cp+4, asinhf16(x) = -0x1.cd8p+1 (RZ) - {0xcc9b, 0xc336, 0, 1, 1}, -}}; -#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS - -LLVM_LIBC_FUNCTION(float16, asinhf16, (float16 x)) { - using namespace acoshf_internal; - using FPBits = fputil::FPBits<float16>; - FPBits xbits(x); - - uint16_t x_u = xbits.uintval(); - uint16_t x_abs = x_u & 0x7fff; - - 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(); - } - - return x; - } - -#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS - // Handle exceptional values - if (auto r = ASINHF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value())) - return r.value(); -#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS - - float xf = x; - const float SIGN[2] = {1.0f, -1.0f}; - float x_sign = SIGN[x_u >> 15]; - - // |x| <= 0.25 - if (LIBC_UNLIKELY(x_abs <= 0x3400)) { - // when |x| < 0x1.718p-5, asinhf16(x) = x. Adjust by 1 ULP for certain - // rounding types. - if (LIBC_UNLIKELY(x_abs < 0x29c6)) { - int rounding = fputil::quick_get_round(); - if ((rounding == FE_UPWARD || rounding == FE_TOWARDZERO) && xf < 0) - return fputil::cast<float16>(xf + 0x1p-24f); - if ((rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO) && xf > 0) - return fputil::cast<float16>(xf - 0x1p-24f); - return fputil::cast<float16>(xf); - } - - float x_sq = xf * xf; - // Generated by Sollya with: - // > P = fpminimax(asinh(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 2^-2]); - // The last coefficient 0x1.bd114ep-6f has been changed to 0x1.bd114ep-5f - // for better accuracy. - float p = fputil::polyeval(x_sq, 1.0f, -0x1.555552p-3f, 0x1.332f6ap-4f, - -0x1.6c53dep-5f, 0x1.bd114ep-5f); - - return fputil::cast<float16>(xf * p); - } - - // General case: asinh(x) = ln(x + sqrt(x^2 + 1)) - float sqrt_term = fputil::sqrt<float>(fputil::multiply_add(xf, xf, 1.0f)); - return fputil::cast<float16>( - x_sign * log_eval(fputil::multiply_add(xf, x_sign, sqrt_term))); -} +LLVM_LIBC_FUNCTION(float16, asinhf16, (float16 x)) { return math::asinhf16(x); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt index 77f3617841293..7ddf26c1d091c 100644 --- a/libc/test/shared/CMakeLists.txt +++ b/libc/test/shared/CMakeLists.txt @@ -17,6 +17,7 @@ add_fp_unittest( libc.src.__support.math.asinf libc.src.__support.math.asinf16 libc.src.__support.math.asinhf + libc.src.__support.math.asinhf16 libc.src.__support.math.erff libc.src.__support.math.exp libc.src.__support.math.exp10 diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp index 2e4450a9b40e8..3ddea7a6a4aa5 100644 --- a/libc/test/shared/shared_math_test.cpp +++ b/libc/test/shared/shared_math_test.cpp @@ -18,6 +18,7 @@ TEST(LlvmLibcSharedMathTest, AllFloat16) { EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::acoshf16(1.0f16)); EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::acospif16(1.0f16)); EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::asinf16(0.0f16)); + EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::asinhf16(0.0f16)); EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::exp10f16(0.0f16)); diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 0e40d92cb5c97..31334e324e705 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -2245,6 +2245,24 @@ libc_support_library( ], ) +libc_support_library( + name = "__support_math_asinhf16", + hdrs = ["src/__support/math/asinhf16.h"], + deps = [ + ":__support_math_acoshf_utils", + ":__support_fputil_fenv_impl", + ":__support_fputil_fp_bits", + ":__support_fputil_polyeval", + ":__support_fputil_cast", + ":__support_fputil_except_value_utils", + ":__support_fputil_multiply_add", + ":__support_fputil_rounding_mode", + ":__support_fputil_sqrt", + ":__support_macros_config", + ":__support_macros_optimization", + ], +) + libc_support_library( name = "__support_math_asinf", hdrs = ["src/__support/math/asinf.h"], @@ -2847,6 +2865,13 @@ libc_math_function( ], ) +libc_math_function( + name = "asinhf16", + additional_deps = [ + ":__support_math_asinhf16", + ], +) + libc_math_function( name = "atanf", additional_deps = [ `````````` </details> https://github.com/llvm/llvm-project/pull/150849 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits