I am working on a Rust crate which changes the rounding mode (+inf, -inf, nearest, or truncate).
The functions that change the rounding mode are written using inline assembly:
fn upward() {
let cw: u32 = 0;
unsafe {
asm!("stmxcsr $0;
mov $0, %eax;
or $$0x4000, %eax;
mov %eax, $0;
ldmxcsr $0;"
: "=*m"(&cw)
: "*m"(&cw)
: "{eax}"
);
}
}
When I compile the code in debug mode it works as intended, I get 0.3333333333337 for one-third when rounding toward positive infinity, but when I compile in release mode I get the same result no matter what rounding mode I set. I guess this behavior is due to the optimizations that the LLVM backend does.
If I knew which LLVM passes are responsible for this optimization, I can disable them as I don't see any other workaround at the moment.