哪些LLVM传递负责浮点优化?

Hou*_*_gc 5 floating-point rounding inline-assembly rust llvm-codegen

我正在研究一个改变舍入模式的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}"
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

当我在调试模式下编译代码时,它按预期工作,当向正无穷大舍入时,我获得0.3333333333337三分之一,但是当我在释放模式下编译时,无论我设置什么舍入模式,我都得到相同的结果.我想这种行为是由于LLVM后端的优化所致.

如果我知道哪个LLVM通过负责此优化,我可以禁用它们,因为我目前没有看到任何其他解决方法.

Eli*_*man 5

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

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

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

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

  • 是。到那时,您基本上只在编写原始程序集,因此Rust或LLVM IR的语义无关紧要。 (2认同)