On Thu, 13 Feb 2025 at 16:46, Ralf Jung <post@xxxxxxxx> wrote: > > Hi all, > > > We have to carefully make the distinction here between codegen and ABI. > > > > The arm64 C code in the kernel is built with -mgeneral-regs-only > > because FP/SIMD registers are not preserved/restored like GPRs, and so > > they must be used only in carefully controlled circumstances, i.e., in > > assembler code called under kernel_neon_begin()/kernel_neon_end() > > [modulo some exceptions related to NEON intrinsics] > > > > This does not impact the ABI, which remains hard-float [this was the > > only arm64 calling convention that existed until about a year ago]. > > Any function that takes or returns floats or doubles (or NEON > > intrinsic types) is simply rejected by the compiler. > > That's how C works. It is not how Rust works. Rust does not reject using floats > ever. Instead, Rust offers softfloat targets where you can still use floats, but > it won't use float registers. Obviously, that needs to use a different ABI. > As you said, aarch64 does not have an official softfloat ABI, but LLVM > implements a de-facto softfloat ABI if you ask it to generate functions that > take/return float types while disabling the relevant target features. (Maybe > LLVM should just refuse to generate such code, and then Rust may have ended up > with a different design. But now this would all be quite tricky to change.) > > > Changing this to softfloat for Rust modifies this calling convention, > > i.e., it will result in floats and doubles being accepted as function > > parameters and return values, but there is no code in the kernel that > > actually supports/implements that. > > As explained above, f32/f64 were already accepted as function parameters and > return values in Rust code before this change. So this patch does not change > anything here. (In fact, the ABI used for these functions should be exactly the > same before and after this patch.) > OK, so can I summarize the above as - Rust calling Rust will work fine and happily use float types without using FP/SIMD registers in codegen; - Rust calling C or C calling Rust will not support float or double arguments or return values due to the restrictions imposed by the C compiler. ? > > Also, it should be clarified > > whether using a softfloat ABI permits the compiler to use FP/SIMD > > registers in codegen. We might still need -Ctarget-feature="-neon" > > here afaict. > > Rust's softfloat targets do not use FP/SIMD registers by default. Ideally these > targets allow selectively using FP/SIMD registers within certain functions; for > aarch64, this is not properly supported by LLVM and therefore Rust. > I read this as 'this default behavior might change in the future', and so -Ctarget-feature="-neon" should be added even if it is redundant at this point in time. > > Ideally, we'd have a target/target-feature combo that makes this more > > explicit: no FP/SIMD codegen at all, without affecting the ABI, > > therefore making float/double types in function prototypes illegal. > > AIUI, this change does something different. > > Having targets without float support would be a significant departure from past > language decisions in Rust -- that doesn't mean it's impossible, but it would > require a non-trivial effort (starting with an RFC to lay down the motivation > and design). > Fair enough. The codegen is all that matters, and there are other cases (e.g., spilling) where the compiler may decide to use FP/SIMD registers without any floats or doubles in sight. In fact, there are swaths of non-performance critical floating point code in the AMDGPU driver where it would be useful to have float/double support using softfloat codegen too.