stdarch icon indicating copy to clipboard operation
stdarch copied to clipboard

Deprecate MXCSR intrinsics

Open gnzlbg opened this issue 5 years ago • 5 comments

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.

gnzlbg avatar Jul 16 '19 07:07 gnzlbg

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.

unageek avatar Aug 03 '20 16:08 unageek

You can write it to the stack inside the asm! block and then reference the stack from LDMXCSR and STMXCSR.

bjorn3 avatar Aug 03 '20 17:08 bjorn3

@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));
}

unageek avatar Aug 13 '20 12:08 unageek

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.

bjorn3 avatar Aug 13 '20 12:08 bjorn3

@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.

GabrielMajeri avatar Jan 02 '22 14:01 GabrielMajeri