Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

f16 and f128 have non-trivial ABI requirements on some targets #138616

Open
RalfJung opened this issue Mar 17, 2025 · 1 comment
Open

f16 and f128 have non-trivial ABI requirements on some targets #138616

RalfJung opened this issue Mar 17, 2025 · 1 comment
Labels
F-f16_and_f128 `#![feature(f16)]`, `#![feature(f128)]` needs-triage This issue may need triage. Remove it if it has been sufficiently triaged.

Comments

@RalfJung
Copy link
Member

RalfJung commented Mar 17, 2025

The standard C ABI for f16 and f128 requires particular target features on certain targets, going beyond the baseline that is generally required for those targets:

This list is non-exhaustive. More research needs to be done here before these types can be stabilized.

But meanwhile, there's the question of -- how should we handle this?

Broadly speaking we have two hammers we could apply here:

  • We mark certain target features as required by the ABI on particular targets. For instance, we already mark x87 as required on targets like i686-unknown-linux-gnu. This might then necessitate creating more target triples so that one can choose another ABI that does not require those target features. I don't know if a standard ABI for f16 without SSE exists on x86-32. We could make one up, like using the softfloat convention for f16 while still passing all other float types like hardfloats, but that does not seem great.
  • We consider certain types to require certain target features when being passed via extern "C" functions. For extern "Rust", we need to come up with our own ABI that avoids the use of any non-default target features. This is what we do for SIMD types. However, this is not quite enough on LLVM since some operations on float types are implicitly lowered to libcalls by LLVM and those can use the wrong ABI. (That's not a problem for SIMD as all operations there are intrinsics which we are already manually decorating with the required target features.) LLVM is generally built around the assumption that the compiler just rejects any use of a type if the corresponding target feature is missing, as that's how C works.

The second hammer seems more attractive here, though it is inconsistent with how we handled f32 / f64 requiring particular target features. I guess we didn't want to lose passing those in float registers for "Rust" functions. ;) The other downside of this approach is that it is incomplete as long as LLVM still uses the wrong ABI for the libcalls it generates.

Cc @tgross35

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 17, 2025
@RalfJung RalfJung added the F-f16_and_f128 `#![feature(f16)]`, `#![feature(f128)]` label Mar 17, 2025
@RalfJung
Copy link
Member Author

RalfJung commented Mar 17, 2025

The other downside of this approach is that it is incomplete as long as LLVM still uses the wrong ABI for the libcalls it generates.

If we also want to follow the SIMD approach here, that basically means we have to consider primitive operations on f16 and f128 to require certain target features, just like the primitive operations on SIMD types (provided via intrinsics). Essentially, we'd need a MIR pass (or earlier) that checks all unary and binary operators, casts, and maybe more, and if there's an f16 / f128 anywhere, it consults a target-specific list of target features that have to be available in the calling function to permit this operation. It also means those types cannot implement Add/Sub/... as we cannot add target features to the trait impls...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-f16_and_f128 `#![feature(f16)]`, `#![feature(f128)]` needs-triage This issue may need triage. Remove it if it has been sufficiently triaged.
Projects
None yet
Development

No branches or pull requests

2 participants