2016-04-22 76 views
5

我正在修改舍入模式(+ inf,-inf,最接近或截斷)的Rust箱子。哪些LLVM通道負責浮點優化?

是改變舍入模式的功能是使用內聯彙編語言編寫:

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

恐怕這個信息可能非常依賴於LLVM的版本(可以自由添加/刪除通行證),並且因此與'rustc'版本綁定。你正在使用哪個版本的'rustc'?你介意升級時是否破壞? –

+0

我每晚都使用Rust 1.10。我不介意它是否中斷。如果我明白是什麼導致了這種行爲,我可以用一點努力做一些解決方法。 –

+1

經過一些閱讀後,我認爲有一些調度通行證正在move()函數調用之前移動divide指令。 (只是一個猜測),糾正我,如果我錯了。 –

回答

4

基本上,你不能這樣做。 LLVM假定所有浮點操作都使用默認舍入模式,並且浮點控制寄存器從不讀取或修改。

有過some discussion of this issue recently on the LLVM-dev mailing list,如果你有興趣。

與此同時,唯一可靠的解決方法是使用內聯彙編,如asm!("addsd $0, $1"

Rust的標準庫還假定您不修改舍入模式(特別是浮點和字符串之間轉換的代碼對此敏感)。

+0

如果我理解你是正確的,那麼在使用內聯彙編時,通過asm中的計算來考慮在mxcsr或fctrl寄存器中設置的舍入模式。宏? –

+1

是的。此時,你基本上只是在編寫原始程序集,所以Rust或LLVM IR的語義無關緊要。 –

+0

是的,LLVM優化是在IR上進行的,謝謝。 –