Pracuję nad skrzynią Rust, która zmienia tryb zaokrąglania (+ inf, -inf, nearest lub truncate).Który z LLVM odpowiada za optymalizacje zmiennoprzecinkowe?
Funkcje, które zmieniają tryb zaokrąglania są napisane przy użyciu zestawu inline:
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}"
);
}
}
Kiedy skompilować kod w trybie debugowania, że działa zgodnie z przeznaczeniem, dostaję 0.3333333333337 jedną trzecią gdy zaokrąglenie w kierunku dodatnim nieskończoności, ale gdy kompiluję w trybie zwolnienia, otrzymuję ten sam wynik niezależnie od ustawionego trybu zaokrąglania. Sądzę, że to zachowanie wynika z optymalizacji, które wykonuje backend LLVM.
Jeśli wiedziałem, które przepustki LLVM są odpowiedzialne za tę optymalizację, mogę je wyłączyć, ponieważ nie widzę obecnie żadnego innego obejścia.
Obawiam się, że informacje te mogą w dużym stopniu zależeć od wersji LLVM (która jest bezpłatna do dodawania/usuwania karnetów), a w związku z tym jest związana z wersją 'rustc'. Którą wersję 'rustc' używasz? Czy przeszkadza Ci to, gdy ulegnie uszkodzeniu podczas aktualizacji? –
Używam Rust 1.10 co wieczór. Nie mam nic przeciwko, jeśli się zepsuje. Jeśli rozumiem, co powoduje takie zachowanie, mogę z odrobiną ciężkiej pracy zrobić pewne obejście. –
Po pewnym odczycie uważam, że istnieją pewne podania do harmonogramu, które przesuwają instrukcję dzielenia przed wywołaniem funkcji upward(). (tylko przypuszczenie), popraw mnie, jeśli się mylę. –