Tracking issue: 32bit x86 targets without SSE2 have unsound floating point behavior #114479
Description
On x86 (32bit) targets that cannot use SSE2 instructions (this includes the tier 1 i686 targets with flags that disable SSE2 support, such as -C target-cpu=pentium
), floating-point operation can return results that are rounded in different ways than they should, and results can be "inconsistent": depending on whether const-propagation happened, the same computation can produce different results, leading to a program that seemingly contradicts itself. This is caused by using x87 instructions to perform floating-point arithmetic, which do not accurately implement IEEE floating-point semantics (not with the right precision, anyway). The test tests/ui/numbers-arithmetic/issue-105626.rs
has an example of such a problem.
Worse, LLVM can use x87 register to store values it thinks are floats, which resets the signaling bit and thus alters the value -- leading to miscompilations.
This is an LLVM bug: rustc is generating LLVM IR with the intended semantics, but LLVM does not compile that code in the way that the LLVM LangRef describes. This is a known and long-standing problem, and very hard to fix. The affected targets are so niche these days that that is nobody's priority. The purpose of this issue mostly is to document its existence and to give it a URL that can be referenced.
Some ideas that have been floated for fixing this problem:
- We could emit different instruction sequences for floating-point operations that emulate the expected rounding behavior using x87 instructions. This will likely require changes deep in LLVM's x86 backend. This is what Java does.
- We could use softfloats.
We could set the FPU control register to 64bit precision for Rust programs, and require other code to set the register in that way before calling into a Rust library.this does not work
Related issues:
- Wrong optimization: instability of x87 floating-point results leads to nonsense llvm/llvm-project#44218: basically the same bug on the LLVM side, and pointing out the potential for soundness issues
- Tracking issue: 32bit x86 targets lose float NaN payload in return values #115567: that's a different problem, also affecting x86-32 but unrelated to what happens when an FP operation is executed; it is about the behavior of NaN bits as they get returned from a function
Prior issues:
Activity