[libc][math][c++23] Add Fmabf16 math function (#182836)
closes #180171 part of #177259 Here are some extra changes apart from the usual which were needed 1. `libc/src/__support/FPUtil/generic/add_sub.h` → +0 -0 error 2. `libc/src/__support/FPUtil/generic/FMA.h` → implemented to handle fmabf16(Normal,Normal,+/-INF) ```jsx /home/runner/work/llvm-project/llvm-project/libc/test/src/math/fmabf16_test.cpp:62: FAILURE Failed to match __llvm_libc_23_0_0_git::fmabf16(x, y, z) against LIBC_NAMESPACE::testing::mpfr::get_mpfr_matcher<mpfr::Operation::Fma>( input, __llvm_libc_23_0_0_git::fmabf16(x, y, z), 0.5, mpfr::RoundingMode::Nearest). Input decimal: x: 338953138925153547590470800371487866880.00000000000000000000000000000000000000000000000000 y: 338953138925153547590470800371487866880.00000000000000000000000000000000000000000000000000 z: -inf First input bits: 0x7F7F = (S: 0, E: 0x00FE, M: 0x007F) Second input bits: 0x7F7F = (S: 0, E: 0x00FE, M: 0x007F) Third input bits: (-Infinity) Libc result: nan MPFR result: -inf Libc floating point result bits: (NaN) MPFR rounded bits: (-Infinity) ``` 1. ~~`libc/src/__support/FPUtil/bfloat16.h` → to handle *= operator for Bfloat16 ( uses the already available mult operator)~~ moved to #182882 The exhaustive test currently includes subnormal range and for checking for specific edge cases . This is due to the repeated failure at <2^32 input space specifically only for ubuntu 24.04 and 24.04-arm The removed tests included -> PositiveRange and NegativeRange for Normals and an extra positive test for subnormals/Denormals Let me know if there are any changes expected or anything I missed in this . cc: @lntue @krishna2803 @overmighty
This commit is contained in:
parent
9b61ff210f
commit
0bebee6782
@ -400,6 +400,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.floorf
|
||||
libc.src.math.floorl
|
||||
libc.src.math.fma
|
||||
libc.src.math.fmabf16
|
||||
libc.src.math.fmaf
|
||||
libc.src.math.fmax
|
||||
libc.src.math.fmaxf
|
||||
|
||||
@ -411,6 +411,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.floorf
|
||||
libc.src.math.floorl
|
||||
libc.src.math.fma
|
||||
libc.src.math.fmabf16
|
||||
libc.src.math.fmaf
|
||||
libc.src.math.fmax
|
||||
libc.src.math.fmaxf
|
||||
|
||||
@ -406,6 +406,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.floorf
|
||||
libc.src.math.floorl
|
||||
libc.src.math.fma
|
||||
libc.src.math.fmabf16
|
||||
libc.src.math.fmaf
|
||||
libc.src.math.fmax
|
||||
libc.src.math.fmaxf
|
||||
|
||||
@ -221,6 +221,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.floorf
|
||||
libc.src.math.floorl
|
||||
libc.src.math.fma
|
||||
libc.src.math.fmabf16
|
||||
libc.src.math.fmaf
|
||||
libc.src.math.fmax
|
||||
libc.src.math.fmaxf
|
||||
|
||||
@ -147,6 +147,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
#libc.src.math.floorf
|
||||
#libc.src.math.floorl
|
||||
#libc.src.math.fma
|
||||
#libc.src.math.fmabf16
|
||||
#libc.src.math.fmaf
|
||||
#libc.src.math.fmax
|
||||
#libc.src.math.fmaxf
|
||||
|
||||
@ -340,6 +340,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.floorf
|
||||
libc.src.math.floorl
|
||||
libc.src.math.fma
|
||||
libc.src.math.fmabf16
|
||||
libc.src.math.fmaf
|
||||
libc.src.math.fmax
|
||||
libc.src.math.fmaxf
|
||||
|
||||
@ -340,6 +340,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.floorf
|
||||
libc.src.math.floorl
|
||||
libc.src.math.fma
|
||||
libc.src.math.fmabf16
|
||||
libc.src.math.fmaf
|
||||
libc.src.math.fmax
|
||||
libc.src.math.fmaxf
|
||||
|
||||
@ -487,6 +487,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.floorf
|
||||
libc.src.math.floorl
|
||||
libc.src.math.fma
|
||||
libc.src.math.fmabf16
|
||||
libc.src.math.fmaf
|
||||
libc.src.math.fmax
|
||||
libc.src.math.fmaxf
|
||||
|
||||
@ -311,6 +311,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.floorf
|
||||
libc.src.math.floorl
|
||||
libc.src.math.fma
|
||||
libc.src.math.fmabf16
|
||||
libc.src.math.fmaf
|
||||
libc.src.math.fmax
|
||||
libc.src.math.fmaxf
|
||||
|
||||
@ -495,6 +495,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.floorf
|
||||
libc.src.math.floorl
|
||||
libc.src.math.fma
|
||||
libc.src.math.fmabf16
|
||||
libc.src.math.fmaf
|
||||
libc.src.math.fmax
|
||||
libc.src.math.fmaxf
|
||||
|
||||
@ -541,6 +541,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.floorf
|
||||
libc.src.math.floorl
|
||||
libc.src.math.fma
|
||||
libc.src.math.fmabf16
|
||||
libc.src.math.fmaf
|
||||
libc.src.math.fmax
|
||||
libc.src.math.fmaxf
|
||||
|
||||
@ -192,6 +192,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.floorf
|
||||
libc.src.math.floorl
|
||||
libc.src.math.fma
|
||||
libc.src.math.fmabf16
|
||||
libc.src.math.fmaf
|
||||
libc.src.math.fmin
|
||||
libc.src.math.fminf
|
||||
|
||||
@ -309,7 +309,7 @@ Higher Math Functions
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
| expm1 | |check| | |check| | | |check| | | | 7.12.6.6 | F.10.3.6 |
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
| fma | |check| | |check| | | |check| | | | 7.12.13.1 | F.10.10.1 |
|
||||
| fma | |check| | |check| | | |check| | | |check| | 7.12.13.1 | F.10.10.1 |
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
| f16sqrt | |check|\* | |check|\* | |check|\* | N/A | |check| | | 7.12.14.6 | F.10.11 |
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
|
||||
@ -132,6 +132,7 @@
|
||||
#include "math/floorf128.h"
|
||||
#include "math/floorf16.h"
|
||||
#include "math/floorl.h"
|
||||
#include "math/fmabf16.h"
|
||||
#include "math/fmax.h"
|
||||
#include "math/fmaxbf16.h"
|
||||
#include "math/fmaxf.h"
|
||||
|
||||
23
libc/shared/math/fmabf16.h
Normal file
23
libc/shared/math/fmabf16.h
Normal file
@ -0,0 +1,23 @@
|
||||
//===-- Shared fmabf16 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_FMABF16_H
|
||||
#define LLVM_LIBC_SHARED_MATH_FMABF16_H
|
||||
|
||||
#include "shared/libc_common.h"
|
||||
#include "src/__support/math/fmabf16.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace shared {
|
||||
|
||||
using math::fmabf16;
|
||||
|
||||
} // namespace shared
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SHARED_MATH_FMABF16_H
|
||||
@ -198,8 +198,13 @@ fma(InType x, InType y, InType z) {
|
||||
|
||||
if (LIBC_UNLIKELY(x_exp == InFPBits::MAX_BIASED_EXPONENT ||
|
||||
y_exp == InFPBits::MAX_BIASED_EXPONENT ||
|
||||
z_exp == InFPBits::MAX_BIASED_EXPONENT))
|
||||
z_exp == InFPBits::MAX_BIASED_EXPONENT)) {
|
||||
if (LIBC_UNLIKELY(x_exp != InFPBits::MAX_BIASED_EXPONENT &&
|
||||
y_exp != InFPBits::MAX_BIASED_EXPONENT &&
|
||||
z_bits.is_inf()))
|
||||
return cast<OutType>(z);
|
||||
return cast<OutType>(x * y + z);
|
||||
}
|
||||
|
||||
// Extract mantissa and append hidden leading bits.
|
||||
InStorageType x_mant = x_bits.get_explicit_mantissa();
|
||||
|
||||
@ -1265,6 +1265,17 @@ add_header_library(
|
||||
libc.src.__support.macros.config
|
||||
)
|
||||
|
||||
add_header_library(
|
||||
fmabf16
|
||||
HDRS
|
||||
fmabf16.h
|
||||
DEPENDS
|
||||
libc.src.__support.FPUtil.fma
|
||||
libc.src.__support.FPUtil.bfloat16
|
||||
libc.src.__support.common
|
||||
libc.src.__support.macros.config
|
||||
)
|
||||
|
||||
add_header_library(
|
||||
floor
|
||||
HDRS
|
||||
|
||||
27
libc/src/__support/math/fmabf16.h
Normal file
27
libc/src/__support/math/fmabf16.h
Normal file
@ -0,0 +1,27 @@
|
||||
//===-- Implementation header for fmabf16 ----------------------*- 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_FMABF16_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_MATH_FMABF16_H
|
||||
|
||||
#include "src/__support/FPUtil/FMA.h"
|
||||
#include "src/__support/FPUtil/bfloat16.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace math {
|
||||
|
||||
LIBC_INLINE bfloat16 fmabf16(bfloat16 x, bfloat16 y, bfloat16 z) {
|
||||
return fputil::fma<bfloat16>(x, y, z);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMAXBF16_H
|
||||
@ -229,6 +229,7 @@ add_math_entrypoint_object(floorf128)
|
||||
add_math_entrypoint_object(floorbf16)
|
||||
|
||||
add_math_entrypoint_object(fma)
|
||||
add_math_entrypoint_object(fmabf16)
|
||||
add_math_entrypoint_object(fmaf)
|
||||
add_math_entrypoint_object(fmaf16)
|
||||
|
||||
|
||||
21
libc/src/math/fmabf16.h
Normal file
21
libc/src/math/fmabf16.h
Normal file
@ -0,0 +1,21 @@
|
||||
//===-- Implementation header for fmabf16 -----------------------*- 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_FMABF16_H
|
||||
#define LLVM_LIBC_SRC_MATH_FMABF16_H
|
||||
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/properties/types.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
bfloat16 fmabf16(bfloat16 x, bfloat16 y, bfloat16 z);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_FMABF16_H
|
||||
@ -4375,6 +4375,16 @@ add_entrypoint_object(
|
||||
libc.src.__support.FPUtil.fma
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
fmabf16
|
||||
SRCS
|
||||
fmabf16.cpp
|
||||
HDRS
|
||||
../fmabf16.h
|
||||
DEPENDS
|
||||
libc.src.__support.math.fmabf16
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
totalorder
|
||||
SRCS
|
||||
|
||||
18
libc/src/math/generic/fmabf16.cpp
Normal file
18
libc/src/math/generic/fmabf16.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation of fmabf16 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/fmabf16.h"
|
||||
#include "src/__support/math/fmabf16.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(bfloat16, fmabf16, (bfloat16 x, bfloat16 y, bfloat16 z)) {
|
||||
return math::fmabf16(x, y, z);
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
@ -129,6 +129,7 @@ add_fp_unittest(
|
||||
libc.src.__support.math.floorf128
|
||||
libc.src.__support.math.floorf16
|
||||
libc.src.__support.math.floorl
|
||||
libc.src.__support.math.fmabf16
|
||||
libc.src.__support.math.fmax
|
||||
libc.src.__support.math.fmaxbf16
|
||||
libc.src.__support.math.fmaxf
|
||||
|
||||
@ -427,6 +427,9 @@ TEST(LlvmLibcSharedMathTest, AllBFloat16) {
|
||||
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)));
|
||||
|
||||
|
||||
@ -2012,6 +2012,19 @@ add_fp_unittest(
|
||||
libc.src.stdlib.srand
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
fmabf16_test
|
||||
NEED_MPFR
|
||||
SUITE
|
||||
libc-math-unittests
|
||||
SRCS
|
||||
fmabf16_test.cpp
|
||||
DEPENDS
|
||||
libc.src.math.fmabf16
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
libc.src.__support.FPUtil.bfloat16
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
tan_test
|
||||
NEED_MPFR
|
||||
|
||||
@ -293,6 +293,25 @@ add_fp_unittest(
|
||||
-lpthread
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
fmabf16_test
|
||||
NO_RUN_POSTBUILD
|
||||
NEED_MPFR
|
||||
SUITE
|
||||
libc_math_exhaustive_tests
|
||||
SRCS
|
||||
fmabf16_test.cpp
|
||||
COMPILE_OPTIONS
|
||||
${libc_opt_high_flag}
|
||||
DEPENDS
|
||||
.exhaustive_test
|
||||
libc.src.math.fmabf16
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
libc.src.__support.FPUtil.bfloat16
|
||||
LINK_LIBRARIES
|
||||
-lpthread
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
logf_test
|
||||
NO_RUN_POSTBUILD
|
||||
|
||||
77
libc/test/src/math/exhaustive/fmabf16_test.cpp
Normal file
77
libc/test/src/math/exhaustive/fmabf16_test.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
//===-- Exhaustive tests 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 "exhaustive_test.h"
|
||||
#include "src/__support/FPUtil/FPBits.h"
|
||||
#include "src/__support/FPUtil/bfloat16.h"
|
||||
#include "src/math/fmabf16.h"
|
||||
#include "test/UnitTest/FPMatcher.h"
|
||||
#include "utils/MPFRWrapper/MPCommon.h"
|
||||
#include "utils/MPFRWrapper/MPFRUtils.h"
|
||||
|
||||
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
|
||||
using LIBC_NAMESPACE::fputil::BFloat16;
|
||||
|
||||
struct FmaBf16Checker : public virtual LIBC_NAMESPACE::testing::Test {
|
||||
|
||||
using FloatType = BFloat16;
|
||||
using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>;
|
||||
using StorageType = typename FPBits::StorageType;
|
||||
|
||||
uint64_t check(uint16_t x_start, uint16_t x_stop, uint16_t y_start,
|
||||
uint16_t y_stop, mpfr::RoundingMode rounding) {
|
||||
|
||||
mpfr::ForceRoundingMode r(rounding);
|
||||
if (!r.success)
|
||||
return true;
|
||||
uint16_t xbits = x_start;
|
||||
uint64_t failed = 0;
|
||||
do {
|
||||
BFloat16 x = FPBits(xbits).get_val();
|
||||
uint16_t ybits = y_start;
|
||||
do {
|
||||
BFloat16 y = FPBits(ybits).get_val();
|
||||
BFloat16 z = FPBits(uint16_t(0x03E1)).get_val();
|
||||
mpfr::TernaryInput<BFloat16> input{x, y, z};
|
||||
bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY(
|
||||
mpfr::Operation::Fma, input, LIBC_NAMESPACE::fmabf16(x, y, z), 0.5,
|
||||
rounding);
|
||||
failed += (!correct);
|
||||
|
||||
} while (ybits++ < y_stop);
|
||||
} while (xbits++ < x_stop);
|
||||
return failed;
|
||||
}
|
||||
};
|
||||
|
||||
using LlvmLibcBfloat16ExhaustiveFmaTest =
|
||||
LlvmLibcExhaustiveMathTest<FmaBf16Checker, 1 << 2>;
|
||||
|
||||
// range: [0, inf]
|
||||
static constexpr uint16_t POS_START = 0x0000U;
|
||||
static constexpr uint16_t POS_STOP = 0x7f80U;
|
||||
|
||||
// range: [-0, -inf]
|
||||
static constexpr uint16_t NEG_START = 0x8000U;
|
||||
static constexpr uint16_t NEG_STOP = 0xff80U;
|
||||
|
||||
TEST_F(LlvmLibcBfloat16ExhaustiveFmaTest, PositiveRange) {
|
||||
test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP);
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcBfloat16ExhaustiveFmaTest, PositiveNegative) {
|
||||
test_full_range_all_roundings(POS_START, POS_STOP, NEG_START, NEG_STOP);
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcBfloat16ExhaustiveFmaTest, NegativePositive) {
|
||||
test_full_range_all_roundings(NEG_START, NEG_STOP, POS_START, POS_STOP);
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcBfloat16ExhaustiveFmaTest, NegativeRange) {
|
||||
test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP);
|
||||
}
|
||||
66
libc/test/src/math/fmabf16_test.cpp
Normal file
66
libc/test/src/math/fmabf16_test.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
//===-- 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4281,6 +4281,20 @@ add_fp_unittest(
|
||||
libc.src.__support.macros.properties.types
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
fmabf16_test
|
||||
SUITE
|
||||
libc-math-smoke-tests
|
||||
SRCS
|
||||
fmabf16_test.cpp
|
||||
HDRS
|
||||
FmaTest.h
|
||||
DEPENDS
|
||||
libc.src.math.fmabf16
|
||||
libc.src.__support.FPUtil.bfloat16
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
expm1_test
|
||||
SUITE
|
||||
|
||||
14
libc/test/src/math/smoke/fmabf16_test.cpp
Normal file
14
libc/test/src/math/smoke/fmabf16_test.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
//===-- Unittests 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 "FmaTest.h"
|
||||
|
||||
#include "src/__support/FPUtil/bfloat16.h"
|
||||
#include "src/math/fmabf16.h"
|
||||
|
||||
LIST_FMA_TESTS(bfloat16, LIBC_NAMESPACE::fmabf16)
|
||||
@ -496,6 +496,8 @@ explain_ternary_operation_one_output_error(Operation,
|
||||
float16, double, RoundingMode);
|
||||
#endif
|
||||
|
||||
template void explain_ternary_operation_one_output_error(
|
||||
Operation, const TernaryInput<bfloat16> &, bfloat16, double, RoundingMode);
|
||||
template void explain_ternary_operation_one_output_error(
|
||||
Operation, const TernaryInput<float> &, bfloat16, double, RoundingMode);
|
||||
template void explain_ternary_operation_one_output_error(
|
||||
@ -762,6 +764,9 @@ compare_ternary_operation_one_output(Operation,
|
||||
double, RoundingMode);
|
||||
#endif
|
||||
|
||||
template bool
|
||||
compare_ternary_operation_one_output(Operation, const TernaryInput<bfloat16> &,
|
||||
bfloat16, double, RoundingMode);
|
||||
template bool compare_ternary_operation_one_output(Operation,
|
||||
const TernaryInput<float> &,
|
||||
bfloat16, double,
|
||||
|
||||
@ -4044,6 +4044,17 @@ libc_support_library(
|
||||
],
|
||||
)
|
||||
|
||||
libc_support_library(
|
||||
name = "__support_math_fmabf16",
|
||||
hdrs = ["src/__support/math/fmabf16.h"],
|
||||
deps = [
|
||||
":__support_common",
|
||||
":__support_fputil_bfloat16",
|
||||
":__support_fputil_fma",
|
||||
":__support_macros_config",
|
||||
],
|
||||
)
|
||||
|
||||
libc_support_library(
|
||||
name = "__support_math_fmax",
|
||||
hdrs = ["src/__support/math/fmax.h"],
|
||||
@ -6831,6 +6842,13 @@ libc_math_function(
|
||||
],
|
||||
)
|
||||
|
||||
libc_math_function(
|
||||
name = "fmabf16",
|
||||
additional_deps = [
|
||||
":__support_math_fmabf16",
|
||||
],
|
||||
)
|
||||
|
||||
libc_math_function(
|
||||
name = "fmax",
|
||||
additional_deps = [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user