stdarch
stdarch copied to clipboard
Deprecate MXCSR intrinsics
Modifying MXCSR is insta-UB in LLVM, and inspecting it is kind of pointless since LLVM can change it behind your back however it wants (e.g. depending on the opt-level).
We should deprecate these and tell people not to use them, since they won't do what they want them to do.
Users that want to mess with MXCSR, should do so in such a way that doesn't trigger UB in LLVM. For example, by opening a single inline asm!
block, where they save the register, modify it, execute some code, and then restore it, before leaving the inline assembly block.
cc @rkruppe - thanks for suggesting this.
opening a single inline asm! block, where they save the register, modify it, execute some code, and then restore it, before leaving the inline assembly block.
Is that possible with the new asm!
syntax? LDMXCSR
/STMXCSR
takes a memory operand only, but writing such an instruction is not supported by the macro yet.
You can write it to the stack inside the asm!
block and then reference the stack from LDMXCSR
and STMXCSR
.
@bjorn3 Thank you very much!
Is it safe or not to specify preserves_flags
in the options
?
#![feature(asm)]
/// Returns x * y rounded down.
fn mul_rd(mut x: f64, y: f64) -> f64 {
unsafe {
asm!(
"sub rsp, 8",
"stmxcsr [rsp]",
"mov dword ptr [rsp + 4], 16256", // _MM_ROUND_DOWN | _MM_MASK_MASK
"ldmxcsr [rsp + 4]",
"mulpd {x}, {y}",
"ldmxcsr [rsp]",
"add rsp, 8",
x = inout(xmm_reg) x,
y = in(xmm_reg) y,
options(pure, nomem)
);
}
x
}
fn main() {
assert_ne!(-mul_rd(-1.1, 10.1), mul_rd(1.1, 10.1));
}
Not safe.
https://www.felixcloutier.com/x86/add
The OF, SF, ZF, AF, CF, and PF flags are set according to the result.
The add
instruction can change several flags.
@Amanieu pointed out that since https://reviews.llvm.org/D68121 got merged, LLVM should now have some support for accessing the MXCSR registers (without causing UB). We should reconsider whether it's a good idea to deprecate the corresponding intrinsics.