Skip to content

Add initial f16/f128 support #1574

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

beetrees
Copy link
Contributor

@beetrees beetrees commented Apr 22, 2025

This PR adds basic initial support for f16 and f128. While this allows simple programs (e.g. dbg!(1.0_f16)) to compile on architectures where Cranelift has basic support for f16/f128 values (currently x86-64 and AArch64), rustc_codegen_cranelift still can't compile compiler_builtins without no-f16-f128 due to missing support in cranelift_frontend (fixed by bytecodealliance/wasmtime#10631) and compiler_builtins requiring math support.

cc @tgross35

@tgross35
Copy link
Contributor

LGTM for the non cranelift-specific parts, LLVM also does promote/demote for f16 powi and fmod.

@bjorn3
Copy link
Member

bjorn3 commented Apr 22, 2025

Is Cranelift ABI compatible with LLVM for f16 and f128 across all targets Cranelift supports?

@beetrees
Copy link
Contributor Author

beetrees commented Apr 22, 2025

By architecture/platform:

  • Non-Windows x86-64 - f16/f128 are passed/returned in XMM registers as per specification.
  • Windows x86-64 - f16/f128 are not supported by the Windows x86-64 ABI, but are available in Cranelift with enable_llvm_abi_extensions which currently matches LLVM 21 (passing/returning both types in XMM registers, except for passing f128 indirectly). Note that LLVM 20, the current LLVM version used by Rust, always passes f128 in XMM registers (see [windows] Always pass fp128 arguments indirectly llvm/llvm-project#128848).
  • Non-Apple AArch64 - f16/f128 are passed/returned in floating-point registers as per specification.
  • Apple AArch64 - the Apple ARM ABI is a variant of the standard AAPCS64, and Apple targets only support f16 in C (where it is passed/returned in floating-point registers). f128 is available in Cranelift with enable_llvm_abi_extensions, matching LLVM by passing/returning in floating-point registers like on non-Apple AArch64.
  • 64-bit RISC-V - f16 is passed/returned in floating-point registers, f128 is passed/returned as a pair of integer registers, both as per the LP64D ABI in the specification (Cranelift does not currently support any other standard RISC-V ABIs).
  • s390x - f128 is passed/returned indirectly as per specification, f16 is only supported as an LLVM/Clang extension in the upcoming LLVM 21 (see [SystemZ] Add support for half (fp16) llvm/llvm-project#109164), where it is passed/returned in floating-point registers.

Summary: All Cranelift f16/f128 support currently matches the standard ABIs, with enable_llvm_abi_extensions enabling extensions that match LLVM 21. Cranelift's Windows x86-64 f128 ABI (only available via enable_llvm_abi_extensions) isn't compatible with the f128 ABI used by LLVM 20.

@beetrees
Copy link
Contributor Author

beetrees commented May 4, 2025

Update: basic load/store/bitcast support is now available for all 4 architectures. Combined with the emit_zero fix, this should all be available in the Cranelift release scheduled for 20th May. Once that happens, it should be theoretically possible to have full f16/f128 support in rustc_codegen_cranelift by lowering math operations to directly calling the relevant functions from compiler-builtins instead of using the not-yet-implemented CLIF instructions. The partial exception to this is f128 on x86-64 Windows, which won't be usable with a Rust sysroot compiled with LLVM 20 (the current version used by Rust) as the f128 ABI has only been fixed in LLVM 21+ (see llvm/llvm-project#128848).

@tgross35
Copy link
Contributor

tgross35 commented May 6, 2025

As a note, once the above lowering to compiler-builtins is available, the recently added config at

TargetConfig {
target_features,
unstable_target_features,
// Cranelift does not yet support f16 or f128
has_reliable_f16: false,
has_reliable_f16_math: false,
has_reliable_f128: false,
has_reliable_f128_math: false,
}
could likely be updated to start running tests. (Hopefully rust-lang/rust#138087 will merge first to avoid racing on any possible new test failures in r-l/rust).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants