On Thu, 28 Apr 2016, Matthew Wahab wrote:

> Hello,
> 
> 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 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?

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.".

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.

-- 
Joseph S. Myers
jos...@codesourcery.com

Reply via email to