5

我正在开发一个更改舍入模式(+inf、-inf、最近或截断)的 Rust 板条箱。

更改舍入模式的函数是使用内联汇编编写的:

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 通道负责此优化,我可以禁用它们,因为目前我没有看到任何其他解决方法。

4

1 回答 1

5

基本上,你不能这样做。LLVM 假定所有浮点运算都使用默认的舍入模式,并且浮点控制寄存器永远不会被读取或修改。

如果您有兴趣,最近在 LLVM-dev 邮件列表上对此问题进行了一些讨论。

同时,唯一可靠的解决方法是使用内联汇编,例如 asm!("addsd $0, $1".

Rust 的标准库还假设您不修改舍入模式(特别是浮点和字符串之间转换的代码对此很敏感)。

于 2016-04-22T22:35:46.347 回答