Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefined Behavior: Changing MXCSR to _MM_ROUND_TOWARD_ZERO on x86 and x86_64. #776

Open
herabit opened this issue Dec 18, 2024 · 4 comments
Labels
C-Bug Something isn't working P-Critical

Comments

@herabit
Copy link

herabit commented Dec 18, 2024

In Rust, modifying the rounding mode in x86 and x86_64 by modifying the MXCSR register (through _mm_setcsr or inline assembly) is considered immediate undefined behavior.

See here for more info.

@Vrixyz Vrixyz added C-Bug Something isn't working P-Critical labels Dec 19, 2024
@Vrixyz
Copy link
Contributor

Vrixyz commented Dec 20, 2024

Thanks for the issue ; I admit I'm not sure how to research "using inline assembly instead".

@Lokathor
Copy link

The key element of using inline assembly is that you can't ever leave an inline assembly block without restoring MXCSR to the default state, or you hit the same UB problem.

You'd have to do the entire round-toward-zero operation using only inline assembly.

@Vrixyz
Copy link
Contributor

Vrixyz commented Jan 6, 2025

A bit more context: this operation occurs when using enable_flush_to_zero, for example:

enable_flush_to_zero!();

This "flush to zero" leads to important performance improvements.

Brainstorming further:

Could the entire round-toward-zero operation can be summarized as a function call, so the assembly would end up quite small (function declaration, arguments prep, function call) ?

@Lokathor
Copy link

Lokathor commented Jan 6, 2025

You cannot leave flush to zero active while executing rust code, it's simply not allowed.

So you can't have functions to toggle the effect on/off, and you also can't have a function that takes a fn pointer to run with flushing set which changes the state and calls back into rust while the state is changed.

This applies equally to all floating point environment settings, though flush to zero is usually the only one people try to change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-Bug Something isn't working P-Critical
Projects
None yet
Development

No branches or pull requests

3 participants