Я работаю над ящиком ржавчины, который меняет режим округления (+ inf, -inf, ближайшее или усекать).Какие пропуска 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 отвечают за эту оптимизацию, я могу отключить их, поскольку на данный момент я не вижу другого обходного пути.
Я боюсь, что эта информация может сильно зависеть от версии LLVM (которая бесплатна для добавления/удаления проходов) и в результате связана с версией 'rustc'. Какую версию 'rustc' вы используете? Не возражаете, если это ломается при обновлении? –
Я использую Rust 1.10 ночной. Я не возражаю, если он сломается. Если я понимаю, что вызывает такое поведение, я могу с небольшой усердием сделать некоторые способы обхода. –
После некоторого чтения я думаю, что есть некоторые прогоны планирования, которые перемещают инструкцию деления перед вызовом функции вверх(). (просто догадка), исправьте меня, если я ошибаюсь. –