[libc-commits] [libc] [libc] Make FPUtils' rounding_mode.h functions constexpr. (PR #149167)

via libc-commits libc-commits at lists.llvm.org
Mon Jul 21 06:19:14 PDT 2025


https://github.com/lntue updated https://github.com/llvm/llvm-project/pull/149167

>From 7456a1c8e4b37592f64a4a4e6fecbc80ea2b9e6b Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Wed, 16 Jul 2025 18:47:13 +0000
Subject: [PATCH] [libc] Make FPUtils' rounding_mode.h functions constexpr.

---
 libc/src/__support/FPUtil/CMakeLists.txt  |  1 +
 libc/src/__support/FPUtil/rounding_mode.h | 67 +++++++++++++++--------
 2 files changed, 45 insertions(+), 23 deletions(-)

diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index cc941f23135a6..764cb33a83c0e 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -16,6 +16,7 @@ add_header_library(
     rounding_mode.h
   DEPENDS
     libc.hdr.fenv_macros
+    libc.src.__support.CPP.type_traits
     libc.src.__support.macros.attributes
     libc.src.__support.macros.properties.architectures
     libc.src.__support.macros.sanitizer
diff --git a/libc/src/__support/FPUtil/rounding_mode.h b/libc/src/__support/FPUtil/rounding_mode.h
index bc66d09b94160..4ee0a0b0490fc 100644
--- a/libc/src/__support/FPUtil/rounding_mode.h
+++ b/libc/src/__support/FPUtil/rounding_mode.h
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_ROUNDING_MODE_H
 
 #include "hdr/fenv_macros.h"
+#include "src/__support/CPP/type_traits.h"   // is_constant_evaluated
 #include "src/__support/macros/attributes.h" // LIBC_INLINE
 #include "src/__support/macros/config.h"
 
@@ -20,18 +21,26 @@ namespace fputil {
 // Using the following observation:
 //   1.0f + 2^-25 = 1.0f        for FE_TONEAREST, FE_DOWNWARD, FE_TOWARDZERO
 //                = 0x1.000002f for FE_UPWARD.
-LIBC_INLINE bool fenv_is_round_up() {
-  volatile float x = 0x1.0p-25f;
-  return (1.0f + x != 1.0f);
+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);
+  }
 }
 
 // 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 bool fenv_is_round_down() {
-  volatile float x = 0x1.0p-25f;
-  return (-1.0f - x != -1.0f);
+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);
+  }
 }
 
 // Quick free-standing test whether fegetround() == FE_TONEAREST.
@@ -40,10 +49,14 @@ LIBC_INLINE 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 bool fenv_is_round_to_nearest() {
-  static volatile float x = 0x1.0p-24f;
-  float y = x;
-  return (1.5f + y == 1.5f - y);
+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);
+  }
 }
 
 // Quick free-standing test whether fegetround() == FE_TOWARDZERO.
@@ -56,23 +69,31 @@ LIBC_INLINE 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);
+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);
+  }
 }
 
 // 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);
+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 + y == 2.0f) ? FE_TONEAREST : FE_UPWARD;
+    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;
+  }
 }
 
 } // namespace fputil



More information about the libc-commits mailing list