[libc-commits] [libc] [libc][math] Add C23 math function frexpf128. (PR #81337)
via libc-commits
libc-commits at lists.llvm.org
Fri Feb 9 15:15:37 PST 2024
https://github.com/lntue created https://github.com/llvm/llvm-project/pull/81337
None
>From adb11a8b8c8e1dc42fac87e84ba8567c9edb9738 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue at google.com>
Date: Fri, 9 Feb 2024 18:07:15 -0500
Subject: [PATCH] [libc][math] Add C23 math function frexpf128.
---
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/riscv/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/docs/math/index.rst | 2 +
libc/spec/stdc.td | 1 +
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/frexpf128.h | 20 +++++++
libc/src/math/generic/CMakeLists.txt | 23 ++++++--
libc/src/math/generic/frexpf128.cpp | 19 +++++++
libc/test/src/math/smoke/CMakeLists.txt | 18 ++++---
libc/test/src/math/smoke/FrexpTest.h | 58 ++++++++++-----------
libc/test/src/math/smoke/frexp_test.cpp | 2 +-
libc/test/src/math/smoke/frexpf128_test.cpp | 13 +++++
libc/test/src/math/smoke/frexpf_test.cpp | 2 +-
libc/test/src/math/smoke/frexpl_test.cpp | 2 +-
15 files changed, 119 insertions(+), 45 deletions(-)
create mode 100644 libc/src/math/frexpf128.h
create mode 100644 libc/src/math/generic/frexpf128.cpp
create mode 100644 libc/test/src/math/smoke/frexpf128_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index f75b2679313996..bc09f488122865 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -386,6 +386,7 @@ if(LIBC_COMPILER_HAS_FLOAT128)
libc.src.math.floorf128
libc.src.math.fmaxf128
libc.src.math.fminf128
+ libc.src.math.frexpf128
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 762beb9040154a..02412e7549a3d5 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -395,6 +395,7 @@ if(LIBC_COMPILER_HAS_FLOAT128)
libc.src.math.floorf128
libc.src.math.fmaxf128
libc.src.math.fminf128
+ libc.src.math.frexpf128
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 52a3ce0132bdcb..8ca9375895c49e 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -414,6 +414,7 @@ if(LIBC_COMPILER_HAS_FLOAT128)
libc.src.math.floorf128
libc.src.math.fmaxf128
libc.src.math.fminf128
+ libc.src.math.frexpf128
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 2758b42610d0ed..94604491a73ecb 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -176,6 +176,8 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| frexpl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| frexpf128 | |check| | |check| | | |check| | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ilogb | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ilogbf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 9c8b5e5c466273..afddc77b07da6a 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -401,6 +401,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<"frexpf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<IntPtr>]], "LIBC_COMPILER_HAS_FLOAT128">,
FunctionSpec<"hypot", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"hypotf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 8cdd84a0f67110..985585cbfb8902 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -137,6 +137,7 @@ add_math_entrypoint_object(fmodf)
add_math_entrypoint_object(frexp)
add_math_entrypoint_object(frexpf)
add_math_entrypoint_object(frexpl)
+add_math_entrypoint_object(frexpf128)
add_math_entrypoint_object(hypot)
add_math_entrypoint_object(hypotf)
diff --git a/libc/src/math/frexpf128.h b/libc/src/math/frexpf128.h
new file mode 100644
index 00000000000000..5d70860fa15599
--- /dev/null
+++ b/libc/src/math/frexpf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for frexpf128 ---------------------*- 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_FREXPF128_H
+#define LLVM_LIBC_SRC_MATH_FREXPF128_H
+
+#include "src/__support/macros/properties/float.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 frexpf128(float128 x, int *exp);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FREXPF128_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 3216ec39401f31..fdf383f070697e 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -916,10 +916,10 @@ add_entrypoint_object(
frexp.cpp
HDRS
../frexp.h
+ COMPILE_OPTIONS
+ -O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -928,10 +928,10 @@ add_entrypoint_object(
frexpf.cpp
HDRS
../frexpf.h
+ COMPILE_OPTIONS
+ -O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -940,10 +940,23 @@ add_entrypoint_object(
frexpl.cpp
HDRS
../frexpl.h
+ COMPILE_OPTIONS
+ -O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_entrypoint_object(
+ frexpf128
+ SRCS
+ frexpf128.cpp
+ HDRS
+ ../frexpf128.h
COMPILE_OPTIONS
- -O2
+ -O3
+ DEPENDS
+ libc.src.__support.macros.properties.float
+ libc.src.__support.FPUtil.manipulation_functions
)
add_entrypoint_object(
diff --git a/libc/src/math/generic/frexpf128.cpp b/libc/src/math/generic/frexpf128.cpp
new file mode 100644
index 00000000000000..b50f37d2dab4b3
--- /dev/null
+++ b/libc/src/math/generic/frexpf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of frexpf128 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/frexpf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, frexpf128, (float128 x, int *exp)) {
+ return fputil::frexp(x, *exp);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 93ce0b716cce86..0d55be5d98bdce 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -779,9 +779,7 @@ add_fp_unittest(
HDRS
FrexpTest.h
DEPENDS
- libc.include.math
libc.src.math.frexp
- libc.src.__support.FPUtil.basic_operations
)
add_fp_unittest(
@@ -793,9 +791,7 @@ add_fp_unittest(
HDRS
FrexpTest.h
DEPENDS
- libc.include.math
libc.src.math.frexpf
- libc.src.__support.FPUtil.basic_operations
)
add_fp_unittest(
@@ -807,9 +803,19 @@ add_fp_unittest(
HDRS
FrexpTest.h
DEPENDS
- libc.include.math
libc.src.math.frexpl
- libc.src.__support.FPUtil.basic_operations
+)
+
+add_fp_unittest(
+ frexpf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ frexpf128_test.cpp
+ HDRS
+ FrexpTest.h
+ DEPENDS
+ libc.src.math.frexpf128
)
# FIXME: These tests are currently broken for NVPTX.
diff --git a/libc/test/src/math/smoke/FrexpTest.h b/libc/test/src/math/smoke/FrexpTest.h
index 981872aa128e13..bf99a9a559f053 100644
--- a/libc/test/src/math/smoke/FrexpTest.h
+++ b/libc/test/src/math/smoke/FrexpTest.h
@@ -10,81 +10,76 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
-
template <typename T> class FrexpTest : public LIBC_NAMESPACE::testing::Test {
DECLARE_SPECIAL_CONSTANTS(T)
- static constexpr StorageType HIDDEN_BIT =
- StorageType(1) << LIBC_NAMESPACE::fputil::FPBits<T>::FRACTION_LEN;
-
public:
typedef T (*FrexpFunc)(T, int *);
void testSpecialNumbers(FrexpFunc func) {
int exponent;
- ASSERT_FP_EQ(aNaN, func(aNaN, &exponent));
- ASSERT_FP_EQ(inf, func(inf, &exponent));
- ASSERT_FP_EQ(neg_inf, func(neg_inf, &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(aNaN, &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, func(inf, &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, func(neg_inf, &exponent));
- ASSERT_FP_EQ(0.0, func(0.0, &exponent));
- ASSERT_EQ(exponent, 0);
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0, func(0.0, &exponent));
+ EXPECT_EQ(exponent, 0);
- ASSERT_FP_EQ(-0.0, func(-0.0, &exponent));
- ASSERT_EQ(exponent, 0);
+ EXPECT_FP_EQ_ALL_ROUNDING(-0.0, func(-0.0, &exponent));
+ EXPECT_EQ(exponent, 0);
}
void testPowersOfTwo(FrexpFunc func) {
int exponent;
- EXPECT_FP_EQ(T(0.5), func(T(1.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(1.0), &exponent));
EXPECT_EQ(exponent, 1);
- EXPECT_FP_EQ(T(-0.5), func(T(-1.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-1.0), &exponent));
EXPECT_EQ(exponent, 1);
- EXPECT_FP_EQ(T(0.5), func(T(2.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(2.0), &exponent));
EXPECT_EQ(exponent, 2);
- EXPECT_FP_EQ(T(-0.5), func(T(-2.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-2.0), &exponent));
EXPECT_EQ(exponent, 2);
- EXPECT_FP_EQ(T(0.5), func(T(4.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(4.0), &exponent));
EXPECT_EQ(exponent, 3);
- EXPECT_FP_EQ(T(-0.5), func(T(-4.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-4.0), &exponent));
EXPECT_EQ(exponent, 3);
- EXPECT_FP_EQ(T(0.5), func(T(8.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(8.0), &exponent));
EXPECT_EQ(exponent, 4);
- EXPECT_FP_EQ(T(-0.5), func(T(-8.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-8.0), &exponent));
EXPECT_EQ(exponent, 4);
- EXPECT_FP_EQ(T(0.5), func(T(16.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(16.0), &exponent));
EXPECT_EQ(exponent, 5);
- EXPECT_FP_EQ(T(-0.5), func(T(-16.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-16.0), &exponent));
EXPECT_EQ(exponent, 5);
- EXPECT_FP_EQ(T(0.5), func(T(32.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(32.0), &exponent));
EXPECT_EQ(exponent, 6);
- EXPECT_FP_EQ(T(-0.5), func(T(-32.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-32.0), &exponent));
EXPECT_EQ(exponent, 6);
}
void testSomeIntegers(FrexpFunc func) {
int exponent;
- EXPECT_FP_EQ(T(0.75), func(T(24.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.75), func(T(24.0), &exponent));
EXPECT_EQ(exponent, 5);
- EXPECT_FP_EQ(T(-0.75), func(T(-24.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.75), func(T(-24.0), &exponent));
EXPECT_EQ(exponent, 5);
- EXPECT_FP_EQ(T(0.625), func(T(40.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.625), func(T(40.0), &exponent));
EXPECT_EQ(exponent, 6);
- EXPECT_FP_EQ(T(-0.625), func(T(-40.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.625), func(T(-40.0), &exponent));
EXPECT_EQ(exponent, 6);
- EXPECT_FP_EQ(T(0.78125), func(T(800.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.78125), func(T(800.0), &exponent));
EXPECT_EQ(exponent, 10);
- EXPECT_FP_EQ(T(-0.78125), func(T(-800.0), &exponent));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.78125), func(T(-800.0), &exponent));
EXPECT_EQ(exponent, 10);
}
};
@@ -93,4 +88,5 @@ template <typename T> class FrexpTest : public LIBC_NAMESPACE::testing::Test {
using LlvmLibcFrexpTest = FrexpTest<T>; \
TEST_F(LlvmLibcFrexpTest, SpecialNumbers) { testSpecialNumbers(&func); } \
TEST_F(LlvmLibcFrexpTest, PowersOfTwo) { testPowersOfTwo(&func); } \
- TEST_F(LlvmLibcFrexpTest, SomeIntegers) { testSomeIntegers(&func); }
+ TEST_F(LlvmLibcFrexpTest, SomeIntegers) { testSomeIntegers(&func); } \
+ static_assert(true, "Require semicolon.")
diff --git a/libc/test/src/math/smoke/frexp_test.cpp b/libc/test/src/math/smoke/frexp_test.cpp
index 4d078baffcb393..79aa9723d3147d 100644
--- a/libc/test/src/math/smoke/frexp_test.cpp
+++ b/libc/test/src/math/smoke/frexp_test.cpp
@@ -10,4 +10,4 @@
#include "src/math/frexp.h"
-LIST_FREXP_TESTS(double, LIBC_NAMESPACE::frexp)
+LIST_FREXP_TESTS(double, LIBC_NAMESPACE::frexp);
diff --git a/libc/test/src/math/smoke/frexpf128_test.cpp b/libc/test/src/math/smoke/frexpf128_test.cpp
new file mode 100644
index 00000000000000..a0df32f5fbdd9e
--- /dev/null
+++ b/libc/test/src/math/smoke/frexpf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for frexpf128 -------------------------------------------===//
+//
+// 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 "FrexpTest.h"
+
+#include "src/math/frexpf128.h"
+
+LIST_FREXP_TESTS(float128, LIBC_NAMESPACE::frexpf128);
diff --git a/libc/test/src/math/smoke/frexpf_test.cpp b/libc/test/src/math/smoke/frexpf_test.cpp
index 577eb9609cfcc5..f2ae637e9a6c90 100644
--- a/libc/test/src/math/smoke/frexpf_test.cpp
+++ b/libc/test/src/math/smoke/frexpf_test.cpp
@@ -10,4 +10,4 @@
#include "src/math/frexpf.h"
-LIST_FREXP_TESTS(float, LIBC_NAMESPACE::frexpf)
+LIST_FREXP_TESTS(float, LIBC_NAMESPACE::frexpf);
diff --git a/libc/test/src/math/smoke/frexpl_test.cpp b/libc/test/src/math/smoke/frexpl_test.cpp
index e5184cd225bcfa..3e1f8b4204e6ae 100644
--- a/libc/test/src/math/smoke/frexpl_test.cpp
+++ b/libc/test/src/math/smoke/frexpl_test.cpp
@@ -10,4 +10,4 @@
#include "src/math/frexpl.h"
-LIST_FREXP_TESTS(long double, LIBC_NAMESPACE::frexpl)
+LIST_FREXP_TESTS(long double, LIBC_NAMESPACE::frexpl);
More information about the libc-commits
mailing list