[ARM] Enable __fp16 as a function parameter and return type.

Matthew Wahab matthew.wahab@foss.arm.com
Tue May 3 13:19:00 GMT 2016


Hello,

On 28/04/16 16:49, Joseph Myers wrote:
> On Thu, 28 Apr 2016, Matthew Wahab wrote:
>
>> The ARM target supports the half-precision floating point type __fp16 but does
>> not allow its use as a function return or parameter type. This patch removes
>> that restriction and defines the ACLE macro __ARM_FP16_ARGS to indicate this.
>> The code generated for passing __fp16 values into and out of functions depends
>> on the level of hardware support but conforms to the AAPCS (see
>> http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf).
>
> The sole use of the TARGET_INVALID_PARAMETER_TYPE and TARGET_INVALID_RETURN_TYPE
> hooks was to disallow __fp16 use as a function return or parameter type.  Thus, I
> think this patch should completely remove those hooks and poison them in
> system.h.

This touches the C and C++ front-ends so I'll send a separate patch to do this.

> This patch addresses one incompatibility of the original __fp16 specification with
> the more recent ACLE specification and the specification in ISO/IEC TS 18661-3 for
> how such types should work. Another such incompatibility is the peculiar rule in
> the original specification that conversions from double to __fp16 go via float,
> with double rounding.  Do you have plans to eliminate that and move to the
> single-rounding semantics that are in current specifications?

The patch aims to preserve the __fp16 semantics currently used by GCC, except for the
obvious argument/return value in registers change. This is to avoid any changes to
the values calculated by existing __fp16 code that might be introduced if things like
the conversion rules are changed.

> I note that that AAPCS revision says for __fp16, in 7.1.1 Arithmetic Types, "In a
> variadic function call this will be passed as a double-precision value.".  I
> haven't checked what this patch implements, but that could be problematic, and
> different from what's said under 7.2, "For variadic functions, float arguments
> that match the ellipsis (...) are converted to type double.".

The patch keeps the current GCC behaviour (conversion to double). (There's an 
existing test for this in gcc.target/arm/fp16-variadic-1.c.)

> In TS 18661-3, _Float16 is *not* affected by default argument promotions; only
> float is.  This reflects how the default conversion of float to double is a legacy
> feature; note for example how in C99 and C11 float _Imaginary is not promoted to
> double _Imaginary, and float _Complex is not promoted to double _Complex.
>
> Thus it would be better for compatibility with TS 18661-3 to pass __fp16 values to
> variadic functions as themselves, unpromoted.  (Formally of course the lack of
> promotion is a language feature not an ABI feature; as long as va_arg for _Float16
> named works correctly, you could promote at the ABI level and then convert back,
> and the only effect would be that sNaNs get quieted, so passing a _Float16 sNaN
> through variable arguments would act as a convertFormat operation instead of a
> copy operation.  It's not clear that having such an ABI-level promotion is a good
> idea, however.)
>
> Now, in the context of the current implementation and current ACLE arithmetic on
> __fp16 values produces float results - the operands are promoted at the C language
> level.  This is different from TS 18661-3, where _Float16 arithmetic produces
> results whose semantics type is _Float16 but which, if FLT_EVAL_METHOD is 0, are
> evaluated with excess range and precision to the range and precision of float.  So
> if __fp16 and float are differently passed to variadic functions, you have the
> issue that if the argument is an expression resulting from __fp16 arithmetic, the
> way it is passed depends on whether current ACLE or TS 18661-3 are followed.  But
> if the eventual aim is for __fp16 (when using the IEEE format rather than the
> alternative format) to become just a typedef for _Float16, then these issues will
> need to be addressed.

When _Float16 support is added, the relationship between __fp16 and _FLoat16 is 
something that will need to be considered. At the moment though, there's only the 
__fp16 type and the intention with this patch is to avoid doing anything that changes 
the behaviour of existing code.

Matthew



More information about the Gcc-patches mailing list