[libc][math][c23] Add fmaf16 C23 math function. (#130757)
Implementation of fmaf16 function for 16-bit inputs.
This commit is contained in:
parent
ee3e17d67f
commit
445837a363
@ -548,6 +548,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
|
||||
libc.src.math.fabsf16
|
||||
libc.src.math.fdimf16
|
||||
libc.src.math.floorf16
|
||||
libc.src.math.fmaf16
|
||||
libc.src.math.fmaxf16
|
||||
libc.src.math.fmaximum_mag_numf16
|
||||
libc.src.math.fmaximum_magf16
|
||||
|
@ -550,6 +550,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
|
||||
libc.src.math.fabsf16
|
||||
libc.src.math.fdimf16
|
||||
libc.src.math.floorf16
|
||||
libc.src.math.fmaf16
|
||||
libc.src.math.fmaxf16
|
||||
libc.src.math.fmaximum_mag_numf16
|
||||
libc.src.math.fmaximum_magf16
|
||||
|
@ -678,6 +678,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
|
||||
libc.src.math.ffma
|
||||
libc.src.math.ffmal
|
||||
libc.src.math.floorf16
|
||||
libc.src.math.fmaf16
|
||||
libc.src.math.fmaxf16
|
||||
libc.src.math.fmaximum_mag_numf16
|
||||
libc.src.math.fmaximum_magf16
|
||||
|
@ -688,6 +688,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
|
||||
libc.src.math.fabsf16
|
||||
libc.src.math.fdimf16
|
||||
libc.src.math.floorf16
|
||||
libc.src.math.fmaf16
|
||||
libc.src.math.fmaxf16
|
||||
libc.src.math.fmaximum_mag_numf16
|
||||
libc.src.math.fmaximum_magf16
|
||||
|
@ -299,7 +299,7 @@ Higher Math Functions
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
|
||||
| expm1 | |check| | |check| | | |check| | | 7.12.6.6 | F.10.3.6 |
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
|
||||
| fma | |check| | |check| | | | | 7.12.13.1 | F.10.10.1 |
|
||||
| fma | |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 |
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
|
||||
|
@ -749,6 +749,15 @@ functions:
|
||||
- type: float
|
||||
- type: float
|
||||
- type: float
|
||||
- name: fmaf16
|
||||
standards:
|
||||
- stdc
|
||||
return_type: _Float16
|
||||
arguments:
|
||||
- type: _Float16
|
||||
- type: _Float16
|
||||
- type: _Float16
|
||||
guard: LIBC_TYPES_HAS_FLOAT16
|
||||
- name: fmax
|
||||
standards:
|
||||
- stdc
|
||||
|
@ -210,6 +210,7 @@ add_math_entrypoint_object(floorf128)
|
||||
|
||||
add_math_entrypoint_object(fma)
|
||||
add_math_entrypoint_object(fmaf)
|
||||
add_math_entrypoint_object(fmaf16)
|
||||
|
||||
add_math_entrypoint_object(fmax)
|
||||
add_math_entrypoint_object(fmaxf)
|
||||
|
21
libc/src/math/fmaf16.h
Normal file
21
libc/src/math/fmaf16.h
Normal file
@ -0,0 +1,21 @@
|
||||
//===-- Implementation header for fmaf16 ------------------------*- 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_FMAF16_H
|
||||
#define LLVM_LIBC_SRC_MATH_FMAF16_H
|
||||
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/properties/types.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
float16 fmaf16(float16 x, float16 y, float16 z);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_FMAF16_H
|
@ -4287,6 +4287,17 @@ add_entrypoint_object(
|
||||
libc.src.__support.FPUtil.fma
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
fmaf16
|
||||
SRCS
|
||||
fmaf16.cpp
|
||||
HDRS
|
||||
../fmaf16.h
|
||||
DEPENDS
|
||||
libc.src.__support.FPUtil.fma
|
||||
libc.src.__support.macros.properties.types
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
fma
|
||||
SRCS
|
||||
|
20
libc/src/math/generic/fmaf16.cpp
Normal file
20
libc/src/math/generic/fmaf16.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
//===-- Implementation of fmaf16 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/fmaf16.h"
|
||||
#include "src/__support/FPUtil/FMA.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(float16, fmaf16, (float16 x, float16 y, float16 z)) {
|
||||
return fputil::fma<float16>(x, y, z);
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
@ -1776,6 +1776,21 @@ add_fp_unittest(
|
||||
FMA_OPT__ONLY
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
fmaf16_test
|
||||
NEED_MPFR
|
||||
SUITE
|
||||
libc-math-unittests
|
||||
SRCS
|
||||
fmaf16_test.cpp
|
||||
HDRS
|
||||
FmaTest.h
|
||||
DEPENDS
|
||||
libc.src.math.fmaf16
|
||||
libc.src.stdlib.rand
|
||||
libc.src.stdlib.srand
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
fma_test
|
||||
NEED_MPFR
|
||||
|
@ -58,8 +58,9 @@ public:
|
||||
|
||||
void test_subnormal_range(FmaFunc func) {
|
||||
constexpr InStorageType COUNT = 100'001;
|
||||
constexpr InStorageType STEP =
|
||||
constexpr InStorageType RAW_STEP =
|
||||
(IN_MAX_SUBNORMAL_U - IN_MIN_SUBNORMAL_U) / COUNT;
|
||||
constexpr InStorageType STEP = (RAW_STEP == 0 ? 1 : RAW_STEP);
|
||||
LIBC_NAMESPACE::srand(1);
|
||||
for (InStorageType v = IN_MIN_SUBNORMAL_U, w = IN_MAX_SUBNORMAL_U;
|
||||
v <= IN_MAX_SUBNORMAL_U && w >= IN_MIN_SUBNORMAL_U;
|
||||
@ -75,7 +76,9 @@ public:
|
||||
|
||||
void test_normal_range(FmaFunc func) {
|
||||
constexpr InStorageType COUNT = 100'001;
|
||||
constexpr InStorageType STEP = (IN_MAX_NORMAL_U - IN_MIN_NORMAL_U) / COUNT;
|
||||
constexpr InStorageType RAW_STEP =
|
||||
(IN_MAX_NORMAL_U - IN_MIN_NORMAL_U) / COUNT;
|
||||
constexpr InStorageType STEP = (RAW_STEP == 0 ? 1 : RAW_STEP);
|
||||
LIBC_NAMESPACE::srand(1);
|
||||
for (InStorageType v = IN_MIN_NORMAL_U, w = IN_MAX_NORMAL_U;
|
||||
v <= IN_MAX_NORMAL_U && w >= IN_MIN_NORMAL_U; v += STEP, w -= STEP) {
|
||||
|
13
libc/test/src/math/fmaf16_test.cpp
Normal file
13
libc/test/src/math/fmaf16_test.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
//===-- Unittests for fmaf16 ----------------------------------------------===//
|
||||
//
|
||||
// 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/math/fmaf16.h"
|
||||
|
||||
LIST_FMA_TESTS(float16, LIBC_NAMESPACE::fmaf16)
|
@ -3562,6 +3562,19 @@ add_fp_unittest(
|
||||
libc.src.__support.macros.properties.types
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
fmaf16_test
|
||||
SUITE
|
||||
libc-math-smoke-tests
|
||||
SRCS
|
||||
fmaf16_test.cpp
|
||||
HDRS
|
||||
FmaTest.h
|
||||
DEPENDS
|
||||
libc.src.math.fmaf16
|
||||
libc.src.__support.FPUtil.cast
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
fma_test
|
||||
SUITE
|
||||
|
@ -9,9 +9,7 @@
|
||||
#ifndef LLVM_LIBC_TEST_SRC_MATH_FMATEST_H
|
||||
#define LLVM_LIBC_TEST_SRC_MATH_FMATEST_H
|
||||
|
||||
#include "src/__support/CPP/type_traits.h"
|
||||
#include "src/__support/FPUtil/cast.h"
|
||||
#include "src/__support/macros/properties/types.h"
|
||||
#include "test/UnitTest/FEnvSafeTest.h"
|
||||
#include "test/UnitTest/FPMatcher.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
@ -90,14 +88,8 @@ public:
|
||||
// Test overflow.
|
||||
OutType z = out.max_normal;
|
||||
InType in_z = LIBC_NAMESPACE::fputil::cast<InType>(out.max_normal);
|
||||
#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
|
||||
// Rounding modes other than the default might not be usable with float16.
|
||||
if constexpr (LIBC_NAMESPACE::cpp::is_same_v<OutType, float16>)
|
||||
EXPECT_FP_EQ(OutType(0.75) * z, func(InType(1.75), in_z, -in_z));
|
||||
else
|
||||
#endif
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(OutType(0.75) * z,
|
||||
func(InType(1.75), in_z, -in_z));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(OutType(0.75) * z,
|
||||
func(InType(1.75), in_z, -in_z));
|
||||
|
||||
// Exact cancellation.
|
||||
EXPECT_FP_EQ_ROUNDING_NEAREST(
|
||||
|
13
libc/test/src/math/smoke/fmaf16_test.cpp
Normal file
13
libc/test/src/math/smoke/fmaf16_test.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
//===-- Unittests for fmaf16 ----------------------------------------------===//
|
||||
//
|
||||
// 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/math/fmaf16.h"
|
||||
|
||||
LIST_FMA_TESTS(float16, LIBC_NAMESPACE::fmaf16)
|
@ -454,6 +454,8 @@ explain_ternary_operation_one_output_error(Operation,
|
||||
long double, double, RoundingMode);
|
||||
|
||||
#ifdef LIBC_TYPES_HAS_FLOAT16
|
||||
template void explain_ternary_operation_one_output_error(
|
||||
Operation, const TernaryInput<float16> &, float16, double, RoundingMode);
|
||||
template void explain_ternary_operation_one_output_error(
|
||||
Operation, const TernaryInput<float> &, float16, double, RoundingMode);
|
||||
template void explain_ternary_operation_one_output_error(
|
||||
@ -672,6 +674,9 @@ compare_ternary_operation_one_output(Operation,
|
||||
long double, double, RoundingMode);
|
||||
|
||||
#ifdef LIBC_TYPES_HAS_FLOAT16
|
||||
template bool
|
||||
compare_ternary_operation_one_output(Operation, const TernaryInput<float16> &,
|
||||
float16, double, RoundingMode);
|
||||
template bool compare_ternary_operation_one_output(Operation,
|
||||
const TernaryInput<float> &,
|
||||
float16, double,
|
||||
|
@ -2845,6 +2845,13 @@ libc_math_function(name = "floorf16")
|
||||
|
||||
# TODO: Add fma, fmaf, fmal, fmaf128 functions.
|
||||
|
||||
libc_math_function(
|
||||
name = "fmaf16",
|
||||
additional_deps = [
|
||||
":__support_fputil_fma",
|
||||
],
|
||||
)
|
||||
|
||||
libc_math_function(name = "fmax")
|
||||
|
||||
libc_math_function(name = "fmaxf")
|
||||
|
@ -476,6 +476,11 @@ math_test(
|
||||
|
||||
# TODO: Add fma, fmaf, fmal, fmaf128 tests.
|
||||
|
||||
math_test(
|
||||
name = "fmaf16",
|
||||
hdrs = ["FmaTest.h"],
|
||||
)
|
||||
|
||||
math_test(
|
||||
name = "fmax",
|
||||
hdrs = ["FMaxTest.h"],
|
||||
|
Loading…
x
Reference in New Issue
Block a user