[libc][math][c23] implement asinpif function (#181511)
Implementing `asinpi` for single-precision. it continues what is done in #152690 that implemented `asinpif16` with header-only approach that is followed since #147386
This commit is contained in:
parent
765c4e6e8f
commit
8f3dd82a0a
@ -339,6 +339,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.asin
|
||||
libc.src.math.asinf
|
||||
libc.src.math.asinhf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.atan2
|
||||
libc.src.math.atan2f
|
||||
# libc.src.math.atan2l
|
||||
|
||||
@ -342,6 +342,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.asin
|
||||
libc.src.math.asinf
|
||||
libc.src.math.asinhf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.atan2
|
||||
libc.src.math.atan2f
|
||||
libc.src.math.atan2l
|
||||
|
||||
@ -340,6 +340,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.acoshf
|
||||
libc.src.math.asinf
|
||||
libc.src.math.asinhf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.atan2
|
||||
libc.src.math.atan2f
|
||||
# libc.src.math.atan2l
|
||||
|
||||
@ -156,6 +156,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.asin
|
||||
libc.src.math.asinf
|
||||
libc.src.math.asinhf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.atan2
|
||||
libc.src.math.atan2f
|
||||
libc.src.math.atan
|
||||
|
||||
@ -286,6 +286,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.asin
|
||||
libc.src.math.asinf
|
||||
libc.src.math.asinhf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.atan
|
||||
libc.src.math.atan2
|
||||
libc.src.math.atan2f
|
||||
|
||||
@ -286,6 +286,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.asin
|
||||
libc.src.math.asinf
|
||||
libc.src.math.asinhf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.atan
|
||||
libc.src.math.atan2
|
||||
libc.src.math.atan2f
|
||||
|
||||
@ -426,6 +426,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.asin
|
||||
libc.src.math.asinf
|
||||
libc.src.math.asinhf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.atan2
|
||||
libc.src.math.atan2f
|
||||
libc.src.math.atan
|
||||
|
||||
@ -256,6 +256,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.asin
|
||||
libc.src.math.asinf
|
||||
libc.src.math.asinhf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.atan2
|
||||
libc.src.math.atan2f
|
||||
libc.src.math.atan
|
||||
|
||||
@ -430,6 +430,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.asin
|
||||
libc.src.math.asinf
|
||||
libc.src.math.asinhf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.atan2
|
||||
libc.src.math.atan2f
|
||||
libc.src.math.atan
|
||||
|
||||
@ -472,6 +472,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.asin
|
||||
libc.src.math.asinf
|
||||
libc.src.math.asinhf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.atan2
|
||||
libc.src.math.atan2f
|
||||
libc.src.math.atan
|
||||
|
||||
@ -135,7 +135,9 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.acoshf
|
||||
libc.src.math.asin
|
||||
libc.src.math.asinf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.asinhf
|
||||
libc.src.math.asinpif
|
||||
libc.src.math.atan2
|
||||
libc.src.math.atan2f
|
||||
libc.src.math.atan
|
||||
|
||||
@ -273,7 +273,7 @@ Higher Math Functions
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
| asinh | |check| | | | |check| | | | 7.12.5.2 | F.10.2.2 |
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
| asinpi | | | | |check| | | | 7.12.4.9 | F.10.1.9 |
|
||||
| asinpi | |check| | | | |check| | | | 7.12.4.9 | F.10.1.9 |
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
| atan | |check| | 1 ULP | | |check| | | | 7.12.4.3 | F.10.1.3 |
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "math/asinf16.h"
|
||||
#include "math/asinhf.h"
|
||||
#include "math/asinhf16.h"
|
||||
#include "math/asinpif.h"
|
||||
#include "math/asinpif16.h"
|
||||
#include "math/atan.h"
|
||||
#include "math/atan2.h"
|
||||
|
||||
23
libc/shared/math/asinpif.h
Normal file
23
libc/shared/math/asinpif.h
Normal file
@ -0,0 +1,23 @@
|
||||
//===-- Shared asinpif header -----------------------------------*- 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_ASINPIF_H
|
||||
#define LLVM_LIBC_SHARED_MATH_ASINPIF_H
|
||||
|
||||
#include "shared/libc_common.h"
|
||||
#include "src/__support/math/asinpif.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace shared {
|
||||
|
||||
using math::asinpif;
|
||||
|
||||
} // namespace shared
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SHARED_MATH_ASINPIF_H
|
||||
@ -172,6 +172,21 @@ add_header_library(
|
||||
libc.src.__support.macros.optimization
|
||||
)
|
||||
|
||||
add_header_library(
|
||||
asinpif
|
||||
HDRS
|
||||
asinpif.h
|
||||
DEPENDS
|
||||
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.sqrt
|
||||
libc.src.__support.macros.optimization
|
||||
)
|
||||
|
||||
add_header_library(
|
||||
atan_utils
|
||||
HDRS
|
||||
|
||||
152
libc/src/__support/math/asinpif.h
Normal file
152
libc/src/__support/math/asinpif.h
Normal file
@ -0,0 +1,152 @@
|
||||
//===-- Implementation header for asinpif -----------------------*- 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_ASINPIF_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_MATH_ASINPIF_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"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace math {
|
||||
|
||||
LIBC_INLINE float asinpif(float x) {
|
||||
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
constexpr size_t N_EXCEPTS = 5;
|
||||
constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINPIF_EXCEPTS = {
|
||||
{// (inputs, RZ output, RU offset, RD offset, RN offset)
|
||||
// x = 0x1.e768f6p-122, asinpif(x) = 0x1.364b7ap-123 (RZ)
|
||||
{0x02F3B47B, 0x021B25BD, 1, 0, 0},
|
||||
// x = 0x1.e768f6p-24, asinpif(x) = 0x1.364b7ap-25 (RZ)
|
||||
{0x33F3B47B, 0x331B25BD, 1, 0, 1},
|
||||
// x = 0x1.dddb4ep-19, asinpif(x) = 0x1.303686p-20 (RZ)
|
||||
{0x366EEDA7, 0x35981B43, 1, 0, 1},
|
||||
// x = -0x1.dddb4ep-19, asinpif(x) = -0x1.303686p-20 (RZ)
|
||||
{0xB66EEDA7, 0xB5981B43, 0, 1, 1},
|
||||
// x = -0x1.e768f6p-24, asinpif(x) = -0x1.364b7ap-25 (RZ)
|
||||
{0xB3F3B47B, 0xB31B25BD, 0, 1, 1}}};
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
using FPBits = fputil::FPBits<float>;
|
||||
|
||||
FPBits xbits(x);
|
||||
bool is_neg = xbits.is_neg();
|
||||
double x_abs = fputil::cast<double>(xbits.abs().get_val());
|
||||
|
||||
auto signed_result = [is_neg](auto r) -> auto { return is_neg ? -r : r; };
|
||||
|
||||
if (LIBC_UNLIKELY(x_abs > 1.0)) {
|
||||
if (xbits.is_nan()) {
|
||||
if (xbits.is_signaling_nan()) {
|
||||
fputil::raise_except_if_required(FE_INVALID);
|
||||
return FPBits::quiet_nan().get_val();
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
fputil::raise_except_if_required(FE_INVALID);
|
||||
fputil::set_errno_if_required(EDOM);
|
||||
return FPBits::quiet_nan().get_val();
|
||||
}
|
||||
|
||||
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
auto r = ASINPIF_EXCEPTS.lookup(xbits.uintval());
|
||||
if (LIBC_UNLIKELY(r.has_value()))
|
||||
return r.value();
|
||||
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
|
||||
|
||||
// the coefficients for the polynomial approximation of asin(x)/(pi*x) in the
|
||||
// range [0, 0.5] extracted using Sollya.
|
||||
//
|
||||
// Sollya code:
|
||||
// > prec = 200;
|
||||
// > display = hexadecimal;
|
||||
// > g = asin(x) / (pi * x);
|
||||
// > P = fpminimax(g, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20|],
|
||||
// > [|D...|], [0, 0.5]);
|
||||
// > for i from 0 to degree(P) do coeff(P, i);
|
||||
// > print("Error:", dirtyinfnorm(P - g, [1e-30; 0.25]));
|
||||
// Error: 0x1.45c281e1cf9b58p-50 ~= 2^−49.652
|
||||
//
|
||||
// Non-zero coefficients (even powers only):
|
||||
constexpr double ASINPI_POLY_COEFFS[] = {
|
||||
0x1.45f306dc9c881p-2, // x^0
|
||||
0x1.b2995e7b7e756p-5, // x^2
|
||||
0x1.8723a1d12f828p-6, // x^4
|
||||
0x1.d1a45564b9545p-7, // x^6
|
||||
0x1.3ce4ceaa0e1e9p-7, // x^8
|
||||
0x1.d2c305898ea13p-8, // x^10
|
||||
0x1.692212e27a5f9p-8, // x^12
|
||||
0x1.2b22cc744d25bp-8, // x^14
|
||||
0x1.8427b864479ffp-9, // x^16
|
||||
0x1.815522d7a2bf1p-8, // x^18
|
||||
-0x1.f6df98438aef4p-9, // x^20
|
||||
0x1.4b50c2eb13708p-7 // x^22
|
||||
};
|
||||
// Evaluates P1(v2) = c1 + c2*v2 + c3*v2^2 + ... (tail of P without c0)
|
||||
auto asinpi_polyeval = [&](double v2) -> double {
|
||||
return fputil::polyeval(
|
||||
v2, ASINPI_POLY_COEFFS[1], ASINPI_POLY_COEFFS[2], ASINPI_POLY_COEFFS[3],
|
||||
ASINPI_POLY_COEFFS[4], ASINPI_POLY_COEFFS[5], ASINPI_POLY_COEFFS[6],
|
||||
ASINPI_POLY_COEFFS[7], ASINPI_POLY_COEFFS[8], ASINPI_POLY_COEFFS[9],
|
||||
ASINPI_POLY_COEFFS[10], ASINPI_POLY_COEFFS[11]);
|
||||
};
|
||||
|
||||
// if |x| <= 0.5:
|
||||
// asinpi(x) = x * (c0 + x^2 * P1(x^2))
|
||||
if (LIBC_UNLIKELY(x_abs <= 0.5)) {
|
||||
double x_d = fputil::cast<double>(x);
|
||||
double v2 = x_d * x_d;
|
||||
double result = x_d * fputil::multiply_add(v2, asinpi_polyeval(v2),
|
||||
ASINPI_POLY_COEFFS[0]);
|
||||
return fputil::cast<float>(result);
|
||||
}
|
||||
|
||||
// If |x| > 0.5:
|
||||
// asinpi(x) = 0.5 - 2 * sqrt(u) * P(u)
|
||||
// = 0.5 - 2 * sqrt(u) * (c0 + u * P1(u))
|
||||
// = (0.5 - 2*sqrt(u)*ONE_OVER_PI_HI)
|
||||
// - 2*sqrt(u) * (ONE_OVER_PI_LO + DELTA_C0 + u * P1(u))
|
||||
//
|
||||
// where u = (1 - |x|) / 2, and
|
||||
// ONE_OVER_PI_HI + ONE_OVER_PI_LO = 1/pi to ~106 bits
|
||||
// DELTA_C0 = c0 - ONE_OVER_PI_HI
|
||||
//
|
||||
// ONE_OVER_PI_LO + DELTA_C0 is a single precomputed constant:
|
||||
// = ONE_OVER_PI_LO + (c0 - ONE_OVER_PI_HI)
|
||||
// = c0 - (ONE_OVER_PI_HI - ONE_OVER_PI_LO)
|
||||
// = c0 - 1/pi (to ~106 bits)
|
||||
constexpr double ONE_OVER_PI_HI = 0x1.45f306dc9c883p-2;
|
||||
constexpr double ONE_OVER_PI_LO = -0x1.6b01ec5417056p-56;
|
||||
// C0_MINUS_1OVERPI = c0 - 1/pi = DELTA_C0 + ONE_OVER_PI_LO
|
||||
constexpr double C0_MINUS_1OVERPI =
|
||||
(ASINPI_POLY_COEFFS[0] - ONE_OVER_PI_HI) + ONE_OVER_PI_LO;
|
||||
|
||||
double u = fputil::multiply_add(-0.5, x_abs, 0.5);
|
||||
double sqrt_u = fputil::sqrt<double>(u);
|
||||
double neg2_sqrt_u = -2.0 * sqrt_u;
|
||||
|
||||
// tail = (c0 - 1/pi) + u * P1(u)
|
||||
double tail = fputil::multiply_add(u, asinpi_polyeval(u), C0_MINUS_1OVERPI);
|
||||
|
||||
double result_hi = fputil::multiply_add(neg2_sqrt_u, ONE_OVER_PI_HI, 0.5);
|
||||
double result = fputil::multiply_add(tail, neg2_sqrt_u, result_hi);
|
||||
|
||||
return fputil::cast<float>(signed_result(result));
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ASINPIF_H
|
||||
@ -58,6 +58,7 @@ add_math_entrypoint_object(asinh)
|
||||
add_math_entrypoint_object(asinhf)
|
||||
add_math_entrypoint_object(asinhf16)
|
||||
|
||||
add_math_entrypoint_object(asinpif)
|
||||
add_math_entrypoint_object(asinpif16)
|
||||
|
||||
add_math_entrypoint_object(atan)
|
||||
|
||||
20
libc/src/math/asinpif.h
Normal file
20
libc/src/math/asinpif.h
Normal file
@ -0,0 +1,20 @@
|
||||
//===-- Implementation header for asinpif -----------------------*- 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_ASINPIF_H
|
||||
#define LLVM_LIBC_SRC_MATH_ASINPIF_H
|
||||
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
float asinpif(float x);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_ASINPIF_H
|
||||
@ -4013,6 +4013,16 @@ add_entrypoint_object(
|
||||
libc.src.__support.math.asinhf16
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
asinpif
|
||||
SRCS
|
||||
asinpif.cpp
|
||||
HDRS
|
||||
../asinpif.h
|
||||
DEPENDS
|
||||
libc.src.__support.math.asinpif
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
asinpif16
|
||||
SRCS
|
||||
|
||||
16
libc/src/math/generic/asinpif.cpp
Normal file
16
libc/src/math/generic/asinpif.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
//===-- Single-precision asinpif(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/asinpif.h"
|
||||
#include "src/__support/math/asinpif.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(float, asinpif, (float x)) { return math::asinpif(x); }
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
@ -19,6 +19,7 @@ add_fp_unittest(
|
||||
libc.src.__support.math.asinf16
|
||||
libc.src.__support.math.asinhf
|
||||
libc.src.__support.math.asinhf16
|
||||
libc.src.__support.math.asinpif
|
||||
libc.src.__support.math.asinpif16
|
||||
libc.src.__support.math.atan
|
||||
libc.src.__support.math.atan2
|
||||
|
||||
@ -140,6 +140,7 @@ TEST(LlvmLibcSharedMathTest, AllFloat) {
|
||||
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::acoshf(1.0f));
|
||||
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::asinf(0.0f));
|
||||
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::asinhf(0.0f));
|
||||
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::asinpif(0.0f));
|
||||
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::atan2f(0.0f, 0.0f));
|
||||
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::atanf(0.0f));
|
||||
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::atanhf(0.0f));
|
||||
|
||||
@ -2476,6 +2476,17 @@ add_fp_unittest(
|
||||
libc.src.math.asinf16
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
asinpif_test
|
||||
NEED_MPFR
|
||||
SUITE
|
||||
libc-math-unittests
|
||||
SRCS
|
||||
asinpif_test.cpp
|
||||
DEPENDS
|
||||
libc.src.math.asinpif
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
asinpif16_test
|
||||
NEED_MPFR
|
||||
|
||||
38
libc/test/src/math/asinpif_test.cpp
Normal file
38
libc/test/src/math/asinpif_test.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
//===-- Unittests for asinpif (MPFR) --------------------------------------===//
|
||||
//
|
||||
// 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/asinpif.h"
|
||||
#include "test/UnitTest/FPMatcher.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
#include "utils/MPFRWrapper/MPFRUtils.h"
|
||||
|
||||
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
|
||||
|
||||
using LlvmLibcAsinpifTest = LIBC_NAMESPACE::testing::FPTest<float>;
|
||||
|
||||
static constexpr mpfr::RoundingMode ROUNDING_MODES[] = {
|
||||
mpfr::RoundingMode::Nearest,
|
||||
mpfr::RoundingMode::Upward,
|
||||
mpfr::RoundingMode::Downward,
|
||||
mpfr::RoundingMode::TowardZero,
|
||||
};
|
||||
|
||||
TEST_F(LlvmLibcAsinpifTest, InFloatRange) {
|
||||
constexpr uint32_t COUNT = 100'000;
|
||||
// Test in [-1, 1]
|
||||
const uint32_t STEP = 0x3F800000 / COUNT; // step through [0, 1.0f] in bits
|
||||
for (mpfr::RoundingMode rm : ROUNDING_MODES) {
|
||||
for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
|
||||
float x = FPBits(v).get_val();
|
||||
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asinpi, x,
|
||||
LIBC_NAMESPACE::asinpif(x), 0.5);
|
||||
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asinpi, -x,
|
||||
LIBC_NAMESPACE::asinpif(-x), 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -518,6 +518,22 @@ add_fp_unittest(
|
||||
-lpthread
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
asinpif_test
|
||||
NO_RUN_POSTBUILD
|
||||
NEED_MPFR
|
||||
SUITE
|
||||
libc_math_exhaustive_tests
|
||||
SRCS
|
||||
asinpif_test.cpp
|
||||
DEPENDS
|
||||
.exhaustive_test
|
||||
libc.src.math.asinpif
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
LINK_LIBRARIES
|
||||
-lpthread
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
atanhf_test
|
||||
NO_RUN_POSTBUILD
|
||||
|
||||
33
libc/test/src/math/exhaustive/asinpif_test.cpp
Normal file
33
libc/test/src/math/exhaustive/asinpif_test.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
//===-- Exhaustive test for asinpif ---------------------------------------===//
|
||||
//
|
||||
// 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 "exhaustive_test.h"
|
||||
#include "src/math/asinpif.h"
|
||||
#include "utils/MPFRWrapper/MPFRUtils.h"
|
||||
|
||||
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
|
||||
|
||||
using LlvmLibcAsinfExhaustiveTest =
|
||||
LlvmLibcUnaryOpExhaustiveMathTest<float, mpfr::Operation::Asinpi,
|
||||
LIBC_NAMESPACE::asinpif>;
|
||||
|
||||
// Range: [0, Inf];
|
||||
static constexpr uint32_t POS_START = 0x0000'0000U;
|
||||
static constexpr uint32_t POS_STOP = 0x7f80'0000U;
|
||||
|
||||
TEST_F(LlvmLibcAsinfExhaustiveTest, PostiveRange) {
|
||||
test_full_range_all_roundings(POS_START, POS_STOP);
|
||||
}
|
||||
|
||||
// Range: [-Inf, 0];
|
||||
static constexpr uint32_t NEG_START = 0xb000'0000U;
|
||||
static constexpr uint32_t NEG_STOP = 0xff80'0000U;
|
||||
|
||||
TEST_F(LlvmLibcAsinfExhaustiveTest, NegativeRange) {
|
||||
test_full_range_all_roundings(NEG_START, NEG_STOP);
|
||||
}
|
||||
@ -4703,6 +4703,18 @@ add_fp_unittest(
|
||||
libc.src.math.asinhf16
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
asinpif_test
|
||||
SUITE
|
||||
libc-math-smoke-tests
|
||||
SRCS
|
||||
asinpif_test.cpp
|
||||
DEPENDS
|
||||
libc.hdr.errno_macros
|
||||
libc.src.math.asinpif
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
asinpif16_test
|
||||
NEED_MPFR
|
||||
|
||||
44
libc/test/src/math/smoke/asinpif_test.cpp
Normal file
44
libc/test/src/math/smoke/asinpif_test.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
//===-- Unittests for asinpif ---------------------------------------------===//
|
||||
//
|
||||
// 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 "hdr/errno_macros.h"
|
||||
#include "hdr/math_macros.h"
|
||||
#include "src/__support/FPUtil/FPBits.h"
|
||||
#include "src/math/asinpif.h"
|
||||
#include "test/UnitTest/FPMatcher.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
|
||||
#include "hdr/stdint_proxy.h"
|
||||
|
||||
using LlvmLibcAsinpifTest = LIBC_NAMESPACE::testing::FPTest<float>;
|
||||
|
||||
TEST_F(LlvmLibcAsinpifTest, SpecialNumbers) {
|
||||
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::asinpif(sNaN), FE_INVALID);
|
||||
EXPECT_MATH_ERRNO(0);
|
||||
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinpif(aNaN));
|
||||
EXPECT_MATH_ERRNO(0);
|
||||
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::asinpif(0.0f));
|
||||
EXPECT_MATH_ERRNO(0);
|
||||
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::asinpif(-0.0f));
|
||||
EXPECT_MATH_ERRNO(0);
|
||||
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinpif(inf));
|
||||
EXPECT_MATH_ERRNO(EDOM);
|
||||
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinpif(neg_inf));
|
||||
EXPECT_MATH_ERRNO(EDOM);
|
||||
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinpif(2.0f));
|
||||
EXPECT_MATH_ERRNO(EDOM);
|
||||
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinpif(-2.0f));
|
||||
EXPECT_MATH_ERRNO(EDOM);
|
||||
}
|
||||
@ -2821,6 +2821,23 @@ libc_support_library(
|
||||
],
|
||||
)
|
||||
|
||||
libc_support_library(
|
||||
name = "__support_math_asinpif",
|
||||
hdrs = ["src/__support/math/asinpif.h"],
|
||||
deps = [
|
||||
":__support_fputil_cast",
|
||||
":__support_fputil_except_value_utils",
|
||||
":__support_fputil_fenv_impl",
|
||||
":__support_fputil_fp_bits",
|
||||
":__support_fputil_multiply_add",
|
||||
":__support_fputil_polyeval",
|
||||
":__support_fputil_rounding_mode",
|
||||
":__support_fputil_sqrt",
|
||||
":__support_macros_config",
|
||||
":__support_macros_optimization",
|
||||
],
|
||||
)
|
||||
|
||||
libc_support_library(
|
||||
name = "__support_math_atan_utils",
|
||||
hdrs = ["src/__support/math/atan_utils.h"],
|
||||
@ -5723,6 +5740,13 @@ libc_math_function(
|
||||
],
|
||||
)
|
||||
|
||||
libc_math_function(
|
||||
name = "asinpif",
|
||||
additional_deps = [
|
||||
":__support_math_asinpif",
|
||||
],
|
||||
)
|
||||
|
||||
libc_math_function(
|
||||
name = "atanf",
|
||||
additional_deps = [":__support_math_atanf"],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user