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