Skip to content

The ABI of float types can be changed by -Ctarget-feature #116344

Description

@RalfJung

View all comments

A function that 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 or enable the soft-float and 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=-x87 or -Ctarget-feature=+soft-float can 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:

  • It is a hard error to toggle some features with #[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
  • It is a warning to toggle them with -Ctarget-feature announcing that this will become a hard error in the future (will be shipped in 1.84)
  • Not all relevant features are properly detected yet, not even on tier 1 targets

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Oct 2, 2023
  2. RalfJung commented on Oct 2, 2023

    @RalfJung
    MemberAuthor

    Cc @rust-lang/opsem

  3. chorman0773 commented on Oct 2, 2023

    @chorman0773
    Contributor

    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.

  4. workingjubilee commented on Oct 2, 2023

    @workingjubilee
    Member

    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.

  5. chorman0773 commented on Oct 2, 2023

    @chorman0773
    Contributor

    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 +x87 and -x87 though). Both cases it's returned in edx:eax (which is weird, I'd expect f64 to get returned in an xmm register otherwise).

  6. chorman0773 commented on Oct 2, 2023

    @chorman0773
    Contributor

    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 putting movupss everywhere, or worse, silently clobber xmm registers when the kernel does something even cleverer with cr4.OSFXSAVE/cr4.OSXSAVE enabled.

  7. workingjubilee commented on Oct 2, 2023

    @workingjubilee
    Member

    Kernel-friendly targets need to be handled specially as always.

  8. added
    O-x86_64Target: x86-64 processors (like x86_64-*) (also known as amd64 and x64)
    A-ABIArea: Concerning the application binary interface (ABI)
    T-opsemRelevant to the opsem team
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Oct 2, 2023
  9. chorman0773 commented on Oct 2, 2023

    @chorman0773
    Contributor

    I was about to say this didn't need O-x86_64, but...
    https://rust.godbolt.org/z/EzMhdsqx9

  10. RalfJung commented on Oct 2, 2023

    @RalfJung
    MemberAuthor

    I 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. :)

  11. 109 remaining items

  12. added 4 commits that reference this issue on Feb 7, 2026
  13. added a commit that references this issue on Feb 7, 2026
  14. TimNN commented on Aug 17, 2026

    @TimNN
    Contributor

    FYI: It looks like LLVM recently submitted llvm/llvm-project#111334 which reports an error specifically for hard/soft float mismatches on ARM.

  15. added 3 commits that reference this issue on Sep 3, 2026
  16. added a commit that references this issue on Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ABIArea: Concerning the application binary interface (ABI)A-floating-pointArea: Floating point numbers and arithmeticA-target-featureArea: Enabling/disabling target features like AVX, Neon, etc.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-opsemRelevant to the opsem team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions