我正在研究一个改变舍入模式的Rust箱子(+ inf,-inf,最近或截断)。
更改舍入模式的函数使用内联汇编编写:
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}"
);
}
}
当我在调试模式下编译代码时,它按预期工作,当向正无穷大舍入时,我获得0.3333333333337三分之一,但是当我在释放模式下编译时,无论我设置什么舍入模式,我都得到相同的结果。我想这种行为是由于LLVM后端的优化所致。
如果我知道哪个LLVM通过负责此优化,我可以禁用它们,因为我目前还没有看到任何其他解决方法。
答案 0 :(得分:4)
基本上,你不能这样做。 LLVM假定所有浮点运算都使用默认的舍入模式,并且永远不会读取或修改浮点控制寄存器。
如果您有兴趣,那就是some discussion of this issue recently on the LLVM-dev mailing list。
与此同时,唯一可靠的解决方法是使用内联汇编,例如asm!("addsd $0, $1"
。
Rust的标准库还假设您不修改舍入模式(特别是浮点和字符串之间的转换代码对此敏感)。