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

Deprecate MXCSR intrinsics #781

Open
gnzlbg opened this issue Jul 16, 2019 · 5 comments
Open

Deprecate MXCSR intrinsics #781

gnzlbg opened this issue Jul 16, 2019 · 5 comments

Comments

@gnzlbg
Copy link
Contributor

gnzlbg commented Jul 16, 2019

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.

@unageek
Copy link

unageek commented Aug 3, 2020

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.

@bjorn3
Copy link
Member

bjorn3 commented Aug 3, 2020

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

@unageek
Copy link

unageek commented Aug 13, 2020

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

@bjorn3
Copy link
Member

bjorn3 commented Aug 13, 2020

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.

@GabrielMajeri
Copy link
Contributor

GabrielMajeri commented Jan 2, 2022

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants