Skip to content

[libc][math][c23] Add {frexp,ilogb,llogb,logb,modf}f16 C23 math functions #94758

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 9 commits into from
Jun 10, 2024
5 changes: 5 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -516,12 +516,17 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.fminimum_magf16
libc.src.math.fminimum_mag_numf16
libc.src.math.fminimum_numf16
libc.src.math.frexpf16
libc.src.math.fromfpf16
libc.src.math.fromfpxf16
libc.src.math.ilogbf16
libc.src.math.llogbf16
libc.src.math.llrintf16
libc.src.math.llroundf16
libc.src.math.logbf16
libc.src.math.lrintf16
libc.src.math.lroundf16
libc.src.math.modff16
libc.src.math.nanf16
libc.src.math.nearbyintf16
libc.src.math.nextafterf16
Expand Down
5 changes: 5 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -549,12 +549,17 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.fminimum_mag_numf16
libc.src.math.fminimum_numf16
libc.src.math.fmodf16
libc.src.math.frexpf16
libc.src.math.fromfpf16
libc.src.math.fromfpxf16
libc.src.math.ilogbf16
libc.src.math.llogbf16
libc.src.math.llrintf16
libc.src.math.llroundf16
libc.src.math.logbf16
libc.src.math.lrintf16
libc.src.math.lroundf16
libc.src.math.modff16
libc.src.math.nanf16
libc.src.math.nearbyintf16
libc.src.math.nextafterf16
Expand Down
2 changes: 1 addition & 1 deletion libc/docs/c23.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Additions:
* issignaling
* issubnormal
* iszero
* llogb*
* llogb* |check|
* pown*
* powr*
* rootn*
Expand Down
10 changes: 5 additions & 5 deletions libc/docs/math/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -160,31 +160,31 @@ Basic Operations
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fmul | N/A | |check| | | N/A | | 7.12.14.3 | F.10.11 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| frexp | |check| | |check| | |check| | | |check| | 7.12.6.7 | F.10.3.7 |
| frexp | |check| | |check| | |check| | |check| | |check| | 7.12.6.7 | F.10.3.7 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fromfp | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fromfpx | |check| | |check| | |check| | |check| | |check| | 7.12.9.11 | F.10.6.11 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| fsub | N/A | | | N/A | | 7.12.14.2 | F.10.11 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| ilogb | |check| | |check| | |check| | | |check| | 7.12.6.8 | F.10.3.8 |
| ilogb | |check| | |check| | |check| | |check| | |check| | 7.12.6.8 | F.10.3.8 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| ldexp | |check| | |check| | |check| | | |check| | 7.12.6.9 | F.10.3.9 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| llogb | |check| | |check| | |check| | | |check| | 7.12.6.10 | F.10.3.10 |
| llogb | |check| | |check| | |check| | |check| | |check| | 7.12.6.10 | F.10.3.10 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| llrint | |check| | |check| | |check| | |check| | |check| | 7.12.9.5 | F.10.6.5 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| llround | |check| | |check| | |check| | |check| | |check| | 7.12.9.7 | F.10.6.7 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| logb | |check| | |check| | |check| | | |check| | 7.12.6.17 | F.10.3.17 |
| logb | |check| | |check| | |check| | |check| | |check| | 7.12.6.17 | F.10.3.17 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| lrint | |check| | |check| | |check| | |check| | |check| | 7.12.9.5 | F.10.6.5 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| lround | |check| | |check| | |check| | |check| | |check| | 7.12.9.7 | F.10.6.7 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| modf | |check| | |check| | |check| | | |check| | 7.12.6.18 | F.10.3.18 |
| modf | |check| | |check| | |check| | |check| | |check| | 7.12.6.18 | F.10.3.18 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| nan | |check| | |check| | |check| | |check| | |check| | 7.12.11.2 | F.10.8.2 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
Expand Down
1 change: 1 addition & 0 deletions libc/spec/spec.td
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def IntPtr : PtrType<IntType>;
def RestrictedIntPtr : RestrictedPtrType<IntType>;
def FloatPtr : PtrType<FloatType>;
def DoublePtr : PtrType<DoubleType>;
def Float16Ptr : PtrType<Float16Type>;
def Float128Ptr : PtrType<Float128Type>;
def UnsignedCharPtr : PtrType<UnsignedCharType>;

Expand Down
5 changes: 5 additions & 0 deletions libc/spec/stdc.td
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"frexp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntPtr>]>,
FunctionSpec<"frexpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntPtr>]>,
FunctionSpec<"frexpl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntPtr>]>,
GuardedFunctionSpec<"frexpf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<IntPtr>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"frexpf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<IntPtr>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fromfp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
Expand Down Expand Up @@ -519,11 +520,13 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"ilogb", RetValSpec<IntType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"ilogbf", RetValSpec<IntType>, [ArgSpec<FloatType>]>,
FunctionSpec<"ilogbl", RetValSpec<IntType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"ilogbf16", RetValSpec<IntType>, [ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"ilogbf128", RetValSpec<IntType>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"llogb", RetValSpec<LongType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"llogbf", RetValSpec<LongType>, [ArgSpec<FloatType>]>,
FunctionSpec<"llogbl", RetValSpec<LongType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"llogbf16", RetValSpec<LongType>, [ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"llogbf128", RetValSpec<LongType>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"ldexp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>]>,
Expand All @@ -546,11 +549,13 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"logb", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"logbf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
FunctionSpec<"logbl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"logbf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"logbf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"modf", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoublePtr>]>,
FunctionSpec<"modff", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatPtr>]>,
FunctionSpec<"modfl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoublePtr>]>,
GuardedFunctionSpec<"modff16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Ptr>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"modff128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Ptr>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"cos", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
Expand Down
1 change: 1 addition & 0 deletions libc/src/__support/FPUtil/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ add_header_library(
.nearest_integer_operations
.normal_float
libc.hdr.math_macros
libc.src.__support.CPP.algorithm
libc.src.__support.CPP.bit
libc.src.__support.CPP.limits
libc.src.__support.CPP.type_traits
Expand Down
5 changes: 3 additions & 2 deletions libc/src/__support/FPUtil/ManipulationFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "rounding_mode.h"

#include "hdr/math_macros.h"
#include "src/__support/CPP/algorithm.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/limits.h" // INT_MAX, INT_MIN
#include "src/__support/CPP/type_traits.h"
Expand Down Expand Up @@ -102,7 +103,7 @@ intlogb(U x) {
return IntLogbConstants<T>::T_MAX;
}

DyadicFloat<FPBits<U>::STORAGE_LEN> normal(bits.get_val());
DyadicFloat<cpp::max(FPBits<U>::STORAGE_LEN, 32)> normal(bits.get_val());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DyadicFloat<Bits> uses UInt<Bits> which requires Bits to be either 32 or a multiple of the size of WordType which is never uint16_t.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe update DyadicFloat to accept Bits to also accept 16?

int exponent = normal.get_unbiased_exponent();
// The C standard does not specify the return value when an exponent is
// out of int range. However, XSI conformance required that INT_MAX or
Expand Down Expand Up @@ -138,7 +139,7 @@ LIBC_INLINE constexpr T logb(T x) {
return FPBits<T>::inf().get_val();
}

DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
DyadicFloat<cpp::max(FPBits<T>::STORAGE_LEN, 32)> normal(bits.get_val());
return static_cast<T>(normal.get_unbiased_exponent());
}

Expand Down
11 changes: 7 additions & 4 deletions libc/src/__support/FPUtil/NormalFloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,11 @@ template <typename T> struct NormalFloat {
if (shift <= FPBits<T>::FRACTION_LEN + 1) {
// Generate a subnormal number. Might lead to loss of precision.
// We round to nearest and round halfway cases to even.
const StorageType shift_out_mask = (StorageType(1) << shift) - 1;
const StorageType shift_out_mask =
static_cast<StorageType>(StorageType(1) << shift) - 1;
const StorageType shift_out_value = mantissa & shift_out_mask;
const StorageType halfway_value = StorageType(1) << (shift - 1);
const StorageType halfway_value =
static_cast<StorageType>(StorageType(1) << (shift - 1));
result.set_biased_exponent(0);
result.set_mantissa(mantissa >> shift);
StorageType new_mantissa = result.get_mantissa();
Expand All @@ -135,7 +137,8 @@ template <typename T> struct NormalFloat {
}
}

result.set_biased_exponent(exponent + FPBits<T>::EXP_BIAS);
result.set_biased_exponent(
static_cast<StorageType>(exponent + FPBits<T>::EXP_BIAS));
result.set_mantissa(mantissa);
return result.get_val();
}
Expand All @@ -155,7 +158,7 @@ template <typename T> struct NormalFloat {
// Normalize subnormal numbers.
if (bits.is_subnormal()) {
unsigned shift = evaluate_normalization_shift(bits.get_mantissa());
mantissa = StorageType(bits.get_mantissa()) << shift;
mantissa = static_cast<StorageType>(bits.get_mantissa() << shift);
exponent = 1 - FPBits<T>::EXP_BIAS - shift;
} else {
exponent = bits.get_biased_exponent() - FPBits<T>::EXP_BIAS;
Expand Down
5 changes: 5 additions & 0 deletions libc/src/math/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ add_math_entrypoint_object(fmodf128)
add_math_entrypoint_object(frexp)
add_math_entrypoint_object(frexpf)
add_math_entrypoint_object(frexpl)
add_math_entrypoint_object(frexpf16)
add_math_entrypoint_object(frexpf128)

add_math_entrypoint_object(fromfp)
Expand All @@ -211,11 +212,13 @@ add_math_entrypoint_object(hypotf)
add_math_entrypoint_object(ilogb)
add_math_entrypoint_object(ilogbf)
add_math_entrypoint_object(ilogbl)
add_math_entrypoint_object(ilogbf16)
add_math_entrypoint_object(ilogbf128)

add_math_entrypoint_object(llogb)
add_math_entrypoint_object(llogbf)
add_math_entrypoint_object(llogbl)
add_math_entrypoint_object(llogbf16)
add_math_entrypoint_object(llogbf128)

add_math_entrypoint_object(ldexp)
Expand All @@ -238,6 +241,7 @@ add_math_entrypoint_object(logf)
add_math_entrypoint_object(logb)
add_math_entrypoint_object(logbf)
add_math_entrypoint_object(logbl)
add_math_entrypoint_object(logbf16)
add_math_entrypoint_object(logbf128)

add_math_entrypoint_object(llrint)
Expand Down Expand Up @@ -267,6 +271,7 @@ add_math_entrypoint_object(lroundf128)
add_math_entrypoint_object(modf)
add_math_entrypoint_object(modff)
add_math_entrypoint_object(modfl)
add_math_entrypoint_object(modff16)
add_math_entrypoint_object(modff128)

add_math_entrypoint_object(nan)
Expand Down
20 changes: 20 additions & 0 deletions libc/src/math/frexpf16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation header for frexpf16 ----------------------*- 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_FREXPF16_H
#define LLVM_LIBC_SRC_MATH_FREXPF16_H

#include "src/__support/macros/properties/types.h"

namespace LIBC_NAMESPACE {

float16 frexpf16(float16 x, int *exp);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_FREXPF16_H
66 changes: 66 additions & 0 deletions libc/src/math/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,19 @@ add_entrypoint_object(
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
frexpf16
SRCS
frexpf16.cpp
HDRS
../frexpf16.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
frexpf128
SRCS
Expand Down Expand Up @@ -1350,6 +1363,19 @@ add_entrypoint_object(
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
ilogbf16
SRCS
ilogbf16.cpp
HDRS
../ilogbf16.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
ilogbf128
SRCS
Expand Down Expand Up @@ -1399,6 +1425,19 @@ add_entrypoint_object(
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
llogbf16
SRCS
llogbf16.cpp
HDRS
../llogbf16.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
llogbf128
SRCS
Expand Down Expand Up @@ -1672,6 +1711,19 @@ add_entrypoint_object(
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
logbf16
SRCS
logbf16.cpp
HDRS
../logbf16.h
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.manipulation_functions
)

add_entrypoint_object(
logbf128
SRCS
Expand All @@ -1681,6 +1733,7 @@ add_entrypoint_object(
COMPILE_OPTIONS
-O3
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.manipulation_functions
)

Expand Down Expand Up @@ -1720,6 +1773,19 @@ add_entrypoint_object(
-O3
)

add_entrypoint_object(
modff16
SRCS
modff16.cpp
HDRS
../modff16.h
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.manipulation_functions
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
modff128
SRCS
Expand Down
19 changes: 19 additions & 0 deletions libc/src/math/generic/frexpf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of frexpf16 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/frexpf16.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float16, frexpf16, (float16 x, int *exp)) {
return fputil::frexp(x, *exp);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/ilogbf16.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of ilogbf16 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/ilogbf16.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(int, ilogbf16, (float16 x)) {
return fputil::intlogb<int>(x);
}

} // namespace LIBC_NAMESPACE
Loading
Loading