| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| //===-- Implementation of f16addf 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/f16addf.h" | ||
| #include "src/__support/FPUtil/generic/add_sub.h" | ||
| #include "src/__support/common.h" | ||
|
|
||
| namespace LIBC_NAMESPACE { | ||
|
|
||
| LLVM_LIBC_FUNCTION(float16, f16addf, (float x, float y)) { | ||
| return fputil::generic::add<float16>(x, y); | ||
| } | ||
|
|
||
| } // namespace LIBC_NAMESPACE |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| //===-- Implementation of f16subf 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/f16subf.h" | ||
| #include "src/__support/FPUtil/generic/add_sub.h" | ||
| #include "src/__support/common.h" | ||
|
|
||
| namespace LIBC_NAMESPACE { | ||
|
|
||
| LLVM_LIBC_FUNCTION(float16, f16subf, (float x, float y)) { | ||
| return fputil::generic::sub<float16>(x, y); | ||
| } | ||
|
|
||
| } // namespace LIBC_NAMESPACE |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| //===-- Utility class to test different flavors of float add ----*- 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_TEST_SRC_MATH_ADDTEST_H | ||
| #define LLVM_LIBC_TEST_SRC_MATH_ADDTEST_H | ||
|
|
||
| #include "test/UnitTest/FEnvSafeTest.h" | ||
| #include "test/UnitTest/FPMatcher.h" | ||
| #include "test/UnitTest/Test.h" | ||
| #include "utils/MPFRWrapper/MPFRUtils.h" | ||
|
|
||
| namespace mpfr = LIBC_NAMESPACE::testing::mpfr; | ||
|
|
||
| template <typename OutType, typename InType> | ||
| class AddTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { | ||
|
|
||
| struct InConstants { | ||
| DECLARE_SPECIAL_CONSTANTS(InType) | ||
| }; | ||
|
|
||
| using InFPBits = typename InConstants::FPBits; | ||
| using InStorageType = typename InConstants::StorageType; | ||
|
|
||
| static constexpr InStorageType IN_MAX_NORMAL_U = | ||
| InFPBits::max_normal().uintval(); | ||
| static constexpr InStorageType IN_MIN_NORMAL_U = | ||
| InFPBits::min_normal().uintval(); | ||
| static constexpr InStorageType IN_MAX_SUBNORMAL_U = | ||
| InFPBits::max_subnormal().uintval(); | ||
| static constexpr InStorageType IN_MIN_SUBNORMAL_U = | ||
| InFPBits::min_subnormal().uintval(); | ||
|
|
||
| public: | ||
| typedef OutType (*AddFunc)(InType, InType); | ||
|
|
||
| void test_subnormal_range(AddFunc func) { | ||
| constexpr InStorageType COUNT = 100'001; | ||
| constexpr InStorageType STEP = | ||
| (IN_MAX_SUBNORMAL_U - IN_MIN_SUBNORMAL_U) / COUNT; | ||
| for (InStorageType i = 0, v = 0, w = IN_MAX_SUBNORMAL_U; i <= COUNT; | ||
| ++i, v += STEP, w -= STEP) { | ||
| InType x = InFPBits(v).get_val(); | ||
| InType y = InFPBits(w).get_val(); | ||
| mpfr::BinaryInput<InType> input{x, y}; | ||
| EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Add, input, func(x, y), | ||
| 0.5); | ||
| } | ||
| } | ||
|
|
||
| void test_normal_range(AddFunc func) { | ||
| constexpr InStorageType COUNT = 100'001; | ||
| constexpr InStorageType STEP = (IN_MAX_NORMAL_U - IN_MIN_NORMAL_U) / COUNT; | ||
| for (InStorageType i = 0, v = 0, w = IN_MAX_NORMAL_U; i <= COUNT; | ||
| ++i, v += STEP, w -= STEP) { | ||
| InType x = InFPBits(v).get_val(); | ||
| InType y = InFPBits(w).get_val(); | ||
| mpfr::BinaryInput<InType> input{x, y}; | ||
| EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Add, input, func(x, y), | ||
| 0.5); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| #define LIST_ADD_TESTS(OutType, InType, func) \ | ||
| using LlvmLibcAddTest = AddTest<OutType, InType>; \ | ||
| TEST_F(LlvmLibcAddTest, SubnormalRange) { test_subnormal_range(&func); } \ | ||
| TEST_F(LlvmLibcAddTest, NormalRange) { test_normal_range(&func); } | ||
|
|
||
| #endif // LLVM_LIBC_TEST_SRC_MATH_ADDTEST_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| //===-- Utility class to test different flavors of float sub ----*- 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_TEST_SRC_MATH_SUBTEST_H | ||
| #define LLVM_LIBC_TEST_SRC_MATH_SUBTEST_H | ||
|
|
||
| #include "test/UnitTest/FEnvSafeTest.h" | ||
| #include "test/UnitTest/FPMatcher.h" | ||
| #include "test/UnitTest/Test.h" | ||
| #include "utils/MPFRWrapper/MPFRUtils.h" | ||
|
|
||
| namespace mpfr = LIBC_NAMESPACE::testing::mpfr; | ||
|
|
||
| template <typename OutType, typename InType> | ||
| class SubTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { | ||
|
|
||
| struct InConstants { | ||
| DECLARE_SPECIAL_CONSTANTS(InType) | ||
| }; | ||
|
|
||
| using InFPBits = typename InConstants::FPBits; | ||
| using InStorageType = typename InConstants::StorageType; | ||
|
|
||
| static constexpr InStorageType IN_MAX_NORMAL_U = | ||
| InFPBits::max_normal().uintval(); | ||
| static constexpr InStorageType IN_MIN_NORMAL_U = | ||
| InFPBits::min_normal().uintval(); | ||
| static constexpr InStorageType IN_MAX_SUBNORMAL_U = | ||
| InFPBits::max_subnormal().uintval(); | ||
| static constexpr InStorageType IN_MIN_SUBNORMAL_U = | ||
| InFPBits::min_subnormal().uintval(); | ||
|
|
||
| public: | ||
| using SubFunc = OutType (*)(InType, InType); | ||
|
|
||
| void test_subnormal_range(SubFunc func) { | ||
| constexpr InStorageType COUNT = 100'001; | ||
| constexpr InStorageType STEP = | ||
| (IN_MAX_SUBNORMAL_U - IN_MIN_SUBNORMAL_U) / COUNT; | ||
| for (InStorageType i = 0, v = 0, w = IN_MAX_SUBNORMAL_U; i <= COUNT; | ||
| ++i, v += STEP, w -= STEP) { | ||
| InType x = InFPBits(v).get_val(); | ||
| InType y = InFPBits(w).get_val(); | ||
| mpfr::BinaryInput<InType> input{x, y}; | ||
| EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sub, input, func(x, y), | ||
| 0.5); | ||
| } | ||
| } | ||
|
|
||
| void test_normal_range(SubFunc func) { | ||
| constexpr InStorageType COUNT = 100'001; | ||
| constexpr InStorageType STEP = (IN_MAX_NORMAL_U - IN_MIN_NORMAL_U) / COUNT; | ||
| for (InStorageType i = 0, v = 0, w = IN_MAX_NORMAL_U; i <= COUNT; | ||
| ++i, v += STEP, w -= STEP) { | ||
| InType x = InFPBits(v).get_val(); | ||
| InType y = InFPBits(w).get_val(); | ||
| mpfr::BinaryInput<InType> input{x, y}; | ||
| EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sub, input, func(x, y), | ||
| 0.5); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| #define LIST_SUB_TESTS(OutType, InType, func) \ | ||
| using LlvmLibcSubTest = SubTest<OutType, InType>; \ | ||
| TEST_F(LlvmLibcSubTest, SubnormalRange) { test_subnormal_range(&func); } \ | ||
| TEST_F(LlvmLibcSubTest, NormalRange) { test_normal_range(&func); } | ||
|
|
||
| #endif // LLVM_LIBC_TEST_SRC_MATH_SUBTEST_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| //===-- Unittests for f16addf ---------------------------------------------===// | ||
| // | ||
| // 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 "AddTest.h" | ||
|
|
||
| #include "src/math/f16addf.h" | ||
|
|
||
| LIST_ADD_TESTS(float16, float, LIBC_NAMESPACE::f16addf) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| //===-- Unittests for f16subf ---------------------------------------------===// | ||
| // | ||
| // 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 "SubTest.h" | ||
|
|
||
| #include "src/math/f16subf.h" | ||
|
|
||
| LIST_SUB_TESTS(float16, float, LIBC_NAMESPACE::f16subf) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,156 @@ | ||
| //===-- Utility class to test different flavors of float add ----*- 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_TEST_SRC_MATH_SMOKE_ADDTEST_H | ||
| #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ADDTEST_H | ||
|
|
||
| #include "hdr/errno_macros.h" | ||
| #include "hdr/fenv_macros.h" | ||
| #include "src/__support/FPUtil/BasicOperations.h" | ||
| #include "test/UnitTest/FEnvSafeTest.h" | ||
| #include "test/UnitTest/FPMatcher.h" | ||
| #include "test/UnitTest/Test.h" | ||
|
|
||
| template <typename OutType, typename InType> | ||
| class AddTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { | ||
|
|
||
| DECLARE_SPECIAL_CONSTANTS(OutType) | ||
|
|
||
| struct InConstants { | ||
| DECLARE_SPECIAL_CONSTANTS(InType) | ||
| }; | ||
|
|
||
| using InFPBits = typename InConstants::FPBits; | ||
| using InStorageType = typename InConstants::StorageType; | ||
|
|
||
| InConstants in; | ||
|
|
||
| public: | ||
| using AddFunc = OutType (*)(InType, InType); | ||
|
|
||
| void test_special_numbers(AddFunc func) { | ||
| EXPECT_FP_IS_NAN(func(aNaN, aNaN)); | ||
| EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(sNaN, sNaN), FE_INVALID); | ||
|
|
||
| InType qnan_42 = InFPBits::quiet_nan(Sign::POS, 0x42).get_val(); | ||
| EXPECT_FP_EQ(InType(0x42.0p+0), | ||
| LIBC_NAMESPACE::fputil::getpayload(func(qnan_42, zero))); | ||
| EXPECT_FP_EQ(InType(0x42.0p+0), | ||
| LIBC_NAMESPACE::fputil::getpayload(func(zero, qnan_42))); | ||
|
|
||
| if constexpr (sizeof(OutType) < sizeof(InType)) { | ||
| InStorageType max_payload = InFPBits::FRACTION_MASK >> 1; | ||
| InType qnan_max = InFPBits::quiet_nan(Sign::POS, max_payload).get_val(); | ||
| EXPECT_FP_EQ(zero, | ||
| LIBC_NAMESPACE::fputil::getpayload(func(qnan_max, zero))); | ||
| EXPECT_FP_EQ(zero, | ||
| LIBC_NAMESPACE::fputil::getpayload(func(zero, qnan_max))); | ||
| EXPECT_FP_EQ(InType(0x42.0p+0), | ||
| LIBC_NAMESPACE::fputil::getpayload(func(qnan_max, qnan_42))); | ||
| EXPECT_FP_EQ(InType(0x42.0p+0), | ||
| LIBC_NAMESPACE::fputil::getpayload(func(qnan_42, qnan_max))); | ||
| } | ||
|
|
||
| EXPECT_FP_EQ(inf, func(inf, zero)); | ||
| EXPECT_FP_EQ(neg_inf, func(neg_inf, zero)); | ||
| EXPECT_FP_EQ(inf, func(inf, neg_zero)); | ||
| EXPECT_FP_EQ(neg_inf, func(neg_inf, neg_zero)); | ||
| } | ||
|
|
||
| void test_invalid_operations(AddFunc func) { | ||
| EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(inf, neg_inf), FE_INVALID); | ||
| EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(neg_inf, inf), FE_INVALID); | ||
| } | ||
|
|
||
| void test_range_errors(AddFunc func) { | ||
| using namespace LIBC_NAMESPACE::fputil::testing; | ||
|
|
||
| if (ForceRoundingMode r(RoundingMode::Nearest); r.success) { | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(max_normal, max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(-inf, func(neg_max_normal, neg_max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
|
|
||
| EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION( | ||
| neg_zero, func(in.neg_min_denormal, in.neg_min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| } | ||
|
|
||
| if (ForceRoundingMode r(RoundingMode::TowardZero); r.success) { | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(max_normal, func(max_normal, max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(neg_max_normal, | ||
| func(neg_max_normal, neg_max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
|
|
||
| EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION( | ||
| neg_zero, func(in.neg_min_denormal, in.neg_min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| } | ||
|
|
||
| if (ForceRoundingMode r(RoundingMode::Downward); r.success) { | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(max_normal, func(max_normal, max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(-inf, func(neg_max_normal, neg_max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
|
|
||
| EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION( | ||
| neg_min_denormal, func(in.neg_min_denormal, in.neg_min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| } | ||
|
|
||
| if (ForceRoundingMode r(RoundingMode::Upward); r.success) { | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(max_normal, max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(neg_max_normal, | ||
| func(neg_max_normal, neg_max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
|
|
||
| EXPECT_FP_EQ_WITH_EXCEPTION(min_denormal, | ||
| func(in.min_denormal, in.min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION( | ||
| neg_zero, func(in.neg_min_denormal, in.neg_min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| } | ||
| } | ||
|
|
||
| void test_inexact_results(AddFunc func) { | ||
| func(InType(1.0), min_denormal); | ||
| EXPECT_FP_EXCEPTION(FE_INEXACT); | ||
| } | ||
| }; | ||
|
|
||
| #define LIST_ADD_TESTS(OutType, InType, func) \ | ||
| using LlvmLibcAddTest = AddTest<OutType, InType>; \ | ||
| TEST_F(LlvmLibcAddTest, SpecialNumbers) { test_special_numbers(&func); } \ | ||
| TEST_F(LlvmLibcAddTest, InvalidOperations) { \ | ||
| test_invalid_operations(&func); \ | ||
| } \ | ||
| TEST_F(LlvmLibcAddTest, RangeErrors) { test_range_errors(&func); } \ | ||
| TEST_F(LlvmLibcAddTest, InexactResults) { test_inexact_results(&func); } | ||
|
|
||
| #endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_ADDTEST_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,158 @@ | ||
| //===-- Utility class to test different flavors of float sub ----*- 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_TEST_SRC_MATH_SMOKE_SUBTEST_H | ||
| #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_SUBTEST_H | ||
|
|
||
| #include "hdr/fenv_macros.h" | ||
| #include "src/__support/FPUtil/BasicOperations.h" | ||
| #include "test/UnitTest/FEnvSafeTest.h" | ||
| #include "test/UnitTest/FPMatcher.h" | ||
| #include "test/UnitTest/Test.h" | ||
|
|
||
| template <typename OutType, typename InType> | ||
| class SubTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { | ||
|
|
||
| DECLARE_SPECIAL_CONSTANTS(OutType) | ||
|
|
||
| struct InConstants { | ||
| DECLARE_SPECIAL_CONSTANTS(InType) | ||
| }; | ||
|
|
||
| using InFPBits = typename InConstants::FPBits; | ||
| using InStorageType = typename InConstants::StorageType; | ||
|
|
||
| InConstants in; | ||
|
|
||
| public: | ||
| using SubFunc = OutType (*)(InType, InType); | ||
|
|
||
| void test_special_numbers(SubFunc func) { | ||
| EXPECT_FP_IS_NAN(func(aNaN, aNaN)); | ||
| EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(sNaN, sNaN), FE_INVALID); | ||
|
|
||
| InType qnan_42 = InFPBits::quiet_nan(Sign::POS, 0x42).get_val(); | ||
| EXPECT_FP_EQ(InType(0x42.0p+0), | ||
| LIBC_NAMESPACE::fputil::getpayload(func(qnan_42, zero))); | ||
| EXPECT_FP_EQ(InType(0x42.0p+0), | ||
| LIBC_NAMESPACE::fputil::getpayload(func(zero, qnan_42))); | ||
|
|
||
| if constexpr (sizeof(OutType) < sizeof(InType)) { | ||
| InStorageType max_payload = InFPBits::FRACTION_MASK >> 1; | ||
| InType qnan_max = InFPBits::quiet_nan(Sign::POS, max_payload).get_val(); | ||
| EXPECT_FP_EQ(zero, | ||
| LIBC_NAMESPACE::fputil::getpayload(func(qnan_max, zero))); | ||
| EXPECT_FP_EQ(zero, | ||
| LIBC_NAMESPACE::fputil::getpayload(func(zero, qnan_max))); | ||
| EXPECT_FP_EQ(InType(0x42.0p+0), | ||
| LIBC_NAMESPACE::fputil::getpayload(func(qnan_max, qnan_42))); | ||
| EXPECT_FP_EQ(InType(0x42.0p+0), | ||
| LIBC_NAMESPACE::fputil::getpayload(func(qnan_42, qnan_max))); | ||
| } | ||
|
|
||
| EXPECT_FP_EQ(inf, func(inf, zero)); | ||
| EXPECT_FP_EQ(neg_inf, func(neg_inf, zero)); | ||
| EXPECT_FP_EQ(inf, func(inf, neg_zero)); | ||
| EXPECT_FP_EQ(neg_inf, func(neg_inf, neg_zero)); | ||
| } | ||
|
|
||
| void test_invalid_operations(SubFunc func) { | ||
| EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(inf, inf), FE_INVALID); | ||
| EXPECT_FP_IS_NAN_WITH_EXCEPTION(func(neg_inf, neg_inf), FE_INVALID); | ||
| } | ||
|
|
||
| void test_range_errors(SubFunc func) { | ||
| using namespace LIBC_NAMESPACE::fputil::testing; | ||
|
|
||
| if (ForceRoundingMode r(RoundingMode::Nearest); r.success) { | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(max_normal, neg_max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(-inf, func(neg_max_normal, max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
|
|
||
| EXPECT_FP_EQ_WITH_EXCEPTION(zero, | ||
| func(in.min_denormal, in.neg_min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(neg_zero, | ||
| func(in.neg_min_denormal, in.min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| } | ||
|
|
||
| if (ForceRoundingMode r(RoundingMode::TowardZero); r.success) { | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(max_normal, func(max_normal, neg_max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(neg_max_normal, | ||
| func(neg_max_normal, max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
|
|
||
| EXPECT_FP_EQ_WITH_EXCEPTION(zero, | ||
| func(in.min_denormal, in.neg_min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(neg_zero, | ||
| func(in.neg_min_denormal, in.min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| } | ||
|
|
||
| if (ForceRoundingMode r(RoundingMode::Downward); r.success) { | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(max_normal, func(max_normal, neg_max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(-inf, func(neg_max_normal, max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
|
|
||
| EXPECT_FP_EQ_WITH_EXCEPTION(zero, | ||
| func(in.min_denormal, in.neg_min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(neg_min_denormal, | ||
| func(in.neg_min_denormal, in.min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| } | ||
|
|
||
| if (ForceRoundingMode r(RoundingMode::Upward); r.success) { | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(max_normal, neg_max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(neg_max_normal, | ||
| func(neg_max_normal, max_normal), | ||
| FE_OVERFLOW | FE_INEXACT); | ||
|
|
||
| EXPECT_FP_EQ_WITH_EXCEPTION(min_denormal, | ||
| func(in.min_denormal, in.neg_min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| EXPECT_FP_EQ_WITH_EXCEPTION(neg_zero, | ||
| func(in.neg_min_denormal, in.min_denormal), | ||
| FE_UNDERFLOW | FE_INEXACT); | ||
| EXPECT_MATH_ERRNO(ERANGE); | ||
| } | ||
| } | ||
|
|
||
| void test_inexact_results(SubFunc func) { | ||
| func(InType(1.0), min_denormal); | ||
| EXPECT_FP_EXCEPTION(FE_INEXACT); | ||
| } | ||
| }; | ||
|
|
||
| #define LIST_SUB_TESTS(OutType, InType, func) \ | ||
| using LlvmLibcSubTest = SubTest<OutType, InType>; \ | ||
| TEST_F(LlvmLibcSubTest, SpecialNumbers) { test_special_numbers(&func); } \ | ||
| TEST_F(LlvmLibcSubTest, InvalidOperations) { \ | ||
| test_invalid_operations(&func); \ | ||
| } \ | ||
| TEST_F(LlvmLibcSubTest, RangeErrors) { test_range_errors(&func); } \ | ||
| TEST_F(LlvmLibcSubTest, InexactResults) { test_inexact_results(&func); } | ||
|
|
||
| #endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_SUBTEST_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| //===-- Unittests for f16addf ---------------------------------------------===// | ||
| // | ||
| // 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 "AddTest.h" | ||
|
|
||
| #include "src/math/f16addf.h" | ||
|
|
||
| LIST_ADD_TESTS(float16, float, LIBC_NAMESPACE::f16addf) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| //===-- Unittests for f16subf ---------------------------------------------===// | ||
| // | ||
| // 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 "SubTest.h" | ||
|
|
||
| #include "src/math/f16subf.h" | ||
|
|
||
| LIST_SUB_TESTS(float16, float, LIBC_NAMESPACE::f16subf) |