-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Casting the same i64 and u64 integers to f32 gives different results on i686-pc-windows-msvc
target
#105626
Comments
n as i64 as f32
and n as u64 as f32
give different results on i686-pc-windows-msvc
targeti686-pc-windows-msvc
target
Here's some reproduction on Godbolt. The problem seems unrelated to i64 and it's entirely the u64 -> f32 conversion that's buggy. https://rust.godbolt.org/z/9Gccr5o1s The fact that we use the floating point numbers as some sort of address makes it seem like we are loading the value from a lookup table and there might be a bug in Windows' table: fadd dword ptr [4*eax + __real@5f80000000000000] |
Took me way too long, but I figured it out. The fact that FPU instructions are used means that it runs into problems with the FPU accuracy. By default the control word is set to 0x27f on Windows and 0x37f on Linux. In particular the 0x3 vs 0x2 is the precision control setting of the FPU.
So on Windows it's in 53-bits mode whereas on Linux it's in 64-bits mode. Running the following code therefore fixes the problem on Windows: fn load_fpu_control_word(control: u16) {
unsafe {
asm!("fldcw [{}]", in(reg) &control, options(nostack));
}
}
load_fpu_control_word(0x37f); This probably is an LLVM bug where LLVM assumes the FPU is configured like on Linux instead of like on Windows. MSVC for example just emits a call to |
The function that lowers the uint to float cast is |
I tested it with some other code and thought it was resolved. |
This was patched upstream (thanks icedrocket!) but it seems like they reverted the patch, as unfortunately it broke Chrome's build: llvm/llvm-project@1692dff I don't know if it is more profitable to work around this on our end by emitting the relevant call? It looks like there's an intention to use another fix: https://reviews.llvm.org/D142178 |
A new fix has been commited to upstream: llvm/llvm-project@11fb09e |
Update LLVM submodule Fixes rust-lang#105626.
Update LLVM submodule Fixes rust-lang#105626.
Update LLVM submodule Fixes rust-lang#105626.
I tried this code:
rust-num/num-bigint#261
I expected to see this happen:
The code prints the output below and exits successfully.
Instead, this happened:
The code prints the output below and panics.
Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: