[libc-commits] [libc] [libc][math] Add LIBC_CONF_MATH_USE_SYSTEM_FENV / LIBC_MATH_USE_SYSTEM_FENV (PR #172902)

via libc-commits libc-commits at lists.llvm.org
Mon Dec 22 08:43:59 PST 2025


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

>From 9e124e9a0b92fb8eb994c010866db006492c53fa Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Thu, 18 Dec 2025 20:41:33 +0000
Subject: [PATCH 1/3] [libc][math] Add LIBC_CONF_MATH_USE_SYSTEM_FENV /
 LIBC_MATH_USE_SYSTEM_FENV to allow math function implementations to use
 system libc's fenv.h instead of internal fenv implementations.

---
 .../modules/LLVMLibCCompileOptionRules.cmake  |  8 +++++
 libc/config/config.json                       |  6 +++-
 libc/docs/configure.rst                       |  3 +-
 libc/shared/libc_common.h                     |  5 +++
 libc/src/__support/FPUtil/FEnvImpl.h          | 35 +++++++++++++++++++
 libc/src/fenv/feclearexcept.cpp               |  2 ++
 libc/src/fenv/fedisableexcept.cpp             |  2 ++
 libc/src/fenv/feenableexcept.cpp              |  2 ++
 libc/src/fenv/fegetenv.cpp                    |  2 ++
 libc/src/fenv/fegetexcept.cpp                 |  2 ++
 libc/src/fenv/fegetexceptflag.cpp             |  2 ++
 libc/src/fenv/fegetround.cpp                  |  2 ++
 libc/src/fenv/feholdexcept.cpp                |  2 ++
 libc/src/fenv/feraiseexcept.cpp               |  2 ++
 libc/src/fenv/fesetenv.cpp                    |  2 ++
 libc/src/fenv/fesetexcept.cpp                 |  2 ++
 libc/src/fenv/fesetexceptflag.cpp             |  2 ++
 libc/src/fenv/fesetround.cpp                  |  2 ++
 libc/src/fenv/fetestexcept.cpp                |  2 ++
 libc/src/fenv/fetestexceptflag.cpp            |  2 ++
 libc/src/fenv/feupdateenv.cpp                 |  2 ++
 libc/test/UnitTest/FEnvSafeTest.cpp           |  4 +++
 libc/test/UnitTest/FPExceptMatcher.cpp        |  2 ++
 libc/test/UnitTest/FPMatcher.h                |  2 ++
 libc/test/UnitTest/RoundingModeUtils.cpp      |  2 ++
 .../test/src/fenv/enabled_exceptions_test.cpp |  2 ++
 libc/test/src/fenv/exception_flags_test.cpp   |  2 ++
 libc/test/src/fenv/exception_status_test.cpp  |  2 ++
 libc/test/src/fenv/feclearexcept_test.cpp     |  2 ++
 libc/test/src/fenv/feholdexcept_test.cpp      |  2 ++
 libc/test/src/fenv/feupdateenv_test.cpp       |  2 ++
 libc/test/src/fenv/getenv_and_setenv_test.cpp |  2 ++
 libc/test/src/math/RIntTest.h                 |  2 ++
 libc/test/src/math/RoundToIntegerTest.h       |  2 ++
 libc/test/src/math/smoke/CanonicalizeTest.h   |  2 ++
 libc/test/src/math/smoke/FModTest.h           |  2 ++
 libc/test/src/math/smoke/NearbyIntTest.h      |  2 ++
 libc/test/src/math/smoke/NextAfterTest.h      |  2 ++
 libc/test/src/math/smoke/NextTowardTest.h     |  2 ++
 libc/test/src/math/smoke/RIntTest.h           |  2 ++
 libc/test/src/math/smoke/RoundToIntegerTest.h |  2 ++
 41 files changed, 129 insertions(+), 2 deletions(-)

diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
index 5caf840a4cfeb..57e4381d5f1af 100644
--- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
+++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
@@ -123,6 +123,14 @@ function(_get_compile_options_from_config output_var)
     list(APPEND config_options "-DLIBC_COPT_RAW_MUTEX_DEFAULT_SPIN_COUNT=${LIBC_CONF_RAW_MUTEX_DEFAULT_SPIN_COUNT}")
   endif()
 
+  if(LIBC_CONF_MATH_USE_SYSTEM_FENV)
+    if(MSVC)
+      list(APPEND config_options "/DLIBC_MATH_USE_SYSTEM_FENV")
+    else()
+      list(APPEND config_options "-DLIBC_MATH_USE_SYSTEM_FENV")
+    endif()
+  endif()
+
   set(${output_var} ${config_options} PARENT_SCOPE)
 endfunction(_get_compile_options_from_config)
 
diff --git a/libc/config/config.json b/libc/config/config.json
index 1c11b9a86d8a4..f981c433b2c7c 100644
--- a/libc/config/config.json
+++ b/libc/config/config.json
@@ -105,11 +105,15 @@
   "math": {
     "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."
+      "doc": "Configure 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": "The value written back to the second parameter when calling frexp/frexpf/frexpl` with `+/-Inf`/`NaN` is unspecified.  Configure an explicit exp value for Inf/NaN inputs."
+    },
+    "LIBC_CONF_MATH_USE_SYSTEM_FENV": {
+      "value": false,
+      "doc": "Use C standard fenv.h calls from the system libc instead our internal fenv implementations."
     }
   },
   "qsort": {
diff --git a/libc/docs/configure.rst b/libc/docs/configure.rst
index 7c36222c7fe81..81888bb07153c 100644
--- a/libc/docs/configure.rst
+++ b/libc/docs/configure.rst
@@ -36,7 +36,8 @@ to learn about the defaults for your platform and target.
     - ``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``: The value written back to the second parameter when calling frexp/frexpf/frexpl` with `+/-Inf`/`NaN` is unspecified.  Configure an explicit 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.
+    - ``LIBC_CONF_MATH_OPTIMIZATIONS``: Configure 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_MATH_USE_SYSTEM_FENV``: Use C standard fenv.h calls from the system libc instead our internal fenv implementations.
 * **"printf" options**
     - ``LIBC_CONF_PRINTF_DISABLE_FIXED_POINT``: Disable printing fixed point values in printf and friends.
     - ``LIBC_CONF_PRINTF_DISABLE_FLOAT``: Disable printing floating point values in printf and friends.
diff --git a/libc/shared/libc_common.h b/libc/shared/libc_common.h
index c4560bbb02763..5f7bebdee04b9 100644
--- a/libc/shared/libc_common.h
+++ b/libc/shared/libc_common.h
@@ -19,6 +19,11 @@
 #define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_SYSTEM_INLINE
 #endif // LIBC_ERRNO_MODE
 
+// Use system fenv functions in math implementations.
+#ifndef LIBC_MATH_USE_SYSTEM_FENV
+#define LIBC_MATH_USE_SYSTEM_FENV
+#endif // LIBC_MATH_USE_SYSTEM_FENV
+
 #ifndef LIBC_NAMESPACE
 #define LIBC_NAMESPACE __llvm_libc
 #endif // LIBC_NAMESPACE
diff --git a/libc/src/__support/FPUtil/FEnvImpl.h b/libc/src/__support/FPUtil/FEnvImpl.h
index 3ef2df5f0a352..858397884813e 100644
--- a/libc/src/__support/FPUtil/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/FEnvImpl.h
@@ -20,6 +20,39 @@
 #include "src/__support/macros/properties/architectures.h"
 #include "src/__support/macros/properties/compiler.h"
 
+#if defined(LIBC_MATH_USE_SYSTEM_FENV)
+
+// Simply call the system libc fenv.h functions, only for those that are used in
+// math function implementations.
+// To be used as an option for math function implementation, not to be used to
+// implement fenv.h functions themselves.
+
+#include <fenv.h>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+
+LIBC_INLINE int clear_except(int excepts) { return feclearexcept(excepts); }
+
+LIBC_INLINE int test_except(int excepts) { return fetestexcept(excepts); }
+
+LIBC_INLINE int get_except() { return fegetexcept(); }
+
+LIBC_INLINE int set_except(int excepts) { return fesetexcept(excepts); }
+
+LIBC_INLINE int raise_except(int excepts) { return feraiseexcept(excepts); }
+
+LIBC_INLINE int get_round() { return fegetround(); }
+
+LIBC_INLINE int set_round(int rounding_mode) {
+  return fesetround(rounding_mode);
+}
+
+} // namespace fputil
+} // namespace LIBC_NAMESPACE_DECL
+
+#else // !LIBC_MATH_USE_SYSTEM_FENV
+
 #if defined(LIBC_TARGET_ARCH_IS_AARCH64) && defined(__ARM_FP)
 #if defined(__APPLE__)
 #include "aarch64/fenv_darwin_impl.h"
@@ -73,6 +106,8 @@ LIBC_INLINE int set_env(const fenv_t *) { return 0; }
 } // namespace LIBC_NAMESPACE_DECL
 #endif
 
+#endif // LIBC_MATH_USE_SYSTEM_FENV
+
 namespace LIBC_NAMESPACE_DECL {
 namespace fputil {
 
diff --git a/libc/src/fenv/feclearexcept.cpp b/libc/src/fenv/feclearexcept.cpp
index c8a032fe399b9..7adfa2360565c 100644
--- a/libc/src/fenv/feclearexcept.cpp
+++ b/libc/src/fenv/feclearexcept.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/feclearexcept.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/src/fenv/fedisableexcept.cpp b/libc/src/fenv/fedisableexcept.cpp
index a2a1e97c54a87..9b66a2c204395 100644
--- a/libc/src/fenv/fedisableexcept.cpp
+++ b/libc/src/fenv/fedisableexcept.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/fedisableexcept.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/src/fenv/feenableexcept.cpp b/libc/src/fenv/feenableexcept.cpp
index 468a170919e61..ecd6bcd4faf19 100644
--- a/libc/src/fenv/feenableexcept.cpp
+++ b/libc/src/fenv/feenableexcept.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/feenableexcept.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/src/fenv/fegetenv.cpp b/libc/src/fenv/fegetenv.cpp
index c692b87c219a6..a396aeb542019 100644
--- a/libc/src/fenv/fegetenv.cpp
+++ b/libc/src/fenv/fegetenv.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/fegetenv.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/src/fenv/fegetexcept.cpp b/libc/src/fenv/fegetexcept.cpp
index 2b3de83848b91..5efad397bad66 100644
--- a/libc/src/fenv/fegetexcept.cpp
+++ b/libc/src/fenv/fegetexcept.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/fegetexcept.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/src/fenv/fegetexceptflag.cpp b/libc/src/fenv/fegetexceptflag.cpp
index 58418cc9cc334..4d508eb0aae45 100644
--- a/libc/src/fenv/fegetexceptflag.cpp
+++ b/libc/src/fenv/fegetexceptflag.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/fegetexceptflag.h"
 #include "hdr/types/fexcept_t.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
diff --git a/libc/src/fenv/fegetround.cpp b/libc/src/fenv/fegetround.cpp
index 4f5caedb77a8c..cb2a802379be1 100644
--- a/libc/src/fenv/fegetround.cpp
+++ b/libc/src/fenv/fegetround.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/fegetround.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/src/fenv/feholdexcept.cpp b/libc/src/fenv/feholdexcept.cpp
index 81b3ea435e552..83ac298c69344 100644
--- a/libc/src/fenv/feholdexcept.cpp
+++ b/libc/src/fenv/feholdexcept.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/feholdexcept.h"
 #include "hdr/types/fenv_t.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
diff --git a/libc/src/fenv/feraiseexcept.cpp b/libc/src/fenv/feraiseexcept.cpp
index 6eaa09dd49a62..137945744b0d9 100644
--- a/libc/src/fenv/feraiseexcept.cpp
+++ b/libc/src/fenv/feraiseexcept.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/feraiseexcept.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/src/fenv/fesetenv.cpp b/libc/src/fenv/fesetenv.cpp
index 7a9f90a740ded..6eb051ddc838d 100644
--- a/libc/src/fenv/fesetenv.cpp
+++ b/libc/src/fenv/fesetenv.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/fesetenv.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/src/fenv/fesetexcept.cpp b/libc/src/fenv/fesetexcept.cpp
index 87758211b7fe3..f0df251609793 100644
--- a/libc/src/fenv/fesetexcept.cpp
+++ b/libc/src/fenv/fesetexcept.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/fesetexcept.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/src/fenv/fesetexceptflag.cpp b/libc/src/fenv/fesetexceptflag.cpp
index 9cec9d15d9742..86cbdaa4545ae 100644
--- a/libc/src/fenv/fesetexceptflag.cpp
+++ b/libc/src/fenv/fesetexceptflag.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/fesetexceptflag.h"
 #include "hdr/types/fexcept_t.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
diff --git a/libc/src/fenv/fesetround.cpp b/libc/src/fenv/fesetround.cpp
index 6f65f9fc4adcf..b32af30bcb632 100644
--- a/libc/src/fenv/fesetround.cpp
+++ b/libc/src/fenv/fesetround.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/fesetround.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/src/fenv/fetestexcept.cpp b/libc/src/fenv/fetestexcept.cpp
index f4986acca6eb8..6e7b3eab0d6ae 100644
--- a/libc/src/fenv/fetestexcept.cpp
+++ b/libc/src/fenv/fetestexcept.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/fetestexcept.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/src/fenv/fetestexceptflag.cpp b/libc/src/fenv/fetestexceptflag.cpp
index 03ba1e6f3f3b4..28ba2f774bb43 100644
--- a/libc/src/fenv/fetestexceptflag.cpp
+++ b/libc/src/fenv/fetestexceptflag.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/fetestexceptflag.h"
 #include "hdr/types/fexcept_t.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
diff --git a/libc/src/fenv/feupdateenv.cpp b/libc/src/fenv/feupdateenv.cpp
index 1cc730ca8bed0..cf3c320740ea3 100644
--- a/libc/src/fenv/feupdateenv.cpp
+++ b/libc/src/fenv/feupdateenv.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/feupdateenv.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
diff --git a/libc/test/UnitTest/FEnvSafeTest.cpp b/libc/test/UnitTest/FEnvSafeTest.cpp
index c4694706b7b0e..73cf6a856c776 100644
--- a/libc/test/UnitTest/FEnvSafeTest.cpp
+++ b/libc/test/UnitTest/FEnvSafeTest.cpp
@@ -6,6 +6,10 @@
 //
 //===---------------------------------------------------------------------===//
 
+#ifdef LIBC_MATH_USE_SYSTEM_FENV
+#undef LIBC_MATH_USE_SYSTEM_FENV
+#endif // LIBC_MATH_USE_SYSTEM_FENV
+
 #include "FEnvSafeTest.h"
 
 #include "src/__support/FPUtil/FEnvImpl.h"
diff --git a/libc/test/UnitTest/FPExceptMatcher.cpp b/libc/test/UnitTest/FPExceptMatcher.cpp
index 9688d53496f94..3f5329bbdc53f 100644
--- a/libc/test/UnitTest/FPExceptMatcher.cpp
+++ b/libc/test/UnitTest/FPExceptMatcher.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "FPExceptMatcher.h"
 
 #include "src/__support/macros/config.h"
diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index 430727e537107..bc6ac367877e5 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_TEST_UNITTEST_FPMATCHER_H
 #define LLVM_LIBC_TEST_UNITTEST_FPMATCHER_H
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/__support/CPP/array.h"
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
diff --git a/libc/test/UnitTest/RoundingModeUtils.cpp b/libc/test/UnitTest/RoundingModeUtils.cpp
index 46ac204bcd759..15b8a36f83fff 100644
--- a/libc/test/UnitTest/RoundingModeUtils.cpp
+++ b/libc/test/UnitTest/RoundingModeUtils.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "RoundingModeUtils.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/rounding_mode.h"
diff --git a/libc/test/src/fenv/enabled_exceptions_test.cpp b/libc/test/src/fenv/enabled_exceptions_test.cpp
index b5e6562a03eee..a742c240a120b 100644
--- a/libc/test/src/fenv/enabled_exceptions_test.cpp
+++ b/libc/test/src/fenv/enabled_exceptions_test.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/feclearexcept.h"
 #include "src/fenv/feraiseexcept.h"
 #include "src/fenv/fetestexcept.h"
diff --git a/libc/test/src/fenv/exception_flags_test.cpp b/libc/test/src/fenv/exception_flags_test.cpp
index 2f4332df861fe..6fbb1a45bc54b 100644
--- a/libc/test/src/fenv/exception_flags_test.cpp
+++ b/libc/test/src/fenv/exception_flags_test.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "hdr/types/fexcept_t.h"
 #include "src/fenv/fegetexceptflag.h"
 #include "src/fenv/fesetexceptflag.h"
diff --git a/libc/test/src/fenv/exception_status_test.cpp b/libc/test/src/fenv/exception_status_test.cpp
index fdf9421457866..49461bc4908a3 100644
--- a/libc/test/src/fenv/exception_status_test.cpp
+++ b/libc/test/src/fenv/exception_status_test.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/feclearexcept.h"
 #include "src/fenv/feraiseexcept.h"
 #include "src/fenv/fesetexcept.h"
diff --git a/libc/test/src/fenv/feclearexcept_test.cpp b/libc/test/src/fenv/feclearexcept_test.cpp
index f39cf4eca05c9..17da105b9b1d4 100644
--- a/libc/test/src/fenv/feclearexcept_test.cpp
+++ b/libc/test/src/fenv/feclearexcept_test.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/fenv/feclearexcept.h"
 
 #include "src/__support/FPUtil/FEnvImpl.h"
diff --git a/libc/test/src/fenv/feholdexcept_test.cpp b/libc/test/src/fenv/feholdexcept_test.cpp
index 1112ec93ee964..0e601d8db3020 100644
--- a/libc/test/src/fenv/feholdexcept_test.cpp
+++ b/libc/test/src/fenv/feholdexcept_test.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "hdr/types/fenv_t.h"
 #include "src/fenv/feholdexcept.h"
 
diff --git a/libc/test/src/fenv/feupdateenv_test.cpp b/libc/test/src/fenv/feupdateenv_test.cpp
index d2ffc0ef8e84d..f50b25e0233e3 100644
--- a/libc/test/src/fenv/feupdateenv_test.cpp
+++ b/libc/test/src/fenv/feupdateenv_test.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "hdr/types/fenv_t.h"
 #include "src/fenv/feupdateenv.h"
 
diff --git a/libc/test/src/fenv/getenv_and_setenv_test.cpp b/libc/test/src/fenv/getenv_and_setenv_test.cpp
index 63929ee984b49..f51c59951ec5a 100644
--- a/libc/test/src/fenv/getenv_and_setenv_test.cpp
+++ b/libc/test/src/fenv/getenv_and_setenv_test.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "hdr/types/fenv_t.h"
 #include "src/fenv/fegetenv.h"
 #include "src/fenv/fegetround.h"
diff --git a/libc/test/src/math/RIntTest.h b/libc/test/src/math/RIntTest.h
index c9d8ebcbc9e23..86e73bb5b0548 100644
--- a/libc/test/src/math/RIntTest.h
+++ b/libc/test/src/math/RIntTest.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_TEST_SRC_MATH_RINTTEST_H
 #define LLVM_LIBC_TEST_SRC_MATH_RINTTEST_H
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/__support/CPP/algorithm.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h
index e5e93869a3235..469db111302c2 100644
--- a/libc/test/src/math/RoundToIntegerTest.h
+++ b/libc/test/src/math/RoundToIntegerTest.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H
 #define LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/__support/CPP/algorithm.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
diff --git a/libc/test/src/math/smoke/CanonicalizeTest.h b/libc/test/src/math/smoke/CanonicalizeTest.h
index e500bc38f9852..524a79acc72bd 100644
--- a/libc/test/src/math/smoke/CanonicalizeTest.h
+++ b/libc/test/src/math/smoke/CanonicalizeTest.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/integer_literals.h"
diff --git a/libc/test/src/math/smoke/FModTest.h b/libc/test/src/math/smoke/FModTest.h
index 838c917a3fd55..ab336cd240580 100644
--- a/libc/test/src/math/smoke/FModTest.h
+++ b/libc/test/src/math/smoke/FModTest.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H
 #define LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "hdr/errno_macros.h"
 #include "hdr/fenv_macros.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
diff --git a/libc/test/src/math/smoke/NearbyIntTest.h b/libc/test/src/math/smoke/NearbyIntTest.h
index 092700e2eef03..aa6c6bfbf52da 100644
--- a/libc/test/src/math/smoke/NearbyIntTest.h
+++ b/libc/test/src/math/smoke/NearbyIntTest.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_TEST_SRC_MATH_NEARBYINTTEST_H
 #define LLVM_LIBC_TEST_SRC_MATH_NEARBYINTTEST_H
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "hdr/fenv_macros.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
diff --git a/libc/test/src/math/smoke/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h
index b7e59f7cd8cfd..2d3e6a03d34cb 100644
--- a/libc/test/src/math/smoke/NextAfterTest.h
+++ b/libc/test/src/math/smoke/NextAfterTest.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
 #define LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/__support/CPP/bit.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
diff --git a/libc/test/src/math/smoke/NextTowardTest.h b/libc/test/src/math/smoke/NextTowardTest.h
index 43e71c6a2d8f6..377f458faeee0 100644
--- a/libc/test/src/math/smoke/NextTowardTest.h
+++ b/libc/test/src/math/smoke/NextTowardTest.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_TEST_SRC_MATH_NEXTTOWARDTEST_H
 #define LLVM_LIBC_TEST_SRC_MATH_NEXTTOWARDTEST_H
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/__support/CPP/bit.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
diff --git a/libc/test/src/math/smoke/RIntTest.h b/libc/test/src/math/smoke/RIntTest.h
index 7f14aeb674d68..d4cfc1b40445b 100644
--- a/libc/test/src/math/smoke/RIntTest.h
+++ b/libc/test/src/math/smoke/RIntTest.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_RINTTEST_H
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_RINTTEST_H
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "test/UnitTest/FEnvSafeTest.h"
diff --git a/libc/test/src/math/smoke/RoundToIntegerTest.h b/libc/test/src/math/smoke/RoundToIntegerTest.h
index c0b326e5dcbb0..70fc361c2e244 100644
--- a/libc/test/src/math/smoke/RoundToIntegerTest.h
+++ b/libc/test/src/math/smoke/RoundToIntegerTest.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDTOINTEGERTEST_H
 #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ROUNDTOINTEGERTEST_H
 
+#undef LIBC_MATH_USE_SYSTEM_FENV
+
 #include "src/__support/CPP/algorithm.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"

>From 358baf02668d8695f6c91107be247994d9eb3e87 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Mon, 22 Dec 2025 16:13:41 +0000
Subject: [PATCH 2/3] Use standard C functions fe(get/set)exceptflag instead.

---
 libc/src/__support/FPUtil/FEnvImpl.h | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/libc/src/__support/FPUtil/FEnvImpl.h b/libc/src/__support/FPUtil/FEnvImpl.h
index 858397884813e..feb9f56bb4ad7 100644
--- a/libc/src/__support/FPUtil/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/FEnvImpl.h
@@ -20,6 +20,11 @@
 #include "src/__support/macros/properties/architectures.h"
 #include "src/__support/macros/properties/compiler.h"
 
+// In full build mode we are the system fenv in libc.
+#if defined(LIBC_FULL_BUILD)
+#undef LIBC_MATH_USE_SYSTEM_FENV
+#endif // LIBC_FULL_BUILD
+
 #if defined(LIBC_MATH_USE_SYSTEM_FENV)
 
 // Simply call the system libc fenv.h functions, only for those that are used in
@@ -36,9 +41,16 @@ LIBC_INLINE int clear_except(int excepts) { return feclearexcept(excepts); }
 
 LIBC_INLINE int test_except(int excepts) { return fetestexcept(excepts); }
 
-LIBC_INLINE int get_except() { return fegetexcept(); }
+LIBC_INLINE int get_except() {
+  fexcept_t excepts = 0;
+  fegetexceptflag(&excepts, FE_ALL_EXCEPT);
+  return static_cast<int>(excepts);
+}
 
-LIBC_INLINE int set_except(int excepts) { return fesetexcept(excepts); }
+LIBC_INLINE int set_except(int excepts) {
+  fexcept_t exc = static_cast<fexcept_t>(excepts);
+  return fesetexceptflag(&excepts, FE_ALL_EXCEPT);
+}
 
 LIBC_INLINE int raise_except(int excepts) { return feraiseexcept(excepts); }
 

>From 80650c6f0dcd92b3ca239787b739d16e73f027c6 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Mon, 22 Dec 2025 16:43:33 +0000
Subject: [PATCH 3/3] Fix fesetexceptflag call.

---
 libc/src/__support/FPUtil/FEnvImpl.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/__support/FPUtil/FEnvImpl.h b/libc/src/__support/FPUtil/FEnvImpl.h
index feb9f56bb4ad7..a21f511bd72b8 100644
--- a/libc/src/__support/FPUtil/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/FEnvImpl.h
@@ -49,7 +49,7 @@ LIBC_INLINE int get_except() {
 
 LIBC_INLINE int set_except(int excepts) {
   fexcept_t exc = static_cast<fexcept_t>(excepts);
-  return fesetexceptflag(&excepts, FE_ALL_EXCEPT);
+  return fesetexceptflag(&exc, FE_ALL_EXCEPT);
 }
 
 LIBC_INLINE int raise_except(int excepts) { return feraiseexcept(excepts); }



More information about the libc-commits mailing list