Skip to content

[libc][math][c23] Add fmaf16 C23 math function. #130757

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libc/config/gpu/amdgpu/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions libc/config/gpu/nvptx/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,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
Expand Down
1 change: 1 addition & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,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
Expand Down
2 changes: 1 addition & 1 deletion libc/docs/headers/math/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
Expand Down
9 changes: 9 additions & 0 deletions libc/include/math.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,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
Expand Down
1 change: 1 addition & 0 deletions libc/src/math/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,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)
Expand Down
21 changes: 21 additions & 0 deletions libc/src/math/fmaf16.h
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions libc/src/math/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4241,6 +4241,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
Expand Down
20 changes: 20 additions & 0 deletions libc/src/math/generic/fmaf16.cpp
Original file line number Diff line number Diff line change
@@ -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
15 changes: 15 additions & 0 deletions libc/test/src/math/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions libc/test/src/math/FmaTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {

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;
Expand All @@ -75,7 +76,9 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {

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) {
Expand Down
13 changes: 13 additions & 0 deletions libc/test/src/math/fmaf16_test.cpp
Original file line number Diff line number Diff line change
@@ -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)
13 changes: 13 additions & 0 deletions libc/test/src/math/smoke/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 2 additions & 10 deletions libc/test/src/math/smoke/FmaTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -90,14 +88,8 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
// 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(
Expand Down
13 changes: 13 additions & 0 deletions libc/test/src/math/smoke/fmaf16_test.cpp
Original file line number Diff line number Diff line change
@@ -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)
5 changes: 5 additions & 0 deletions libc/utils/MPFRWrapper/MPFRUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions utils/bazel/llvm-project-overlay/libc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2831,6 +2831,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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,11 @@ math_test(

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

math_test(
name = "fmaf16",
hdrs = ["FmaTest.h"],
)

math_test(
name = "fmax",
hdrs = ["FMaxTest.h"],
Expand Down
Loading