[libc-commits] [libc] [libc] Fix constexpr FPUtils rounding_mode.h functions. (PR #152342)
via libc-commits
libc-commits at lists.llvm.org
Wed Aug 6 10:13:00 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: None (lntue)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/152342.diff
1 Files Affected:
- (modified) libc/src/__support/FPUtil/rounding_mode.h (+59-34)
``````````diff
diff --git a/libc/src/__support/FPUtil/rounding_mode.h b/libc/src/__support/FPUtil/rounding_mode.h
index 4ee0a0b0490fc..69b6a63a59c5a 100644
--- a/libc/src/__support/FPUtil/rounding_mode.h
+++ b/libc/src/__support/FPUtil/rounding_mode.h
@@ -17,30 +17,24 @@
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
+namespace generic {
+
// Quick free-standing test whether fegetround() == FE_UPWARD.
// Using the following observation:
// 1.0f + 2^-25 = 1.0f for FE_TONEAREST, FE_DOWNWARD, FE_TOWARDZERO
// = 0x1.000002f for FE_UPWARD.
-LIBC_INLINE static constexpr bool fenv_is_round_up() {
- if (cpp::is_constant_evaluated()) {
- return false;
- } else {
- volatile float x = 0x1.0p-25f;
- return (1.0f + x != 1.0f);
- }
+LIBC_INLINE bool fenv_is_round_up() {
+ volatile float x = 0x1.0p-25f;
+ return (1.0f + x != 1.0f);
}
// Quick free-standing test whether fegetround() == FE_DOWNWARD.
// Using the following observation:
// -1.0f - 2^-25 = -1.0f for FE_TONEAREST, FE_UPWARD, FE_TOWARDZERO
// = -0x1.000002f for FE_DOWNWARD.
-LIBC_INLINE static constexpr bool fenv_is_round_down() {
- if (cpp::is_constant_evaluated()) {
- return false;
- } else {
- volatile float x = 0x1.0p-25f;
- return (-1.0f - x != -1.0f);
- }
+LIBC_INLINE bool fenv_is_round_down() {
+ volatile float x = 0x1.0p-25f;
+ return (-1.0f - x != -1.0f);
}
// Quick free-standing test whether fegetround() == FE_TONEAREST.
@@ -49,14 +43,10 @@ LIBC_INLINE static constexpr bool fenv_is_round_down() {
// = 0x1.100002p0f for FE_UPWARD,
// 1.5f - 2^-24 = 1.5f for FE_TONEAREST, FE_UPWARD
// = 0x1.0ffffep-1f for FE_DOWNWARD, FE_TOWARDZERO
-LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() {
- if (cpp::is_constant_evaluated()) {
- return true;
- } else {
- volatile float x = 0x1.0p-24f;
- float y = 1.5f + x;
- return (y == 1.5f - x);
- }
+LIBC_INLINE bool fenv_is_round_to_nearest() {
+ static volatile float x = 0x1.0p-24f;
+ float y = 1.5f + x;
+ return (y == 1.5f - x);
}
// Quick free-standing test whether fegetround() == FE_TOWARDZERO.
@@ -69,13 +59,56 @@ LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() {
// (0x1.000002p0f + 2^-24) + (-1.0f - 2^-24) = 2^-23 for FE_TOWARDZERO
// = 2^-22 for FE_TONEAREST, FE_UPWARD
// = 0 for FE_DOWNWARD
+LIBC_INLINE bool fenv_is_round_to_zero() {
+ static volatile float x = 0x1.0p-24f;
+ float y = x;
+ return ((0x1.000002p0f + y) + (-1.0f - y) == 0x1.0p-23f);
+}
+
+// Quick free standing get rounding mode based on the above observations.
+LIBC_INLINE int quick_get_round() {
+ static volatile float x = 0x1.0p-24f;
+ float y = x;
+ float z = (0x1.000002p0f + y) + (-1.0f - y);
+
+ if (z == 0.0f)
+ return FE_DOWNWARD;
+ if (z == 0x1.0p-23f)
+ return FE_TOWARDZERO;
+ return (2.0f + y == 2.0f) ? FE_TONEAREST : FE_UPWARD;
+}
+
+} // namespace generic
+
+LIBC_INLINE static constexpr bool fenv_is_round_up() {
+ if (cpp::is_constant_evaluated()) {
+ return false;
+ } else {
+ return generic::fenv_is_round_up();
+ }
+}
+
+LIBC_INLINE static constexpr bool fenv_is_round_down() {
+ if (cpp::is_constant_evaluated()) {
+ return false;
+ } else {
+ return generic::fenv_is_round_down();
+ }
+}
+
+LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() {
+ if (cpp::is_constant_evaluated()) {
+ return true;
+ } else {
+ return generic::fenv_is_round_to_nearest();
+ }
+}
+
LIBC_INLINE static constexpr bool fenv_is_round_to_zero() {
if (cpp::is_constant_evaluated()) {
return false;
} else {
- volatile float x = 0x1.0p-24f;
- volatile float y = 0x1.000002p0f + x;
- return (y + (-1.0f - x) == 0x1.0p-23f);
+ return generic::fenv_is_round_to_zero();
}
}
@@ -84,15 +117,7 @@ LIBC_INLINE static constexpr int quick_get_round() {
if (cpp::is_constant_evaluated()) {
return FE_TONEAREST;
} else {
- volatile float x = 0x1.0p-24f;
- volatile float y = 0x1.000002p0f + x;
- float z = y + (-1.0f - x);
-
- if (z == 0.0f)
- return FE_DOWNWARD;
- if (z == 0x1.0p-23f)
- return FE_TOWARDZERO;
- return (2.0f + x == 2.0f) ? FE_TONEAREST : FE_UPWARD;
+ return generic::quick_get_round();
}
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/152342
More information about the libc-commits
mailing list