uweigand wrote:
> My understanding is that in GCC's `__gnu_h2f_ieee`/`__gnu_f2h_ieee` is always > `i32`<->`i16` (integer ABI), then `__extendhfsf2`/`__truncsfhf2` uses either > `int16_t` or `_Float16` on a per-target basis as controlled by > `__LIBGCC_HAS_HF_MODE__` (I don't know where this gets set). In LLVM > compiler-rt, `COMPILER_RT_HAS_FLOAT16` is the control to do the same thing > but it affects `extend`/`trunc` as well as `h2f`/`f2h`. I think the > discrepancy works out here because if a target has `_Float16`, it will never > be calling `__gnu_h2f_ieee` `__gnu_f2h_ieee`. >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? > From your first two sentences it sounds like `f16` is getting passed in a FP > register but going > FP->GPR->__gnu_h2f_ieee->FP->some_math_op->FP->__gnu_f2h_ieee->GPR->FP? I > think it makes sense to either always pass `f16` as `i16` and avoid the FP > registers, or make `_Float16` available so `COMPILER_RT_HAS_FLOAT16` can be > used. > > @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). > A quick check seems to show that GCC 13 does not support `_Float16` on s390x, > nor does the crossbuild `libgcc.a` provide `__gnu_h2f_ieee`, > `__gnu_f2h_ieee`, `__extendhfsf2`, or `__truncsfhf2`. So I think LLVM will be > the one to set the precedent here. Yes, we'd have to add those. I don't think we want `__gnu_h2f_ieee` or `__gnu_f2h_ieee` as those are ARM-only. We'd be defining and using `__extendhfsf2` and `__truncsfhf2`, which would be defined with `_Float16` arguments passed in floating-point registers. Either way, we should define the same set of routines (with the same ABI) in libgcc and compiler-rt. > Note that there are some common issues with these conversions, would probably > be good to test against them if possible #97981 #97975. Thanks for pointing this out! https://github.com/llvm/llvm-project/pull/109164 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits