| //===-- Unit test for fmabf16 ---------------------------------------===// | |
| // | |
| // 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/__support/FPUtil/bfloat16.h" | |
| #include "src/math/fmabf16.h" | |
| #include "test/UnitTest/FPMatcher.h" | |
| #include "test/UnitTest/Test.h" | |
| #include "utils/MPFRWrapper/MPFRUtils.h" | |
| using LlvmLibcFmaBf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>; | |
| namespace mpfr = LIBC_NAMESPACE::testing::mpfr; | |
| // subnormal range (negative) | |
| static constexpr uint16_t SUBNORM_NEG_START = 0x8001U; | |
| static constexpr uint16_t SUBNORM_NEG_STOP = 0x807FU; | |
| TEST_F(LlvmLibcFmaBf16Test, SubnormalNegativeRange) { | |
| constexpr bfloat16 Z_VALUES[] = {zero, neg_zero, inf, | |
| neg_inf, min_normal, max_normal}; | |
| for (uint16_t v1 = SUBNORM_NEG_START; v1 <= SUBNORM_NEG_STOP; v1++) { | |
| for (uint16_t v2 = v1; v2 <= SUBNORM_NEG_STOP; v2++) { | |
| bfloat16 x = FPBits(v1).get_val(); | |
| bfloat16 y = FPBits(v2).get_val(); | |
| for (const bfloat16 &z : Z_VALUES) { | |
| mpfr::TernaryInput<bfloat16> input{x, y, z}; | |
| EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fma, input, | |
| LIBC_NAMESPACE::fmabf16(x, y, z), 0.5); | |
| } | |
| bfloat16 neg_xy = -(x * y); | |
| mpfr::TernaryInput<bfloat16> input{x, y, neg_xy}; | |
| EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fma, input, | |
| LIBC_NAMESPACE::fmabf16(x, y, neg_xy), | |
| 0.5); | |
| } | |
| } | |
| } | |
| TEST_F(LlvmLibcFmaBf16Test, SpecialNumbers) { | |
| constexpr bfloat16 VALUES[] = {zero, neg_zero, inf, | |
| neg_inf, min_normal, max_normal}; | |
| for (size_t i = 0; i < 6; ++i) { | |
| for (size_t j = i; j < 6; ++j) { | |
| bfloat16 x = VALUES[i]; | |
| bfloat16 y = VALUES[j]; | |
| for (const bfloat16 &z : VALUES) { | |
| mpfr::TernaryInput<bfloat16> input{x, y, z}; | |
| EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fma, input, | |
| LIBC_NAMESPACE::fmabf16(x, y, z), 0.5); | |
| } | |
| bfloat16 neg_xy = -(x * y); | |
| mpfr::TernaryInput<bfloat16> input{x, y, neg_xy}; | |
| EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fma, input, | |
| LIBC_NAMESPACE::fmabf16(x, y, neg_xy), | |
| 0.5); | |
| } | |
| } | |
| } |