Skip to content

Commit 2f3a8fd

Browse files
authored
[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.
1 parent 53336ad commit 2f3a8fd

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

libc/src/__support/FPUtil/FEnvImpl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,12 @@ LIBC_INLINE static int set_except_if_required([[maybe_unused]] int excepts) {
9191
LIBC_INLINE static int raise_except_if_required([[maybe_unused]] int excepts) {
9292
#ifndef LIBC_MATH_HAS_NO_EXCEPT
9393
if (math_errhandling & MATH_ERREXCEPT)
94+
#ifdef LIBC_TARGET_ARCH_IS_X86_64
95+
return raise_except</*SKIP_X87_FPU*/ true>(excepts);
96+
#else // !LIBC_TARGET_ARCH_IS_X86
9497
return raise_except(excepts);
98+
#endif // LIBC_TARGET_ARCH_IS_X86
99+
95100
#endif // LIBC_MATH_HAS_NO_EXCEPT
96101
return 0;
97102
}

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ LIBC_INLINE int set_except(int excepts) {
239239
return 0;
240240
}
241241

242-
LIBC_INLINE int raise_except(int excepts) {
242+
template <bool SKIP_X87_FPU = false> LIBC_INLINE int raise_except(int excepts) {
243243
uint16_t status_value = internal::get_status_value_for_except(excepts);
244244

245245
// 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) {
256256
// when raising the next exception.
257257

258258
auto raise_helper = [](uint16_t singleExceptFlag) {
259-
internal::X87StateDescriptor state;
259+
if constexpr (!SKIP_X87_FPU) {
260+
internal::X87StateDescriptor state;
261+
internal::get_x87_state_descriptor(state);
262+
state.status_word |= singleExceptFlag;
263+
internal::write_x87_state_descriptor(state);
264+
}
265+
260266
uint32_t mxcsr = 0;
261-
internal::get_x87_state_descriptor(state);
262267
mxcsr = internal::get_mxcsr();
263-
state.status_word |= singleExceptFlag;
264268
mxcsr |= singleExceptFlag;
265-
internal::write_x87_state_descriptor(state);
266269
internal::write_mxcsr(mxcsr);
267270
internal::fwait();
268271
};

0 commit comments

Comments
 (0)