-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Tracking issue: 32bit x86 targets without SSE2 have unsound floating point behavior #114479
Copy link
Copy link
Open
Labels
A-floating-pointArea: Floating point numbers and arithmeticArea: Floating point numbers and arithmeticC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCI-miscompileIssue: Correct Rust code lowers to incorrect machine codeIssue: Correct Rust code lowers to incorrect machine codeI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessO-x86_32Target: x86 processors, 32 bit (like i686-*) (also known as IA-32, i386, i586, i686)Target: x86 processors, 32 bit (like i686-*) (also known as IA-32, i386, i586, i686)P-mediumMedium priorityMedium priority
Metadata
Metadata
Assignees
Labels
A-floating-pointArea: Floating point numbers and arithmeticArea: Floating point numbers and arithmeticC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCI-miscompileIssue: Correct Rust code lowers to incorrect machine codeIssue: Correct Rust code lowers to incorrect machine codeI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessO-x86_32Target: x86 processors, 32 bit (like i686-*) (also known as IA-32, i386, i586, i686)Target: x86 processors, 32 bit (like i686-*) (also known as IA-32, i386, i586, i686)P-mediumMedium priorityMedium priority
Type
Fields
Give feedbackNo fields configured for issues without a type.
View all comments
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 testtests/ui/numbers-arithmetic/issue-105626.rshas 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. 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 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 workRelated issues:
i586-unknown-linux-gnu#152635: also different problem, LLVM lowering of f->i casts on i586 produce incorrect results.Prior issues: