[libc-commits] [libc] [libc] Skip x87 floating point register and only update mxcsr for x86_64 targets when raising exceptions inside math functions. (PR #144951)
via libc-commits
libc-commits at lists.llvm.org
Thu Jun 19 13:30:38 PDT 2025
https://github.com/lntue created https://github.com/llvm/llvm-project/pull/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.
>From b2ebbde9c794adb9503ed6149fc0746abdcdaa23 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Thu, 19 Jun 2025 20:24:04 +0000
Subject: [PATCH] [libc] Skip x87 floating point register and only update mxcsr
for x86_64 targets when raising exceptions inside math functions.
---
libc/src/__support/FPUtil/FEnvImpl.h | 5 +++++
libc/src/__support/FPUtil/x86_64/FEnvImpl.h | 13 ++++++++-----
2 files changed, 13 insertions(+), 5 deletions(-)
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