丸めモード (+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}"
);
}
}
デバッグ モードでコードをコンパイルすると、意図したとおりに動作します。正の無限大に向かって丸めると、3 分の 1 で 0.3333333333337 が得られますが、リリース モードでコンパイルすると、設定した丸めモードに関係なく同じ結果が得られます。この動作は、LLVM バックエンドが行う最適化によるものだと思います。
この最適化の原因となっている LLVM パスがわかっている場合は、現時点で他の回避策が見当たらないため、それらを無効にすることができます。