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

Diagnostic: no EMMS instruction before call #57831

Closed
gnzlbg opened this issue Jan 22, 2019 · 4 comments
Closed

Diagnostic: no EMMS instruction before call #57831

gnzlbg opened this issue Jan 22, 2019 · 4 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-SIMD Area: SIMD (Single Instruction Multiple Data) C-enhancement Category: An issue proposing an enhancement or a PR with one. O-x86_32 Target: x86 processors, 32 bit (like i686-*) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@gnzlbg
Copy link
Contributor

gnzlbg commented Jan 22, 2019

The Intel compiler has an extremely useful warning (https://software.intel.com/en-us/articles/cdiag964) that triggers if MMX code interfaces with x87 code without an EMMS instruction before the x87 code.

Example (playground):

pub fn init(_x: i32);
fn main() {
    unsafe {
        let m0 = _mm_cvtsi32_si64(1);
        let m1 = _mm_cvtsi32_si64(2);
        let mut m2 = _mm_cvtsi32_si64(4);

        m2 = _mm_add_pi8(m0, m1);
        let value = _mm_cvtsi64_si32(m2);

        // Without a call to _mm_empty()
        // this program has UB
        //_mm_empty();
        init(value);
    }
}

Without the call to _mm_empty no emms instruction is emitted, and the program has undefined behavior.

It would be nice if rustc could emit the following error message:

init(value);
^^^^^^^^^^ error: no EMMS instruction before call

note: Use the EMMS instruction (e.g.  by calling the _mm_empty() intrinsic ) 
after the MMX instructions immediately before the x87 code to restore 
the Floating-point status on the CPU.

There are a couple of common ways to emit an EMMS instruction:

  • using {core, std}::arch::{x86, x86_64}::{_mm_empty(), _m_empty()}
  • using asm!("emms" : : : "volatile");

The diagnostic should not be emitted if an EMMS instruction is emitted right before a call to an x87 function.


Note, LLVM, by design, does not emit EMMS instructions when they are needed (https://bugs.llvm.org/show_bug.cgi?id=1838). Instead, the user generating LLVM-IR is responsible of doing so manually when necessary.

@Centril Centril added the A-diagnostics Area: Messages for errors, warnings, and lints label Jan 22, 2019
@the8472
Copy link
Member

the8472 commented Feb 2, 2019

GCC just implemented rewiring the MMX intrinsics to 8byte SSE2 equivalents. Maybe rust could do the same to avoid this pitfall.

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Feb 4, 2019

@the8472 would you mind opening a separate issue to discuss that? This wouldn't help anybody trying to actually use the MMX registers.

Implementing the rewiring should be trivial though. We could have a -Z flag to toggle it, and rustc would just need to use normal vector types instead of x86_mmx. LLVM already does the rest (MMX registers are only actually used if the LLVM IR explicitly uses the x86_mmx type).

@crlf0710 crlf0710 added C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 11, 2020
@jonas-schievink jonas-schievink added A-SIMD Area: SIMD (Single Instruction Multiple Data) O-x86 labels Sep 3, 2020
@mati865
Copy link
Contributor

mati865 commented Sep 21, 2020

IMO with MMX support removed from Rust this should be closed.

@workingjubilee
Copy link
Member

Agreed. It is no longer possible to invoke the relevant intrinsics on nightly, so Rust cannot cause the relevant interaction directly, and in particular the reproducer just results in a compiler error. This issue can be closed.

@Noratrieb Noratrieb added O-x86_32 Target: x86 processors, 32 bit (like i686-*) and removed O-x86-all labels Oct 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-SIMD Area: SIMD (Single Instruction Multiple Data) C-enhancement Category: An issue proposing an enhancement or a PR with one. O-x86_32 Target: x86 processors, 32 bit (like i686-*) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

8 participants