Skip to content

Discussion about platform support of f16 and f128Β #151557

Description

@tgross35

Continuing discussion from the tracking issue starting around here #116909 (comment).

Activity

  1. added
    C-discussionCategory: Discussion or questions that doesn't represent real issues.
    F-f16_and_f128`#![feature(f16)]`, `#![feature(f128)]`
    on Jan 23, 2026
  2. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Jan 23, 2026
  3. removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Jan 23, 2026
  4. tgross35 commented on Jan 23, 2026

    @tgross35
    MemberAuthor

    Replying to @pinskia at #116909 (comment):

    I realize this is differs from the usual GCC path which e.g. doesn't support __int128 on i386 since it (despite my efforts) isn't specified there.

    It is also not defined on arm (aarch32) nor powerpc32 nor mips32. You still are thinking everything is x86 again and again.

    "e.g." was meant to imply this was a single example, it's not an exhaustive list.

    AFAIK LLVM's half type now works on all targets since LLVM22, using i16 ABI and libcalls as a fallback. f128 still has some work to be done. For reference, we keep track of this at

    llvm/llvm-project@a0c5f19 says otherwise. Unless that was reverted. Plus using i16 ABI sounds like an ABI violation here. The bigger issue here is LLVM also is broken and should have made the discussion effort about ABIs. I think for MIPS ABI for an example f16 should pass via floating point registers but LLVM is not going to break the ABI now will they? This makes things harder in general.

    I was not aware of the zOS patch, but at least it sounds like it is expected to come back llvm/llvm-project#145532 (comment).

    I don't think the current ABI can be considered "broken" when there is nothing to be compatible with, it's just effectively an LLVM extension. Would discussion about ABI have been meaningful? Given the current state of thing, I wouldn't expect GCC to ever support _Float16 or any newer types on MIPS since its ABI is frozen in 1994.

    If GCC did start supporting f16 on MIPS or others then I think LLVM would likely be okay with an ABI break, based on some precedent. Of course ideally there would be LLVM-GCC cross-discussion for figuring out the best ABI. Agreed that fregs is probably better on MIPS and some other platforms, the int fallback is just a more reasonable default across all unspecified targets.

    (Note that LLVM provides half pretty much everywhere but the Clang frontend doesn't yet expose _Float16 on all platforms, similar to GCC. I don't know that this will always be the case, though.)

  5. programmerjake commented on Jan 24, 2026

    @programmerjake
    Member

    One other thing to consider is that Rust's ABI (not to be confused with extern "C") is basically whatever rustc finds most convenient, so it doesn't have to match whatever the psABI (or equivalent) for your target is, it can be whatever LLVM feels like doing today as long as rustc can make that work. That said, I think there is an effort being made to have the LLVM and GCC rustc backends have compatible ABIs, though IDK how compatible they are.

    Rust's ABI compatibility for extern "Rust" is use the exact same compiler version otherwise whenever it breaks you get to keep all the pieces.

  6. pinskia commented on Jan 24, 2026

    @pinskia

    One other thing to consider is that Rust's ABI (not to be confused with extern "C") is basically whatever rustc finds most convenient,

    I do find that alone is a broken part of rustc. Because it means writing C code that calls into rust code has take extra extra steps. This is unlike how most Fortran, Ada, D or most other languages happen today. (yes Fortran2003 has BIND(C) which allows for portable extern "C" but most compilers support it with earlier versions of Fortran even Fortran77). Basically RUSTC said let's break compatibility because LLVM does not provide us with the support. That is the bigger issue at handle.
    The way GCC front-ends works is the middle-end does all of the layout and such and argument passing handling.

    so it doesn't have to match whatever the psABI (or equivalent) for your target is, it can be whatever LLVM feels like doing today as long as rustc can make that work. That said, I think there is an effort being made to have the LLVM and GCC rustc backends have compatible ABIs, though IDK how compatible they are.

    It is hard to do compatibility really because of the way LLVM is broken in a few different ways and not supplying ABI/struct layout functionality in the first place.

    Rust's ABI compatibility for extern "Rust" is use the exact same compiler version otherwise whenever it breaks you get to keep all the pieces.

  7. programmerjake commented on Jan 24, 2026

    @programmerjake
    Member

    Basically RUSTC said let's break compatibility because LLVM does not provide us with the support.

    Afaik the reason rustc doesn't have a stable Rust ABI is because we want to allow future changes without everyone complaining that we broke all their code because the ABI changed. a good example of that is when rustc changed the ABI for returning floats on x86-32 targets with SSE to return them in SSE registers instead of using the x87 registers as required by the C ABI -- that fixes signalling NaNs being converted to quiet NaNs when just returning them from a function.
    rustc does have working extern "C" for when you want to opt-in to having a stable ABI, but by doing that you're also opting out of having that ABI improve in the future. So afaik it wasn't because getting the correct C ABI with LLVM is really difficult, because rustc goes to all that effort anyway when you select the C ABI by making your function extern "C".

  8. pinskia commented on Jan 24, 2026

    @pinskia

    Basically RUSTC said let's break compatibility because LLVM does not provide us with the support.

    Afaik the reason rustc doesn't have a stable Rust ABI is because we want to allow future changes without everyone complaining that we broke all their code because the ABI changed. a good example of that is when rustc changed the ABI for returning floats on x86-32 targets with SSE to return them in SSE registers instead of using the x87 registers as required by the C ABI -- that fixes signalling NaNs being converted to quiet NaNs when just returning them from a function.

    everyone complaining
    Those 2 words are the reason why you have a stable abi. Breaking them even without a guarantee is bad news. Breaking them for not using x87 is even worse news. Oh i forgot llvm has many troubles with x87 in the first place. Did you know sse also has issues with nans?

    rustc does have working extern "C" for when you want to opt-in to having a stable ABI, but by doing that you're also opting out of having that ABI improve in the future. So afaik it wasn't because getting the correct C ABI with LLVM is really difficult, because rustc goes to all that effort anyway when you select the C ABI by making your function extern "C".

    I still am laughing here. Because Breaking for x87 vs sse is just funny.

    I still see everyone is taking a x86 center of the world approach too. Like the world does not revolve around x86 and never did. Oh maybe it did for llvm but that is a different story.

  9. tgross35 commented on Jan 24, 2026

    @tgross35
    MemberAuthor

    There are certainly numerous residual issues with NaNs that consume a lot of effort. What Jacob mentioned is specifically about the issue where a float's bitwise repr may be modified simply by passing to another function, which we get around by passing in GPRs or (if available) vregs - no interaction with the actual SSE ops.

    Keeping the ABI flexibility isn't x86-specific, that arch just tends to hit edge cases the easiest. There isn't any reason we couldn't also use this flexibility to do something like return an enum tag in a GPR and its payload via an outptr for optimization opportunities (came up in discussion recently).

  10. nikic commented on Jan 24, 2026

    @nikic
    Contributor

    (Note that LLVM provides half pretty much everywhere but the Clang frontend doesn't yet expose _Float16 on all platforms, similar to GCC. I don't know that this will always be the case, though.)

    Right, clang only supports _Float16 on targets that have a defined ABI for it. (It also supports the storage-only __fp16 on all targets, as an extension.)

    half in LLVM will follow the psABI for the target if one is defined and otherwise use an unstable ABI that can (and does) change between versions.

    Rust only cares about the psABI for extern "C" functions. I assume that f16 will trigger the improper C types lint when you try to use it in FFI on a target that does not define an ABI for it.

    Compatibility between the LLVM backend and other backends for the extern "Rust" ABI requires mapping the Rust ABI to something that is supported by all relevant backends (which would be the platform psABI if no extensions are supported). We have made changes to the Rust ABI to accommodate ABI compatibility between LLVM and Cranelift in the past. I'm not familiar with what the ABI compatibility story for the GCC backend is.

  11. programmerjake commented on Jan 24, 2026

    @programmerjake
    Member

    I still see everyone is taking a x86 center of the world approach too. Like the world does not revolve around x86 and never did. Oh maybe it did for llvm but that is a different story.

    My current job is designing a Power ISA CPU (where I'm kinda annoyed that the ELFv2 ABI requires f128 to be passed in vector registers which I'm not planning on implementing anytime soon), so no, everyone thinking x86 is the center of the world is just your assumption.

  12. barracuda156 commented on May 1, 2026

    @barracuda156

    @pinskia @programmerjake Addition of f128 has broken the build of mrustc on powerpc-darwin.

  13. tgross35 commented on May 1, 2026

    @tgross35
    MemberAuthor

    We don't yet support f128 on PPC targets because of the ABI. That's a todo item, they're just disabled for now. I'll reply on the mrustc issue.

    (Andrew is a GCC maintainer not directly involved with our float work)

  14. barracuda156 commented on May 2, 2026

    @barracuda156

    @tgross35

    I'll reply on the mrustc issue

    Thank you, let’s continue discussion there, as it is somewhat niche.

    Andrew is a GCC maintainer not directly involved with our float work

    Yes, I referred him because I know him (not in person, but via gcc-related issues).

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

    C-discussionCategory: Discussion or questions that doesn't represent real issues.F-f16_and_f128`#![feature(f16)]`, `#![feature(f128)]`

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions