Skip to content

Commit 445837a

Browse files
authored
[libc][math][c23] Add fmaf16 C23 math function. (llvm#130757)
Implementation of fmaf16 function for 16-bit inputs.
1 parent ee3e17d commit 445837a

File tree

19 files changed

+145
-13
lines changed

19 files changed

+145
-13
lines changed

libc/config/gpu/amdgpu/entrypoints.txt

+1
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
548548
libc.src.math.fabsf16
549549
libc.src.math.fdimf16
550550
libc.src.math.floorf16
551+
libc.src.math.fmaf16
551552
libc.src.math.fmaxf16
552553
libc.src.math.fmaximum_mag_numf16
553554
libc.src.math.fmaximum_magf16

libc/config/gpu/nvptx/entrypoints.txt

+1
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
550550
libc.src.math.fabsf16
551551
libc.src.math.fdimf16
552552
libc.src.math.floorf16
553+
libc.src.math.fmaf16
553554
libc.src.math.fmaxf16
554555
libc.src.math.fmaximum_mag_numf16
555556
libc.src.math.fmaximum_magf16

libc/config/linux/aarch64/entrypoints.txt

+1
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
678678
libc.src.math.ffma
679679
libc.src.math.ffmal
680680
libc.src.math.floorf16
681+
libc.src.math.fmaf16
681682
libc.src.math.fmaxf16
682683
libc.src.math.fmaximum_mag_numf16
683684
libc.src.math.fmaximum_magf16

libc/config/linux/x86_64/entrypoints.txt

+1
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
688688
libc.src.math.fabsf16
689689
libc.src.math.fdimf16
690690
libc.src.math.floorf16
691+
libc.src.math.fmaf16
691692
libc.src.math.fmaxf16
692693
libc.src.math.fmaximum_mag_numf16
693694
libc.src.math.fmaximum_magf16

libc/docs/headers/math/index.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ Higher Math Functions
299299
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
300300
| expm1 | |check| | |check| | | |check| | | 7.12.6.6 | F.10.3.6 |
301301
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
302-
| fma | |check| | |check| | | | | 7.12.13.1 | F.10.10.1 |
302+
| fma | |check| | |check| | | |check| | | 7.12.13.1 | F.10.10.1 |
303303
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
304304
| f16sqrt | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.6 | F.10.11 |
305305
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+

libc/include/math.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,15 @@ functions:
749749
- type: float
750750
- type: float
751751
- type: float
752+
- name: fmaf16
753+
standards:
754+
- stdc
755+
return_type: _Float16
756+
arguments:
757+
- type: _Float16
758+
- type: _Float16
759+
- type: _Float16
760+
guard: LIBC_TYPES_HAS_FLOAT16
752761
- name: fmax
753762
standards:
754763
- stdc

libc/src/math/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ add_math_entrypoint_object(floorf128)
210210

211211
add_math_entrypoint_object(fma)
212212
add_math_entrypoint_object(fmaf)
213+
add_math_entrypoint_object(fmaf16)
213214

214215
add_math_entrypoint_object(fmax)
215216
add_math_entrypoint_object(fmaxf)

libc/src/math/fmaf16.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for fmaf16 ------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_MATH_FMAF16_H
10+
#define LLVM_LIBC_SRC_MATH_FMAF16_H
11+
12+
#include "src/__support/macros/config.h"
13+
#include "src/__support/macros/properties/types.h"
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
float16 fmaf16(float16 x, float16 y, float16 z);
18+
19+
} // namespace LIBC_NAMESPACE_DECL
20+
21+
#endif // LLVM_LIBC_SRC_MATH_FMAF16_H

libc/src/math/generic/CMakeLists.txt

+11
Original file line numberDiff line numberDiff line change
@@ -4287,6 +4287,17 @@ add_entrypoint_object(
42874287
libc.src.__support.FPUtil.fma
42884288
)
42894289

4290+
add_entrypoint_object(
4291+
fmaf16
4292+
SRCS
4293+
fmaf16.cpp
4294+
HDRS
4295+
../fmaf16.h
4296+
DEPENDS
4297+
libc.src.__support.FPUtil.fma
4298+
libc.src.__support.macros.properties.types
4299+
)
4300+
42904301
add_entrypoint_object(
42914302
fma
42924303
SRCS

libc/src/math/generic/fmaf16.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation of fmaf16 function ---------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/math/fmaf16.h"
10+
#include "src/__support/FPUtil/FMA.h"
11+
#include "src/__support/common.h"
12+
#include "src/__support/macros/config.h"
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
16+
LLVM_LIBC_FUNCTION(float16, fmaf16, (float16 x, float16 y, float16 z)) {
17+
return fputil::fma<float16>(x, y, z);
18+
}
19+
20+
} // namespace LIBC_NAMESPACE_DECL

libc/test/src/math/CMakeLists.txt

+15
Original file line numberDiff line numberDiff line change
@@ -1776,6 +1776,21 @@ add_fp_unittest(
17761776
FMA_OPT__ONLY
17771777
)
17781778

1779+
add_fp_unittest(
1780+
fmaf16_test
1781+
NEED_MPFR
1782+
SUITE
1783+
libc-math-unittests
1784+
SRCS
1785+
fmaf16_test.cpp
1786+
HDRS
1787+
FmaTest.h
1788+
DEPENDS
1789+
libc.src.math.fmaf16
1790+
libc.src.stdlib.rand
1791+
libc.src.stdlib.srand
1792+
)
1793+
17791794
add_fp_unittest(
17801795
fma_test
17811796
NEED_MPFR

libc/test/src/math/FmaTest.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
5858

5959
void test_subnormal_range(FmaFunc func) {
6060
constexpr InStorageType COUNT = 100'001;
61-
constexpr InStorageType STEP =
61+
constexpr InStorageType RAW_STEP =
6262
(IN_MAX_SUBNORMAL_U - IN_MIN_SUBNORMAL_U) / COUNT;
63+
constexpr InStorageType STEP = (RAW_STEP == 0 ? 1 : RAW_STEP);
6364
LIBC_NAMESPACE::srand(1);
6465
for (InStorageType v = IN_MIN_SUBNORMAL_U, w = IN_MAX_SUBNORMAL_U;
6566
v <= IN_MAX_SUBNORMAL_U && w >= IN_MIN_SUBNORMAL_U;
@@ -75,7 +76,9 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
7576

7677
void test_normal_range(FmaFunc func) {
7778
constexpr InStorageType COUNT = 100'001;
78-
constexpr InStorageType STEP = (IN_MAX_NORMAL_U - IN_MIN_NORMAL_U) / COUNT;
79+
constexpr InStorageType RAW_STEP =
80+
(IN_MAX_NORMAL_U - IN_MIN_NORMAL_U) / COUNT;
81+
constexpr InStorageType STEP = (RAW_STEP == 0 ? 1 : RAW_STEP);
7982
LIBC_NAMESPACE::srand(1);
8083
for (InStorageType v = IN_MIN_NORMAL_U, w = IN_MAX_NORMAL_U;
8184
v <= IN_MAX_NORMAL_U && w >= IN_MIN_NORMAL_U; v += STEP, w -= STEP) {

libc/test/src/math/fmaf16_test.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//===-- Unittests for fmaf16 ----------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "FmaTest.h"
10+
11+
#include "src/math/fmaf16.h"
12+
13+
LIST_FMA_TESTS(float16, LIBC_NAMESPACE::fmaf16)

libc/test/src/math/smoke/CMakeLists.txt

+13
Original file line numberDiff line numberDiff line change
@@ -3562,6 +3562,19 @@ add_fp_unittest(
35623562
libc.src.__support.macros.properties.types
35633563
)
35643564

3565+
add_fp_unittest(
3566+
fmaf16_test
3567+
SUITE
3568+
libc-math-smoke-tests
3569+
SRCS
3570+
fmaf16_test.cpp
3571+
HDRS
3572+
FmaTest.h
3573+
DEPENDS
3574+
libc.src.math.fmaf16
3575+
libc.src.__support.FPUtil.cast
3576+
)
3577+
35653578
add_fp_unittest(
35663579
fma_test
35673580
SUITE

libc/test/src/math/smoke/FmaTest.h

+2-10
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99
#ifndef LLVM_LIBC_TEST_SRC_MATH_FMATEST_H
1010
#define LLVM_LIBC_TEST_SRC_MATH_FMATEST_H
1111

12-
#include "src/__support/CPP/type_traits.h"
1312
#include "src/__support/FPUtil/cast.h"
14-
#include "src/__support/macros/properties/types.h"
1513
#include "test/UnitTest/FEnvSafeTest.h"
1614
#include "test/UnitTest/FPMatcher.h"
1715
#include "test/UnitTest/Test.h"
@@ -90,14 +88,8 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
9088
// Test overflow.
9189
OutType z = out.max_normal;
9290
InType in_z = LIBC_NAMESPACE::fputil::cast<InType>(out.max_normal);
93-
#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
94-
// Rounding modes other than the default might not be usable with float16.
95-
if constexpr (LIBC_NAMESPACE::cpp::is_same_v<OutType, float16>)
96-
EXPECT_FP_EQ(OutType(0.75) * z, func(InType(1.75), in_z, -in_z));
97-
else
98-
#endif
99-
EXPECT_FP_EQ_ALL_ROUNDING(OutType(0.75) * z,
100-
func(InType(1.75), in_z, -in_z));
91+
EXPECT_FP_EQ_ALL_ROUNDING(OutType(0.75) * z,
92+
func(InType(1.75), in_z, -in_z));
10193

10294
// Exact cancellation.
10395
EXPECT_FP_EQ_ROUNDING_NEAREST(
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//===-- Unittests for fmaf16 ----------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "FmaTest.h"
10+
11+
#include "src/math/fmaf16.h"
12+
13+
LIST_FMA_TESTS(float16, LIBC_NAMESPACE::fmaf16)

libc/utils/MPFRWrapper/MPFRUtils.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,8 @@ explain_ternary_operation_one_output_error(Operation,
454454
long double, double, RoundingMode);
455455

456456
#ifdef LIBC_TYPES_HAS_FLOAT16
457+
template void explain_ternary_operation_one_output_error(
458+
Operation, const TernaryInput<float16> &, float16, double, RoundingMode);
457459
template void explain_ternary_operation_one_output_error(
458460
Operation, const TernaryInput<float> &, float16, double, RoundingMode);
459461
template void explain_ternary_operation_one_output_error(
@@ -672,6 +674,9 @@ compare_ternary_operation_one_output(Operation,
672674
long double, double, RoundingMode);
673675

674676
#ifdef LIBC_TYPES_HAS_FLOAT16
677+
template bool
678+
compare_ternary_operation_one_output(Operation, const TernaryInput<float16> &,
679+
float16, double, RoundingMode);
675680
template bool compare_ternary_operation_one_output(Operation,
676681
const TernaryInput<float> &,
677682
float16, double,

utils/bazel/llvm-project-overlay/libc/BUILD.bazel

+7
Original file line numberDiff line numberDiff line change
@@ -2845,6 +2845,13 @@ libc_math_function(name = "floorf16")
28452845

28462846
# TODO: Add fma, fmaf, fmal, fmaf128 functions.
28472847

2848+
libc_math_function(
2849+
name = "fmaf16",
2850+
additional_deps = [
2851+
":__support_fputil_fma",
2852+
],
2853+
)
2854+
28482855
libc_math_function(name = "fmax")
28492856

28502857
libc_math_function(name = "fmaxf")

utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel

+5
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,11 @@ math_test(
476476

477477
# TODO: Add fma, fmaf, fmal, fmaf128 tests.
478478

479+
math_test(
480+
name = "fmaf16",
481+
hdrs = ["FmaTest.h"],
482+
)
483+
479484
math_test(
480485
name = "fmax",
481486
hdrs = ["FMaxTest.h"],

0 commit comments

Comments
 (0)