[libc-commits] [libc] 2f3a8fd - [libc] Skip x87 floating point register and only update mxcsr for x86_64 targets when raising exceptions inside math functions. (#144951)

via libc-commits libc-commits at lists.llvm.org
Thu Jun 19 14:06:55 PDT 2025


Author: lntue
Date: 2025-06-19T17:06:52-04:00
New Revision: 2f3a8fd0b3322baac25e5595313413ed4cd1158f

URL: https://github.com/llvm/llvm-project/commit/2f3a8fd0b3322baac25e5595313413ed4cd1158f
DIFF: https://github.com/llvm/llvm-project/commit/2f3a8fd0b3322baac25e5595313413ed4cd1158f.diff

LOG: [libc] Skip x87 floating point register and only update mxcsr for x86_64 targets when raising exceptions inside math functions. (#144951)

Updating x87 floating point register significantly affect the
performance of the functions.
All the floating point exception reads will merge the results from both
mxcsr and x87 registers anyway.

Added: 
    

Modified: 
    libc/src/__support/FPUtil/FEnvImpl.h
    libc/src/__support/FPUtil/x86_64/FEnvImpl.h

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/FPUtil/FEnvImpl.h b/libc/src/__support/FPUtil/FEnvImpl.h
index ba145a3da45cc..76910880eb810 100644
--- a/libc/src/__support/FPUtil/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/FEnvImpl.h
@@ -91,7 +91,12 @@ LIBC_INLINE static int set_except_if_required([[maybe_unused]] int excepts) {
 LIBC_INLINE static int raise_except_if_required([[maybe_unused]] int excepts) {
 #ifndef LIBC_MATH_HAS_NO_EXCEPT
   if (math_errhandling & MATH_ERREXCEPT)
+#ifdef LIBC_TARGET_ARCH_IS_X86_64
+    return raise_except</*SKIP_X87_FPU*/ true>(excepts);
+#else  // !LIBC_TARGET_ARCH_IS_X86
     return raise_except(excepts);
+#endif // LIBC_TARGET_ARCH_IS_X86
+
 #endif // LIBC_MATH_HAS_NO_EXCEPT
   return 0;
 }

diff  --git a/libc/src/__support/FPUtil/x86_64/FEnvImpl.h b/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
index b77178ea69ea0..560727c22978e 100644
--- a/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
@@ -239,7 +239,7 @@ LIBC_INLINE int set_except(int excepts) {
   return 0;
 }
 
-LIBC_INLINE int raise_except(int excepts) {
+template <bool SKIP_X87_FPU = false> LIBC_INLINE int raise_except(int excepts) {
   uint16_t status_value = internal::get_status_value_for_except(excepts);
 
   // We set the status flag for exception one at a time and call the
@@ -256,13 +256,16 @@ LIBC_INLINE int raise_except(int excepts) {
   // when raising the next exception.
 
   auto raise_helper = [](uint16_t singleExceptFlag) {
-    internal::X87StateDescriptor state;
+    if constexpr (!SKIP_X87_FPU) {
+      internal::X87StateDescriptor state;
+      internal::get_x87_state_descriptor(state);
+      state.status_word |= singleExceptFlag;
+      internal::write_x87_state_descriptor(state);
+    }
+
     uint32_t mxcsr = 0;
-    internal::get_x87_state_descriptor(state);
     mxcsr = internal::get_mxcsr();
-    state.status_word |= singleExceptFlag;
     mxcsr |= singleExceptFlag;
-    internal::write_x87_state_descriptor(state);
     internal::write_mxcsr(mxcsr);
     internal::fwait();
   };


        


More information about the libc-commits mailing list