[libc-commits] [libc] [libc][math] Add option to set a specific exponent for frexp with Inf/NaN inputs. (PR #112387)
via libc-commits
libc-commits at lists.llvm.org
Thu Oct 17 21:55:05 PDT 2024
https://github.com/lntue updated https://github.com/llvm/llvm-project/pull/112387
>From 8230e3a9155328b0b1f08303e8b0cf122ef2a50f Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Tue, 15 Oct 2024 16:10:27 +0000
Subject: [PATCH 1/2] [libc][math] Add option to set a specific exponent for
frexp(Inf/NaN, exp).
---
libc/cmake/modules/LLVMLibCCompileOptionRules.cmake | 11 ++++++++---
libc/config/config.json | 4 ++++
libc/docs/configure.rst | 1 +
libc/src/__support/FPUtil/ManipulationFunctions.h | 6 +++++-
libc/test/src/math/smoke/FrexpTest.h | 11 +++++++++++
5 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
index 737ac87f4c7a21..0c658c6866c437 100644
--- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
+++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
@@ -79,6 +79,14 @@ function(_get_compile_options_from_config output_var)
list(APPEND config_options "-DLIBC_ADD_NULL_CHECKS")
endif()
+ if(NOT "${LIBC_CONF_FREXP_INF_NAN_EXPONENT}" STREQUAL "")
+ list(APPEND config_options "-DLIBC_FREXP_INF_NAN_EXPONENT=${LIBC_CONF_FREXP_INF_NAN_EXPONENT}")
+ endif()
+
+ if(LIBC_CONF_MATH_OPTIMIZATIONS)
+ list(APPEND compile_options "-DLIBC_MATH=${LIBC_CONF_MATH_OPTIMIZATIONS}")
+ endif()
+
set(${output_var} ${config_options} PARENT_SCOPE)
endfunction(_get_compile_options_from_config)
@@ -170,9 +178,6 @@ function(_get_common_compile_options output_var flags)
list(APPEND compile_options "-Wthread-safety")
list(APPEND compile_options "-Wglobal-constructors")
endif()
- if(LIBC_CONF_MATH_OPTIMIZATIONS)
- list(APPEND compile_options "-DLIBC_MATH=${LIBC_CONF_MATH_OPTIMIZATIONS}")
- endif()
elseif(MSVC)
list(APPEND compile_options "/EHs-c-")
list(APPEND compile_options "/GR-")
diff --git a/libc/config/config.json b/libc/config/config.json
index 2e4f878778e6e0..77d9a8d248e191 100644
--- a/libc/config/config.json
+++ b/libc/config/config.json
@@ -87,6 +87,10 @@
"LIBC_CONF_MATH_OPTIMIZATIONS": {
"value": 0,
"doc": "Configures optimizations for math functions. Values accepted are LIBC_MATH_SKIP_ACCURATE_PASS, LIBC_MATH_SMALL_TABLES, LIBC_MATH_NO_ERRNO, LIBC_MATH_NO_EXCEPT, and LIBC_MATH_FAST."
+ },
+ "LIBC_CONF_FREXP_INF_NAN_EXPONENT": {
+ "value": "",
+ "doc": "Set the specific exp value for Inf/NaN inputs."
}
},
"qsort": {
diff --git a/libc/docs/configure.rst b/libc/docs/configure.rst
index 867bb807d10ac9..e225e6b566dfb2 100644
--- a/libc/docs/configure.rst
+++ b/libc/docs/configure.rst
@@ -33,6 +33,7 @@ to learn about the defaults for your platform and target.
* **"general" options**
- ``LIBC_ADD_NULL_CHECKS``: Add nullptr checks in the library's implementations to some functions for which passing nullptr is undefined behavior.
* **"math" options**
+ - ``LIBC_CONF_FREXP_INF_NAN_EXPONENT``: Set the specific exp value for Inf/NaN inputs.
- ``LIBC_CONF_MATH_OPTIMIZATIONS``: Configures optimizations for math functions. Values accepted are LIBC_MATH_SKIP_ACCURATE_PASS, LIBC_MATH_SMALL_TABLES, LIBC_MATH_NO_ERRNO, LIBC_MATH_NO_EXCEPT, and LIBC_MATH_FAST.
* **"printf" options**
- ``LIBC_CONF_PRINTF_DISABLE_FIXED_POINT``: Disable printing fixed point values in printf and friends.
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index 66bfe2aa377f99..c3853e93026ad3 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -31,8 +31,12 @@ namespace fputil {
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T frexp(T x, int &exp) {
FPBits<T> bits(x);
- if (bits.is_inf_or_nan())
+ if (bits.is_inf_or_nan()) {
+#ifdef LIBC_FREXP_INF_NAN_EXPONENT
+ exp = LIBC_FREXP_INF_NAN_EXPONENT;
+#endif // LIBC_FREXP_INF_NAN_EXPONENT
return x;
+ }
if (bits.is_zero()) {
exp = 0;
return x;
diff --git a/libc/test/src/math/smoke/FrexpTest.h b/libc/test/src/math/smoke/FrexpTest.h
index 11641fc6743c44..3fb3a2e1688c81 100644
--- a/libc/test/src/math/smoke/FrexpTest.h
+++ b/libc/test/src/math/smoke/FrexpTest.h
@@ -21,8 +21,19 @@ class FrexpTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
void testSpecialNumbers(FrexpFunc func) {
int exponent;
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(aNaN, &exponent));
+#ifdef LIBC_FREXP_INF_NAN_EXPONENT
+ EXPECT_EQ(LIBC_FREXP_INF_NAN_EXPONENT, exponent);
+#endif // LIBC_FREXP_INF_NAN_EXPONENT
+
EXPECT_FP_EQ_ALL_ROUNDING(inf, func(inf, &exponent));
+#ifdef LIBC_FREXP_INF_NAN_EXPONENT
+ EXPECT_EQ(LIBC_FREXP_INF_NAN_EXPONENT, exponent);
+#endif // LIBC_FREXP_INF_NAN_EXPONENT
+
EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, func(neg_inf, &exponent));
+#ifdef LIBC_FREXP_INF_NAN_EXPONENT
+ EXPECT_EQ(LIBC_FREXP_INF_NAN_EXPONENT, exponent);
+#endif // LIBC_FREXP_INF_NAN_EXPONENT
EXPECT_FP_EQ_ALL_ROUNDING(zero, func(zero, &exponent));
EXPECT_EQ(exponent, 0);
>From 296cf82f2bdb368ad0a5f37da3ef7dbfc759f40d Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Fri, 18 Oct 2024 04:54:44 +0000
Subject: [PATCH 2/2] Update comments.
---
libc/config/config.json | 2 +-
libc/src/__support/FPUtil/ManipulationFunctions.h | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/libc/config/config.json b/libc/config/config.json
index 77d9a8d248e191..9a5d5c3c68da60 100644
--- a/libc/config/config.json
+++ b/libc/config/config.json
@@ -90,7 +90,7 @@
},
"LIBC_CONF_FREXP_INF_NAN_EXPONENT": {
"value": "",
- "doc": "Set the specific exp value for Inf/NaN inputs."
+ "doc": "The value written back to the second parameter when calling frexp/frexpf/frexpl` with `+/-Inf`/`NaN` is unspecified. Configue an explicit exp value for Inf/NaN inputs."
}
},
"qsort": {
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index c3853e93026ad3..9c10011ccd2039 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -33,6 +33,10 @@ LIBC_INLINE T frexp(T x, int &exp) {
FPBits<T> bits(x);
if (bits.is_inf_or_nan()) {
#ifdef LIBC_FREXP_INF_NAN_EXPONENT
+ // The value written back to the second parameter when calling
+ // frexp/frexpf/frexpl` with `+/-Inf`/`NaN` is unspecified in the standard.
+ // Set the exp value for Inf/NaN inputs explicitly to
+ // LIBC_FREXP_INF_NAN_EXPONENT if it is defined.
exp = LIBC_FREXP_INF_NAN_EXPONENT;
#endif // LIBC_FREXP_INF_NAN_EXPONENT
return x;
More information about the libc-commits
mailing list