Repository navigation
The ABI of float types can be changed by -Ctarget-feature #116344
Description
Activity
- addedneeds-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triagingThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
on Oct 2, 2023 Cc @rust-lang/opsem
FTR, I think the -x87,+softfp and -x87,+sse codegens are wrong for at least the C abi, because Sys-V (and msabi) do prescribe that float/double are returned in st(0) and provide no other alternative - so I think rustc should reject this code in particular.
I actually wanted a similar prohibition retroactively on the simd types, but the x86_64-psabi list did not accept that request.
If I understand @chorman0773 correctly #115476 (comment), then a function that takes/returns an f32/f64 is not ABI-compatible with other functions that have the same signature on i686 when certain target features differ. It looks like one can disable the x87 feature and then it will use different ways of passing floating-point arguments.
This is correct.
So IMO we should consider certain features to be in the required baseline for i686 targets and just error out when they get disabled (or force-enable them, or refuse to codegen things involving floats, or something like that) -- in particular, x87 and sse2.
I believe I have vocalized that this is my desired solution as well.
Demonstrating the 3 different ways that rustc returns floats on x86: https://rust.godbolt.org/z/r83MbYh5n.
Although it seems f64 specifically is spared on sse and softfp (not between
+x87and-x87though). Both cases it's returned inedx:eax(which is weird, I'd expectf64to get returned in an xmm register otherwise).So IMO we should consider certain features to be in the required baseline for i686 targets and just error out when they get disabled (or force-enable them, or refuse to codegen things involving floats, or something like that) -- in particular, x87 and sse2. Currently it may seem like --target i686-unknown-linux-gnu -C target-feature=-sse2,-sse is a tier 1 target but really it isn't.
Force enabling them (or blanket erroring) on i686-wide would affect kernel mode code that typically disables the FPU and vector extensions to avoid having to save that state every context switch. Refusing to codegen floats is a reasonable alternative, though. For sse in particular, llvm really loves to copy data arround using xmm registers, so this will either cause a
#GP(0)when llvm starts puttingmovupss everywhere, or worse, silently clobber xmm registers when the kernel does something even cleverer withcr4.OSFXSAVE/cr4.OSXSAVEenabled.Kernel-friendly targets need to be handled specially as always.
- addedO-x86_64Target: x86-64 processors (like x86_64-*) (also known as amd64 and x64)Target: x86-64 processors (like x86_64-*) (also known as amd64 and x64)A-ABIArea: Concerning the application binary interface (ABI)Area: Concerning the application binary interface (ABI)T-opsemRelevant to the opsem teamRelevant to the opsem teamT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.and removedneeds-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triagingThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
on Oct 2, 2023 I was about to say this didn't need O-x86_64, but...
https://rust.godbolt.org/z/EzMhdsqx9I just realized that with
#[target_feature]we don't allow disabling features at all. That makes me quite surprised that we allow disabling features on stable with-C target-feature... was that a deliberate mismatch?
Force enabling them (or blanket erroring) on i686-wide would affect kernel mode code that typically disables the FPU and vector extensions to avoid having to save that state every context switch.
Force enabling them wouldn't affect that code if it doesn't use any floats. :)
109 remaining items
- added 4 commits that reference this issue
on Feb 7, 2026 - added a commit that references this issue
on Feb 22, 2026 - added a commit that references this issue
on May 8, 2026 FYI: It looks like LLVM recently submitted llvm/llvm-project#111334 which reports an error specifically for hard/soft float mismatches on ARM.
Reacted by Ralf Jung- added 3 commits that reference this issue
on Sep 3, 2026 - added a commit that references this issue
on Sep 4, 2026 - added a commit that references this issue
on Sep 19, 2026 - added a commit that references this issue
on Sep 23, 2026
View all comments
A function that returns an
f32/f64is not ABI-compatible with other functions that have the same signature on i686 when certain target features differ. It looks like one can disable thex87feature or enable thesoft-floatand then it will use different ways of passing floating-point arguments.This is unsound as code calling methods from the standard library would now use the wrong registers to return results. In other words, setting
-Ctarget-feature=-x87or-Ctarget-feature=+soft-floatcan introduce UB unless the standard library is rebuilt with the same flags. We therefore should reject these flags, to avoid the UB. This issue tracks that problem, and transitioning it to a hard error.(SIMD types have a similar problem, but we are dealing with that differently. See #116558.)
Current status:
#[target_feature](will be shipped in 1.84) -- not a breaking change since those features were not allowed in#[target_feature]before either, only the error message changed-Ctarget-featureannouncing that this will become a hard error in the future (will be shipped in 1.84)