[libc][math] Add C23 ldexpf128 math function and fix DyadicFloat conversions for subnormal ranges and 80-bit floating points. by lntue · Pull Request #81780 · llvm/llvm-project (original) (raw)

@llvm/pr-subscribers-libc

Author: None (lntue)

Changes


Patch is 23.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/81780.diff

20 Files Affected:

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index bc09f488122865..6e194682df4bfc 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -387,6 +387,7 @@ if(LIBC_COMPILER_HAS_FLOAT128) libc.src.math.fmaxf128 libc.src.math.fminf128 libc.src.math.frexpf128 + libc.src.math.ldexpf128 libc.src.math.roundf128 libc.src.math.sqrtf128 libc.src.math.truncf128 diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 02412e7549a3d5..71ff4bcfc35195 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -396,6 +396,7 @@ if(LIBC_COMPILER_HAS_FLOAT128) libc.src.math.fmaxf128 libc.src.math.fminf128 libc.src.math.frexpf128 + libc.src.math.ldexpf128 libc.src.math.roundf128 libc.src.math.sqrtf128 libc.src.math.truncf128 diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 57b4a1e0f93d4f..33f6e97af0e183 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -435,6 +435,7 @@ if(LIBC_COMPILER_HAS_FLOAT128) libc.src.math.fmaxf128 libc.src.math.fminf128 libc.src.math.frexpf128 + libc.src.math.ldexpf128 libc.src.math.roundf128 libc.src.math.sqrtf128 libc.src.math.truncf128 diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst index bd2af656d9eecd..c586fe6664e27f 100644 --- a/libc/docs/math/index.rst +++ b/libc/docs/math/index.rst @@ -191,6 +191,8 @@ Basic Operations +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | ldexpl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ +| ldexpf128 | |check| | |check| | | |check| | | | | | | | | | ++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | llrint | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | llrintf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index 9ed94638f522ca..79487cb697f320 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -413,6 +413,7 @@ def StdC : StandardSpec<"stdc"> { FunctionSpec<"ldexp", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"ldexpf", RetValSpec, [ArgSpec, ArgSpec]>, FunctionSpec<"ldexpl", RetValSpec, [ArgSpec, ArgSpec]>, + GuardedFunctionSpec<"ldexpf128", RetValSpec, [ArgSpec, ArgSpec], "LIBC_COMPILER_HAS_FLOAT128">, FunctionSpec<"log10", RetValSpec, [ArgSpec]>, FunctionSpec<"log10f", RetValSpec, [ArgSpec]>, diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt index 3307d33434f0b3..0c932e8ffcd550 100644 --- a/libc/src/__support/FPUtil/CMakeLists.txt +++ b/libc/src/__support/FPUtil/CMakeLists.txt @@ -75,24 +75,6 @@ add_header_library( libc.src.__support.common ) -add_header_library( - manipulation_functions - HDRS - ManipulationFunctions.h - DEPENDS - .fenv_impl - .fp_bits - .nearest_integer_operations - .normal_float - libc.src.__support.CPP.bit - libc.src.__support.CPP.limits - libc.src.__support.CPP.type_traits - libc.src.__support.common - libc.src.__support.macros.optimization - libc.include.math - libc.src.errno.errno -)

add_header_library( basic_operations HDRS @@ -221,4 +203,23 @@ add_header_library( libc.src.__support.macros.optimization )

+add_header_library(

+) + add_subdirectory(generic) diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h index 6665c90845683b..92ffe0c5a1e749 100644 --- a/libc/src/__support/FPUtil/FPBits.h +++ b/libc/src/__support/FPUtil/FPBits.h @@ -633,13 +633,13 @@ struct FPRepImpl : public FPRepSem<fp_type, RetT> { using typename UP::Significand;

using UP::FP_MASK;

public: // Constants. using UP::EXP_BIAS; using UP::EXP_MASK; using UP::FRACTION_MASK;

@@ -735,8 +735,8 @@ struct FPRepImpl : public FPRepSem<fp_type, RetT> { // FIXME: Use an uint32_t for 'biased_exp'. LIBC_INLINE static constexpr RetT create_value(Sign sign, StorageType biased_exp, StorageType mantissa) {

} diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h index 9becbaa45eadeb..9e760a28f42d75 100644 --- a/libc/src/__support/FPUtil/ManipulationFunctions.h +++ b/libc/src/__support/FPUtil/ManipulationFunctions.h @@ -12,6 +12,8 @@ #include "FPBits.h" #include "NearestIntegerOperations.h" #include "NormalFloat.h" +#include "dyadic_float.h" +#include "rounding_mode.h"

#include "src/__support/CPP/bit.h" #include "src/__support/CPP/limits.h" // INT_MAX, INT_MIN @@ -117,10 +119,8 @@ LIBC_INLINE T logb(T x) {

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v, int> = 0> LIBC_INLINE T ldexp(T x, int exp) {

FPBits bits(x);

@@ -129,18 +129,40 @@ LIBC_INLINE T ldexp(T x, int exp) { // early. Because the result of the ldexp operation can be a subnormal number, // we need to accommodate the (mantissaWidth + 1) worth of shift in // calculating the limit.

template <typename T, typename U, diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h index a8b3ad7a16d3bb..382904cf13bddb 100644 --- a/libc/src/__support/FPUtil/dyadic_float.h +++ b/libc/src/__support/FPUtil/dyadic_float.h @@ -44,7 +44,7 @@ template struct DyadicFloat { static_assert(FPBits::FRACTION_LEN < Bits); FPBits x_bits(x); sign = x_bits.sign();

@@ -112,49 +119,57 @@ template struct DyadicFloat {

 MantissaType m_hi(mantissa >> shift);

diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index 985585cbfb8902..05ce51e8fc6503 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -149,6 +149,7 @@ add_math_entrypoint_object(ilogbl) add_math_entrypoint_object(ldexp) add_math_entrypoint_object(ldexpf) add_math_entrypoint_object(ldexpl) +add_math_entrypoint_object(ldexpf128)

add_math_entrypoint_object(log10) add_math_entrypoint_object(log10f) diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index fdf383f070697e..259ae1c2793439 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -1001,10 +1001,10 @@ add_entrypoint_object( ldexp.cpp HDRS ../ldexp.h

DEPENDS libc.src.__support.FPUtil.manipulation_functions

)

add_entrypoint_object( @@ -1013,10 +1013,10 @@ add_entrypoint_object( ldexpf.cpp HDRS ../ldexpf.h

DEPENDS libc.src.__support.FPUtil.manipulation_functions

)

add_entrypoint_object( @@ -1025,10 +1025,23 @@ add_entrypoint_object( ldexpl.cpp HDRS ../ldexpl.h

DEPENDS libc.src.__support.FPUtil.manipulation_functions +) + +add_entrypoint_object(

COMPILE_OPTIONS

add_object_library( diff --git a/libc/src/math/generic/ldexpf128.cpp b/libc/src/math/generic/ldexpf128.cpp new file mode 100644 index 00000000000000..ed2ebd38dfae75 --- /dev/null +++ b/libc/src/math/generic/ldexpf128.cpp @@ -0,0 +1,19 @@ +//===-- Implementation of ldexpf128 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/ldexpf128.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(float128, ldexpf128, (float128 x, int exp)) {

+#define LLVM_LIBC_SRC_MATH_LDEXPF128_H + +#include "src/__support/macros/properties/float.h" + +namespace LIBC_NAMESPACE { + +float128 ldexpf128(float128 x, int exp); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_MATH_LDEXPF128_H diff --git a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp index a9f9842c503057..625aa70973b9f1 100644 --- a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp +++ b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp @@ -56,3 +56,37 @@ TEST(LlvmLibcDyadicFloatTest, QuickMul) { Float256 z = quick_mul(x, y); EXPECT_FP_EQ_ALL_ROUNDING(double(x) * double(y), double(z)); } + +#define TEST_EDGE_RANGES(Name, Type) \