Lay the ground for C++26 `constexpr` math functions: - Introduce `LIBC_ENABLE_CONSTEXPR` macro switch to specify the desire of `constexpr`-only code route. - Introduce `LIBC_HAS_CONSTANT_EVALUATION` to indicate that we are using `constexpr`-only code in all dependent functions. - Introduce `LIBC_CONSTEXPR` macro qualifier to aid in altering the signature of non-`constexpr` functions. Note that non-`constexpr` qualified functions are caused by the exploitation of non-`constexpr` compatible utils, resulting in non-qualified dependent function, but it can be modified to be qualified using other code routes. If the function is `constexpr` compatible, then it's prohibited to use `LIBC_CONSTEXPR` as a function qualifier. We only qualify it with `constexpr` as usual. `LIBC_CONSTEXPR` may or may not evaluate to `constexpr` depending on the environment configurations, thus it's only used to modify the function signature in constant evaluation context and remove the qualifier if it's not desired (depending on provided configurations). Possible side effects: - Current qualified routes may or may not produce the desired ULP, this is implementation dependent (function by function basis) and needs further testing of the chosen code route. - The shared tests in the current configuration can still compile with unsupported compiler. I didn't want to raise compilation error with unsupported compilers now, but we need to push compiler support with newer versions for this one to work as intended.
498 lines
24 KiB
C++
498 lines
24 KiB
C++
//===-- Unittests for shared math functions -------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#define LIBC_ENABLE_CONSTEXPR 1
|
|
|
|
#include "shared/math/log.h"
|
|
|
|
#ifdef LIBC_HAS_CONSTANT_EVALUATION
|
|
|
|
//===-- Double Tests ------------------------------------------------------===//
|
|
|
|
static_assert(0x0p+0 == LIBC_NAMESPACE::shared::log(1.0));
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#endif // LIBC_HAS_CONSTANT_EVALUATION
|
|
|
|
#undef LIBC_ENABLE_CONSTEXPR
|
|
|
|
#include "shared/math.h"
|
|
#include "test/UnitTest/FPMatcher.h"
|
|
#include "test/UnitTest/Test.h"
|
|
|
|
#ifdef LIBC_TYPES_HAS_FLOAT16
|
|
|
|
TEST(LlvmLibcSharedMathTest, AllFloat16) {
|
|
using FPBits = LIBC_NAMESPACE::fputil::FPBits<float16>;
|
|
|
|
int exponent;
|
|
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(0x1p+0f16, LIBC_NAMESPACE::shared::rsqrtf16(1.0f16));
|
|
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::sqrtf16(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(0x0p+0f16, LIBC_NAMESPACE::shared::asinpif16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::atan2f16(0.0f16, 0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::atanf16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::atanhf16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::atanpif16(0.0f16));
|
|
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::cosf16(0.0f16));
|
|
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::coshf16(0.0f16));
|
|
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::cospif16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::erff16(0.0f16));
|
|
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::exp10f16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::exp10m1f16(0.0f16));
|
|
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::exp2f16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::exp2m1f16(0.0f16));
|
|
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::expf16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::expm1f16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16,
|
|
LIBC_NAMESPACE::shared::fmaf16(0.0f16, 0.0f16, 0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::hypotf16(0.0f16, 0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::logf16(1.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::sinhf16(0.0f16));
|
|
|
|
EXPECT_FP_EQ(float16(10.0), LIBC_NAMESPACE::shared::f16fma(2.0, 3.0, 4.0));
|
|
|
|
EXPECT_FP_EQ(float16(10.0),
|
|
LIBC_NAMESPACE::shared::f16fmaf(2.0f, 3.0f, 4.0f));
|
|
|
|
#ifdef LIBC_TYPES_HAS_FLOAT128
|
|
|
|
EXPECT_FP_EQ(10.0f16, LIBC_NAMESPACE::shared::f16fmaf128(
|
|
float128(2.0), float128(3.0), float128(4.0)));
|
|
EXPECT_FP_EQ(
|
|
5.0f16, LIBC_NAMESPACE::shared::f16addf128(float128(2.0), float128(3.0)));
|
|
EXPECT_FP_EQ(float128(0.0), LIBC_NAMESPACE::shared::f16divf128(
|
|
float128(0.0), float128(1.0)));
|
|
|
|
EXPECT_FP_EQ(float128(0.0), LIBC_NAMESPACE::shared::f16mulf128(
|
|
float128(0.0), float128(0.0)));
|
|
|
|
EXPECT_FP_EQ(float128(0.0), LIBC_NAMESPACE::shared::f16subf128(
|
|
float128(0.0), float128(0.0)));
|
|
#endif // LIBC_TYPES_HAS_FLOAT128
|
|
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::f16div(0.0, 1.0));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::f16divl(0.0L, 1.0L));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::f16divf(0.0f, 1.0f));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::f16mul(0.0L, 0.0L));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::f16mull(0.0L, 0.0L));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::f16mulf(0.0f, 0.0f));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::f16sub(0.0, 0.0));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::f16subl(0.0L, 0.0L));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::f16subf(0.0f, 0.0f));
|
|
|
|
EXPECT_FP_EQ(5.0f16, LIBC_NAMESPACE::shared::f16add(2.0, 3.0));
|
|
EXPECT_FP_EQ(5.0f16, LIBC_NAMESPACE::shared::f16addf(2.0f, 3.0f));
|
|
EXPECT_FP_EQ(5.0f16, LIBC_NAMESPACE::shared::f16addl(2.0L, 3.0L));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::f16sqrt(0.0));
|
|
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::f16sqrtf(0.0f));
|
|
|
|
#ifdef LIBC_TYPES_HAS_FLOAT128
|
|
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::f16sqrtf128(float128(0.0)));
|
|
|
|
#endif // LIBC_TYPES_HAS_FLOAT128
|
|
|
|
EXPECT_FP_EQ(float16(10.0),
|
|
LIBC_NAMESPACE::shared::f16fmal(2.0L, 3.0L, 4.0L));
|
|
|
|
ASSERT_FP_EQ(float16(8 << 5), LIBC_NAMESPACE::shared::ldexpf16(8.0f16, 5));
|
|
ASSERT_FP_EQ(float16(-1 * (8 << 5)),
|
|
LIBC_NAMESPACE::shared::ldexpf16(-8.0f16, 5));
|
|
|
|
EXPECT_FP_EQ_ALL_ROUNDING(
|
|
0.75f16, LIBC_NAMESPACE::shared::frexpf16(24.0f16, &exponent));
|
|
EXPECT_EQ(exponent, 5);
|
|
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::ilogbf16(1.0f16));
|
|
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::log10f16(10.0f16));
|
|
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::log2f16(2.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::logbf16(1.0f16));
|
|
EXPECT_EQ(0L, LIBC_NAMESPACE::shared::llogbf16(1.0f16));
|
|
|
|
EXPECT_FP_EQ(0x1.921fb6p+0f16, LIBC_NAMESPACE::shared::acosf16(0.0f16));
|
|
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::f16sqrtl(1.0L));
|
|
EXPECT_FP_EQ(0.0f16, LIBC_NAMESPACE::shared::sinf16(0.0f16));
|
|
EXPECT_FP_EQ(0.0f16, LIBC_NAMESPACE::shared::tanf16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::sinpif16(0.0f16));
|
|
EXPECT_FP_EQ(0.0f16, LIBC_NAMESPACE::shared::tanhf16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::tanpif16(0.0f16));
|
|
|
|
float16 canonicalizef16_cx = 0.0f16;
|
|
float16 canonicalizef16_x = 0.0f16;
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::canonicalizef16(&canonicalizef16_cx,
|
|
&canonicalizef16_x));
|
|
EXPECT_FP_EQ(0x0p+0f16, canonicalizef16_cx);
|
|
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::ceilf16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::fdimf16(0.0f16, 0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::floorf16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::fmaxf16(0.0f16, 0.0f16));
|
|
float16 getpayloadf16_x = 0.0f16;
|
|
EXPECT_FP_EQ(-0x1p+0f16,
|
|
LIBC_NAMESPACE::shared::getpayloadf16(&getpayloadf16_x));
|
|
|
|
float16 setpayloadf16_res = 0.0f16;
|
|
EXPECT_EQ(0,
|
|
LIBC_NAMESPACE::shared::setpayloadf16(&setpayloadf16_res, 0.0f16));
|
|
|
|
float16 setpayloadsigf16_res = 0.0f16;
|
|
EXPECT_EQ(1, LIBC_NAMESPACE::shared::setpayloadsigf16(&setpayloadsigf16_res,
|
|
0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, setpayloadsigf16_res);
|
|
float16 neg_min_denormal = FPBits::min_subnormal(Sign::NEG).get_val();
|
|
EXPECT_FP_EQ(neg_min_denormal, LIBC_NAMESPACE::shared::nextdownf16(0.0f16));
|
|
float16 min_denormal = FPBits::min_subnormal(Sign ::POS).get_val();
|
|
EXPECT_FP_EQ(min_denormal, LIBC_NAMESPACE::shared::nextupf16(0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16,
|
|
LIBC_NAMESPACE::shared::nexttowardf16(0.0f16, 0.0f16));
|
|
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::nextafterf16(0.0f16, 0.0f16));
|
|
}
|
|
|
|
#endif // LIBC_TYPES_HAS_FLOAT16
|
|
|
|
TEST(LlvmLibcSharedMathTest, AllFloat) {
|
|
using FPBits = LIBC_NAMESPACE::fputil::FPBits<float>;
|
|
int exponent;
|
|
float sin, cos;
|
|
|
|
EXPECT_FP_EQ(0x1.921fb6p+0, LIBC_NAMESPACE::shared::acosf(0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::acoshf(1.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::acospif(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));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::cbrtf(0.0f));
|
|
EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::cosf(0.0f));
|
|
EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::coshf(0.0f));
|
|
EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::cospif(0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::exp10m1f(0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::erff(0.0f));
|
|
EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::exp10f(0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::exp2m1f(0.0f));
|
|
EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::expf(0.0f));
|
|
EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::exp2f(0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::expm1f(0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::fmaf(0.0f, 0.0f, 0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::hypotf(0.0f, 0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::logf(1.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::sinhf(0.0f));
|
|
|
|
EXPECT_FP_EQ_ALL_ROUNDING(0.75f,
|
|
LIBC_NAMESPACE::shared::frexpf(24.0f, &exponent));
|
|
EXPECT_EQ(exponent, 5);
|
|
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::ilogbf(1.0f));
|
|
|
|
ASSERT_FP_EQ(float(8 << 5), LIBC_NAMESPACE::shared::ldexpf(8.0f, 5));
|
|
ASSERT_FP_EQ(float(-1 * (8 << 5)), LIBC_NAMESPACE::shared::ldexpf(-8.0f, 5));
|
|
|
|
EXPECT_EQ(long(0), LIBC_NAMESPACE::shared::llogbf(1.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::log1pf(0.0f));
|
|
EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::log10f(10.0f));
|
|
EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::log2f(2.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::logbf(1.0f));
|
|
EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::powf(0.0f, 0.0f));
|
|
EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::rsqrtf(1.0f));
|
|
|
|
LIBC_NAMESPACE::shared::sincosf(0.0f, &sin, &cos);
|
|
ASSERT_FP_EQ(1.0f, cos);
|
|
ASSERT_FP_EQ(0.0f, sin);
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::sinpif(0.0f));
|
|
EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::sinf(0.0f));
|
|
EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::sqrtf(0.0f));
|
|
EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::tanf(0.0f));
|
|
EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::tanhf(0.0f));
|
|
EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::tanpif(0.0f));
|
|
|
|
float canonicalizef_cx = 0.0f;
|
|
float canonicalizef_x = 0.0f;
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::canonicalizef(&canonicalizef_cx,
|
|
&canonicalizef_x));
|
|
EXPECT_FP_EQ(0x0p+0f, canonicalizef_cx);
|
|
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16mulf(0.0f, 0.0f));
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16subf(0.0f, 0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::ceilf(0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::fdimf(0.0f, 0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::floorf(0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::fmaxf(0.0f, 0.0f));
|
|
float getpayloadf_x = 0.0f;
|
|
EXPECT_FP_EQ(-0x1p+0f, LIBC_NAMESPACE::shared::getpayloadf(&getpayloadf_x));
|
|
|
|
float setpayloadf_res = 0.0f;
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::setpayloadf(&setpayloadf_res, 0.0f));
|
|
|
|
float setpayloadsigf_res = 0.0f;
|
|
EXPECT_EQ(1,
|
|
LIBC_NAMESPACE::shared::setpayloadsigf(&setpayloadsigf_res, 0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, setpayloadsigf_res);
|
|
float neg_min_denormal = FPBits::min_subnormal(Sign::NEG).get_val();
|
|
EXPECT_FP_EQ(neg_min_denormal, LIBC_NAMESPACE::shared::nextdownf(0.0f));
|
|
float min_denormal = FPBits::min_subnormal(Sign ::POS).get_val();
|
|
EXPECT_FP_EQ(min_denormal, LIBC_NAMESPACE::shared::nextupf(0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::nexttowardf(0.0f, 0.0f));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::nextafterf(0.0f, 0.0f));
|
|
}
|
|
|
|
TEST(LlvmLibcSharedMathTest, AllDouble) {
|
|
using FPBits = LIBC_NAMESPACE::fputil::FPBits<double>;
|
|
|
|
double sin, cos;
|
|
LIBC_NAMESPACE::shared::sincos(0.0, &sin, &cos);
|
|
|
|
EXPECT_FP_EQ(0x1.921fb54442d18p+0, LIBC_NAMESPACE::shared::acos(0.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::asin(0.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::atan(0.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::atan2(0.0, 0.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::cbrt(0.0));
|
|
EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::cos(0.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::dsqrtl(0.0));
|
|
EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::exp(0.0));
|
|
EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::exp2(0.0));
|
|
EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::exp10(0.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::expm1(0.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::fma(0.0, 0.0, 0.0));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::ffma(0.0, 0.0, 0.0));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::hypot(0.0, 0.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::fsqrt(0.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::log10(1.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::log1p(0.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::log2(1.0));
|
|
EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::shared::pow(0.0, 0.0));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::sin(0.0));
|
|
EXPECT_FP_EQ(1.0, cos);
|
|
EXPECT_FP_EQ(0.0, sin);
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::sqrt(0.0));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::tan(0.0));
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::ilogb(1.0));
|
|
EXPECT_EQ(0L, LIBC_NAMESPACE::shared::llogb(1.0));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::logb(1.0));
|
|
|
|
double canonicalize_cx = 0.0;
|
|
double canonicalize_x = 0.0;
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::canonicalize(&canonicalize_cx,
|
|
&canonicalize_x));
|
|
EXPECT_FP_EQ(0.0, canonicalize_cx);
|
|
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16mul(0.0, 0.0));
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16sub(0.0, 0.0));
|
|
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::ceil(0.0));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::fadd(0.0, 0.0));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::fdim(0.0, 0.0));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::floor(0.0));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::fmax(0.0, 0.0));
|
|
double getpayload_x = 0.0;
|
|
EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::shared::getpayload(&getpayload_x));
|
|
|
|
double setpayload_res = 0.0;
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::setpayload(&setpayload_res, 0.0));
|
|
|
|
double setpayloadsig_res = 0.0;
|
|
EXPECT_EQ(1, LIBC_NAMESPACE::shared::setpayloadsig(&setpayloadsig_res, 0.0));
|
|
EXPECT_FP_EQ(0.0, setpayloadsig_res);
|
|
double neg_min_denormal = FPBits::min_subnormal(Sign::NEG).get_val();
|
|
EXPECT_FP_EQ(neg_min_denormal, LIBC_NAMESPACE::shared::nextdown(0.0));
|
|
double min_denormal = FPBits::min_subnormal(Sign ::POS).get_val();
|
|
EXPECT_FP_EQ(min_denormal, LIBC_NAMESPACE::shared::nextup(0.0));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::nexttoward(0.0, 0.0));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::nextafter(0.0, 0.0));
|
|
}
|
|
|
|
TEST(LlvmLibcSharedMathTest, AllLongDouble) {
|
|
using FPBits = LIBC_NAMESPACE::fputil::FPBits<long double>;
|
|
EXPECT_FP_EQ(0x0p+0L,
|
|
LIBC_NAMESPACE::shared::dfmal(0x0.p+0L, 0x0.p+0L, 0x0.p+0L));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::fsqrtl(0.0L));
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::ilogbl(0x1.p+0L));
|
|
EXPECT_EQ(0L, LIBC_NAMESPACE::shared::llogbl(1.0L));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::logbl(1.0L));
|
|
EXPECT_FP_EQ(10.0f, LIBC_NAMESPACE::shared::ffmal(2.0L, 3.0, 4.0L));
|
|
|
|
long double canonicalizel_cx = 0.0L;
|
|
long double canonicalizel_x = 0.0L;
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::canonicalizel(&canonicalizel_cx,
|
|
&canonicalizel_x));
|
|
EXPECT_FP_EQ(0x0p+0L, canonicalizel_cx);
|
|
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16mull(0.0L, 0.0L));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::ceill(0.0L));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::daddl(0.0L, 0.0L));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::faddl(0.0L, 0.0L));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::fdiml(0.0L, 0.0L));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::floorl(0.0L));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::fmaxl(0.0L, 0.0L));
|
|
long double getpayloadl_x = 0.0L;
|
|
EXPECT_FP_EQ(-0x1p+0L, LIBC_NAMESPACE::shared::getpayloadl(&getpayloadl_x));
|
|
|
|
long double setpayloadl_res = 0.0L;
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::setpayloadl(&setpayloadl_res, 0.0L));
|
|
|
|
long double setpayloadsigl_res = 0.0L;
|
|
EXPECT_EQ(1,
|
|
LIBC_NAMESPACE::shared::setpayloadsigl(&setpayloadsigl_res, 0.0L));
|
|
EXPECT_FP_EQ(0x0p+0L, setpayloadsigl_res);
|
|
|
|
long double neg_min_denormal = FPBits::min_subnormal(Sign::NEG).get_val();
|
|
EXPECT_FP_EQ(neg_min_denormal, LIBC_NAMESPACE::shared::nextdownl(0.0L));
|
|
long double min_denormal = FPBits::min_subnormal(Sign ::POS).get_val();
|
|
EXPECT_FP_EQ(min_denormal, LIBC_NAMESPACE::shared::nextupl(0.0L));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::nexttowardl(0.0L, 0.0L));
|
|
EXPECT_FP_EQ(0x0p+0L, LIBC_NAMESPACE::shared::nextafterl(0.0L, 0.0L));
|
|
}
|
|
|
|
#ifdef LIBC_TYPES_HAS_FLOAT128
|
|
|
|
TEST(LlvmLibcSharedMathTest, AllFloat128) {
|
|
using FPBits = LIBC_NAMESPACE::fputil::FPBits<float128>;
|
|
int exponent;
|
|
|
|
EXPECT_FP_EQ(float128(0x0p+0),
|
|
LIBC_NAMESPACE::shared::atan2f128(float128(0.0), float128(0.0)));
|
|
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::ffmaf128(
|
|
float128(0.0), float128(0.0), float128(0.0)));
|
|
EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::fsqrtf128(float128(1.0f)));
|
|
EXPECT_FP_EQ_ALL_ROUNDING(float128(0.75), LIBC_NAMESPACE::shared::frexpf128(
|
|
float128(24), &exponent));
|
|
EXPECT_EQ(exponent, 5);
|
|
|
|
EXPECT_EQ(3, LIBC_NAMESPACE::shared::ilogbf128(float128(8.0)));
|
|
ASSERT_FP_EQ(float128(8 << 5),
|
|
LIBC_NAMESPACE::shared::ldexpf128(float128(8), 5));
|
|
ASSERT_FP_EQ(float128(-1 * (8 << 5)),
|
|
LIBC_NAMESPACE::shared::ldexpf128(float128(-8), 5));
|
|
EXPECT_FP_EQ(float128(0.0), LIBC_NAMESPACE::shared::logbf128(float128(1.0)));
|
|
EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::shared::dfmaf128(
|
|
float128(0.0), float128(0.0), float128(0.0)));
|
|
EXPECT_FP_EQ(float128(0x1p+0),
|
|
LIBC_NAMESPACE::shared::sqrtf128(float128(1.0)));
|
|
|
|
EXPECT_EQ(0L, LIBC_NAMESPACE::shared::llogbf128(float128(1.0)));
|
|
|
|
EXPECT_FP_EQ(bfloat16(5.0), LIBC_NAMESPACE::shared::bf16addf128(
|
|
float128(2.0), float128(3.0)));
|
|
|
|
float128 canonicalizef128_cx = float128(0.0);
|
|
float128 canonicalizef128_x = float128(0.0);
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::canonicalizef128(&canonicalizef128_cx,
|
|
&canonicalizef128_x));
|
|
EXPECT_FP_EQ(float128(0.0), canonicalizef128_cx);
|
|
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16subf128(
|
|
float128(0.0), float128(0.0)));
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16fmaf128(
|
|
float128(0.0), float128(0.0), float128(0.0)));
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::bf16mulf128(
|
|
float128(0.0), float128(0.0)));
|
|
EXPECT_FP_EQ(bfloat16(2.0), LIBC_NAMESPACE::shared::bf16divf128(
|
|
float128(4.0), float128(2.0)));
|
|
EXPECT_FP_EQ(float128(0.0), LIBC_NAMESPACE::shared::ceilf128(float128(0.0)));
|
|
EXPECT_FP_EQ(float128(0.0),
|
|
LIBC_NAMESPACE::shared::daddf128(float128(0.0), float128(0.0)));
|
|
EXPECT_FP_EQ(float128(0.0),
|
|
LIBC_NAMESPACE::shared::faddf128(float128(0.0), float128(0.0)));
|
|
EXPECT_FP_EQ(float128(0.0), LIBC_NAMESPACE::shared::floorf128(float128(0.0)));
|
|
EXPECT_FP_EQ(float128(0.0),
|
|
LIBC_NAMESPACE::shared::fdimf128(float128(0.0), float128(0.0)));
|
|
EXPECT_FP_EQ(float128(0.0),
|
|
LIBC_NAMESPACE::shared::fmaxf128(float128(0.0), float128(0.0)));
|
|
|
|
float128 getpayloadf128_x = float128(0.0);
|
|
EXPECT_FP_EQ(float128(-1.0),
|
|
LIBC_NAMESPACE::shared::getpayloadf128(&getpayloadf128_x));
|
|
|
|
float128 setpayloadf128_res = float128(0.0);
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::setpayloadf128(&setpayloadf128_res,
|
|
float128(0.0)));
|
|
|
|
float128 setpayloadsigf128_res = float128(0.0);
|
|
EXPECT_EQ(1, LIBC_NAMESPACE::shared::setpayloadsigf128(&setpayloadsigf128_res,
|
|
float128(0.0)));
|
|
EXPECT_FP_EQ(float128(0.0), setpayloadsigf128_res);
|
|
|
|
float128 neg_min_denormal = FPBits::min_subnormal(Sign::NEG).get_val();
|
|
EXPECT_FP_EQ(neg_min_denormal,
|
|
LIBC_NAMESPACE::shared::nextdownf128(float128(0.0)));
|
|
float128 min_denormal = FPBits::min_subnormal(Sign ::POS).get_val();
|
|
EXPECT_FP_EQ(min_denormal, LIBC_NAMESPACE::shared::nextupf128(float128(0.0)));
|
|
EXPECT_FP_EQ(float128(0.0), LIBC_NAMESPACE::shared::nextafterf128(
|
|
float128(0.0), float128(0.0)));
|
|
}
|
|
|
|
#endif // LIBC_TYPES_HAS_FLOAT128
|
|
|
|
TEST(LlvmLibcSharedMathTest, AllBFloat16) {
|
|
using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>;
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::atanbf16(bfloat16(0.0)));
|
|
EXPECT_FP_EQ(bfloat16(5.0), LIBC_NAMESPACE::shared::bf16add(2.0, 3.0));
|
|
EXPECT_FP_EQ(bfloat16(2.0f), LIBC_NAMESPACE::shared::bf16divf(4.0f, 2.0f));
|
|
EXPECT_FP_EQ(bfloat16(2.0), LIBC_NAMESPACE::shared::bf16divl(6.0L, 3.0L));
|
|
EXPECT_FP_EQ(bfloat16(2.0), LIBC_NAMESPACE::shared::bf16div(4.0, 2.0));
|
|
EXPECT_FP_EQ(bfloat16(10.0),
|
|
LIBC_NAMESPACE::shared::bf16fmal(2.0L, 3.0L, 4.0L));
|
|
|
|
bfloat16 canonicalizebf16_cx = bfloat16(0.0);
|
|
bfloat16 canonicalizebf16_x = bfloat16(0.0);
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::canonicalizebf16(&canonicalizebf16_cx,
|
|
&canonicalizebf16_x));
|
|
EXPECT_FP_EQ(bfloat16(0.0), canonicalizebf16_cx);
|
|
EXPECT_FP_EQ(bfloat16(5.0), LIBC_NAMESPACE::shared::bf16addf(2.0f, 3.0f));
|
|
EXPECT_FP_EQ(bfloat16(5.0), LIBC_NAMESPACE::shared::bf16addl(2L, 3L));
|
|
EXPECT_FP_EQ(bfloat16(10.0),
|
|
LIBC_NAMESPACE::shared::bf16fmaf(2.0f, 3.0f, 4.0f));
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::ceilbf16(bfloat16(0.0)));
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::floorbf16(bfloat16(0.0)));
|
|
EXPECT_FP_EQ(bfloat16(0.0),
|
|
LIBC_NAMESPACE::shared::fdimbf16(bfloat16(0.0), bfloat16(0.0)));
|
|
EXPECT_FP_EQ(bfloat16(10.0),
|
|
LIBC_NAMESPACE::shared::fmabf16(bfloat16(2.0), bfloat16(3.0),
|
|
bfloat16(4.0)));
|
|
EXPECT_FP_EQ(bfloat16(0.0),
|
|
LIBC_NAMESPACE::shared::fmaxbf16(bfloat16(0.0), bfloat16(0.0)));
|
|
|
|
EXPECT_FP_EQ(bfloat16(10.0), LIBC_NAMESPACE::shared::bf16fma(2.0, 3.0, 4.0));
|
|
|
|
bfloat16 getpayloadbf16_x = bfloat16(0.0);
|
|
EXPECT_FP_EQ(bfloat16(-1.0),
|
|
LIBC_NAMESPACE::shared::getpayloadbf16(&getpayloadbf16_x));
|
|
|
|
EXPECT_FP_EQ(bfloat16(5.0),
|
|
LIBC_NAMESPACE::shared::hypotbf16(bfloat16(4.0), bfloat16(3.0)));
|
|
|
|
bfloat16 setpayloadbf16_res = bfloat16(0.0);
|
|
EXPECT_EQ(0, LIBC_NAMESPACE::shared::setpayloadbf16(&setpayloadbf16_res,
|
|
bfloat16(0.0)));
|
|
|
|
bfloat16 setpayloadsigbf16_res = bfloat16(0.0);
|
|
EXPECT_EQ(1, LIBC_NAMESPACE::shared::setpayloadsigbf16(&setpayloadsigbf16_res,
|
|
bfloat16(0.0)));
|
|
EXPECT_FP_EQ(bfloat16(0.0), setpayloadsigbf16_res);
|
|
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::log_bf16(bfloat16(1.0)));
|
|
|
|
bfloat16 neg_min_denormal = FPBits::min_subnormal(Sign::NEG).get_val();
|
|
EXPECT_FP_EQ(neg_min_denormal,
|
|
LIBC_NAMESPACE::shared::nextdownbf16(bfloat16(0.0)));
|
|
bfloat16 min_denormal = FPBits::min_subnormal(Sign ::POS).get_val();
|
|
EXPECT_FP_EQ(min_denormal, LIBC_NAMESPACE::shared::nextupbf16(bfloat16(0.0)));
|
|
|
|
EXPECT_FP_EQ(bfloat16(0.0),
|
|
LIBC_NAMESPACE::shared::nexttowardbf16(bfloat16(0.0), 0.0L));
|
|
EXPECT_FP_EQ(bfloat16(0.0), LIBC_NAMESPACE::shared::nextafterbf16(
|
|
bfloat16(0.0), bfloat16(0.0)));
|
|
}
|