[clang] [llvm] [SystemZ] Add support for half (fp16) (PR #109164)
Trevor Gross via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 23 14:47:00 PDT 2024
tgross35 wrote:
> From what I can see in the libgcc sources, `__gnu_h2f_ieee`/`__gnu_f2h_ieee` is indeed always `i32`<->`i16`, but it is only present on 32-bit ARM, no other platforms. On AArch64, GCC will always use inline instructions to perform the conversion. On 32-bit and 64-bit Intel, the compiler will use inline instructions if AVX512-FP16 is available; if not, but SSE2 is available, the compiler will use `__extendhfsf2`/`__truncsfhf2` with a `HFmode` argument (this corresponds to `_Float16`, i.e. it is passed in SSE2 registers, not like an integer); if not even SSE2 is available, using the type will result in an error.
>
> I never see `__extendhfsf2`/`__truncsfhf2` being used with `int16_t`, even in principle, on any platform in libgcc. There is indeed a setting `__LIBGCC_HAS_HF_MODE__` (controlled indirectly by the GCC target back-end's `TARGET_LIBGCC_FLOATING_POINT_MODE_SUPPORTED_P` setting), but the only thing that appears to be controlled by this flag is whether routines for complex multiplication and division (`__mulhc3` / `__divhc3`) are being built. Am I missing something here?
I think this is accurate, libgcc just appears to (reasonably) not provide any f16-related symbols on platforms where GCC doesn't support `_Float16`. LLVM does seem to use `__gnu_h2f_ieee` and `__gnu_f2h_ieee` though, on targets where Clang doesn't have `_Float16` (e.g. PowerPC, Wasm, x86-32 without SSE), which is why it shows up in the current state of this PR. Presumably this is `HasLegalHalfType`?
For that reason we just always provide the symbol [in rust's compiler-builtins](https://github.com/rust-lang/compiler-builtins/blob/adaef3265c560998a03b6902bd63d88009d3a132/src/float/trunc.rs#L139-L145) (though we let LLVM figure out that `f16` is `i16`).
> > @uweigand mentioned figuring out an ABI for `_Float16`, is this possible? That seems like the best option.
>
> Yes, we're working on that. What we're planning to do is to have `_Float16` be passed and returned in the same way as `float` and `double`, i.e. using (part of) certain floating-point registers. These registers are available on every SystemZ architecture level, so we would not have to guard their use (like Intel does with the SSE2 registers).
That is great news, especially considering how problematic the target-feature-dependent ABI on x86-32 has been.
https://github.com/llvm/llvm-project/pull/109164
More information about the cfe-commits
mailing list