Are LLVM/rust's floating-point issues on 32-bit platforms relevant to Julia?

Palli
Thu, 13 Nov 2025 16:17:00 +0000
Offtopic

I noticed:

github.com/rust-lang/rust

Tracking issue: 32bit x86 targets lose float NaN payload in return values

opened 12:42PM - 05 Sep 23 UTC

RalfJung

C-tracking-issue A-floating-point A-ABI O-x86_32

On x86 (32bit) targets, returning a floating-point number from a "C" ABI functi…on by-value can change the bits of their NaN payloads. (Specifically, the quiet bit gets set.) This is caused by using x87 registers to pass return values, as mandated by the ABI for this target. This is a known and long-standing problem, and very hard to fix. The purpose of this issue mostly is to document its existence and to give it a URL that can be referenced. A proper fix would require patching LLVM to use different code to load float return values into an x87 register -- specifically, it has to be done in a way that NaN payloads are fully preserved. Related issues: - https://github.com/llvm/llvm-project/issues/66803: the same bug on the LLVM side. - https://github.com/rust-lang/rust/issues/114479: that's a different problem, also affecting x86-32 but concerning the actual FP computations, not the NaN bits of return values. Prior issues: - https://github.com/rust-lang/rust/issues/73288 - https://github.com/rust-lang/rust/issues/46948

github.com/rust-lang/rust

Tracking issue: 32bit x86 targets without SSE2 have unsound floating point behavior

opened 06:46PM - 04 Aug 23 UTC

RalfJung

P-medium I-unsound C-tracking-issue A-floating-point O-x86_32 I-miscompile

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](https://github.com/rust-lang/rust/issues/114479#issuecomment-2072052116). 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. Note that this problem affects all binaries built without SSE2 being globally enabled, even if these binaries are later used on systems that do have SSE2 -- the only way to avoid the problem is to not use the x87 FPU at all, i.e., generate binaries that require SSE2. 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](https://open-std.org/JTC1/SC22/JSG/docs/m3/docs/jsgn326.pdf). - 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](https://github.com/rust-lang/rust/issues/114479#issuecomment-1808507590) Related issues: - https://github.com/llvm/llvm-project/issues/44218: basically the same bug on the LLVM side, and pointing out the potential for soundness issues - https://github.com/rust-lang/rust/issues/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: - https://github.com/rust-lang/rust/issues/72327

This is an LLVM bug: rustc is generating LLVM IR with the intended semantics

This is about Rust, but might translate to Julia (and more) since both use LLVM?!

Both have tier 1 support for 32-bit on Windows, and them on Linux too (we tier 2). [And they are now ahead with tier 1 support for ARM64 on Windows too, us tier 2 only, tier 1 for macOS though, and this is off-topic. I suppose all ARM just work for floating point.]

32-bit x86 uses floating point stack, at least for Rust, if I recall implicated. I think 64-bit doesn’t usse it (but could), neither for us, do we use it for 32-bit?

3 posts - 3 participants