This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Adding __float128 (i.e TS 18661-3)



On 05/05/2016 06:35 PM, Joseph Myers wrote:
> On Thu, 5 May 2016, Paul E. Murphy wrote:
>> For the initial support, I want to focus on math.h. I suggest the
>> following should be the minimal set of libm/c functions required to
>> enable a new TS 18661-3 type:
>>
>> copysign modf scalbn frexp ldexp sin cos ceil erf expm1 fabs
>> floor log1p logb nextafter rint scalbln tan tanh fmax fmin fdim trunc
>> remquo round lround llround nextup nextdown acos acosh asin asinh
>> atan2 atanh cosh exp exp10 fmod hypot log log2 log10 pow scalbn ilogb
>> exp2 lgamma_r lgamma
> 
> I don't know where this list came from, but it's missing, for example, 
> sinh and remainder.
> 
> In the case of remainder, one of the many preparatory patches would be to 
> change the documentation to express that remainder is the primary name and 
> drem is a legacy alias, since it presently describes drem as the main 
> name.  (drem should *not* get a dremf128 version, remainderf128 is 
> sufficient.)
> 
> I think the starting point is:
> 
> * All functions that both (a) exist for long double in glibc at present, 
> and (b) exist for _Float128 in TS 18661-3, should have versions for 
> _Float128.  This includes the <complex.h> functions, which you omitted 
> from your list (and <tgmath.h> support would be updated for both real and 
> complex functions).  (Some preparatory changes would refactor the existing 
> complex function implementations so that float / double / long double 
> share most of the code, included with different macros defined.  This is 
> the sort of thing that's a good idea anyway, independent of adding new 
> types, simply to make the functions easier to maintain.)

Admittedly, the list was my imperfect attempt to list those functions
which TS 18661-3 declares for which there is a mathematically equivalent
long double function already implemented in libm,.

Likewise, we should implement those which diverge from the base C11
standard in an attempt to improve the removed function. Such functions
may demand more discussion. Anyhow, str{to,from} and their GNU
derivatives must be included with the preliminary support. Likewise
for next{up,down}.

Do you think it is beneficial to exhaustively list each function? 

I intentionally omitted tgmath and complex as I view them as an isolated
chunk of work at this time. They broaden the the scope of the initial
work too much.

I hope to gain consensus that the additions to math.h and stdlib.h,
and their respective ABI in lib{c,m} is sufficient for initial
support of TS 18661.

Likewise, that we can defer work on complex and tgmath while we work
on the base enablement.

> 
> * All functions that exist for long double in glibc at present, but do not 
> exist for _Float128 in TS 18661-3, need a careful analysis.  Some should 
> be added for _Float128 (e.g. lgammaf128_r, strtof128_l, as in your list, 
> and the Bessel functions, missing from your list).  Some should not (e.g. 
> legacy aliases such as drem and gamma should not get _Float128 versions; 
> nor should other legacy functions such as scalb even though they would 
> need versions added to support it as an alternative long double type).
> 
> * The minimum set of new functions from TS 18661-1 that should be added to 
> get _Float128 versions is, I think, nextup nextdown strfrom (all on your 
> list).  Of course that means earlier patches in the series would add such 
> functions (with test coverage, documentation etc.) for all existing 
> floating-point types / formats on all architectures, before the _Float128 
> versions are added later.  [Other functions that are new in TS 18661 can 
> be ignored.]
> 
> * Internal functions need careful consideration - but in general, a few 
> such functions as __isinff128 will need adding as backing for macros in 
> standard headers.  And where we have __*l_finite, I think consistency 
> probably means adding __*f128_finite (and working out a clean way to 
> handle this in bits/math-finite.h).
> 
> * If a function is internal, or if its type involves some standard header 
> typedef, then in the case where __float128 and long double have the same 
> representation it should *not* get an additional ABI exported from the 
> shared libraries as an alias.
> 
> Working out the exact set of additions to the ABI and the API is the most 
> critical thing to get consensus on.
> 
>> #define __C11_GENEN(t,f)  \
>>            t: f,         \
>>   const    t: f,         \
>>   volatile t: f,         \
>>   volatile const t: f,
> 
> WG14 consensus is that qualifiers are not needed with _Generic (the 
> relevant type is always the unqualified type), so they should not be 
> included here.  If you want backwards compatibility with non-GCC compilers 
> predating that consensus, using unary + in the _Generic call is a much 
> less intrusive way of removing qualifiers.

That is an interesting observation.

> 
>> # if __GNUC_PREREQ (4,6) && !defined __SUPPORT_SNAN__                        \
>>      && !defined __OPTIMIZE_SIZE__
>> #  define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE,           \
>>      FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
>> # else
>> #  define fpclassify(x) _Generic( (x),                 \
> 
> You need to keep supporting compilers without _Generic (although you might 
> choose not to have type-generic macros support __float128 with such 
> compilers).

Is it possible to determine if a compiler supports it? GCC enabled some
C11 support in 4.6, but _Generic was added in 4.9. Anyhow, if my history
is correct, GCC supported __float128 in 4.8, so a third alternative is
needed anyways.

Where do we draw the line for TS 18661 support? Must the compiler support
_Generic and __STDC_IEC_60559_TYPES__ >= 201506L, or must it be a GCC
compiler of some minimum version when a user defines 
__STDC_WANT_IEC_60559_TYPES_EXT__?

Let's say glibc + GCC on a given platform supports a hypothetical _Float128
and _Float16 type, and exposes some subset of TS 18661 functionality for
both types. Someone attempts to use a compiler which only supports _Float128,
is there a standards compliant mechanism to prevent exposing the _Float16
machinery without including float.h?


>> My proposed design for source structure is:
>> * sysdeps/ieee754/f128/ holds all the __float128
>>   (e.g sysdeps/ieee754/f64x-ibm for a _Float64x type based off ibm128)
> 
> _Float64x cannot be based on ibm128; it must have IEEE semantics.  It 
> could be an alias for __float128, or for x86 extended (I don't see any 
> circumstances in which it would be anything else).
> 
>> * matherr and other legacy behavior should stick around.
>>   Why? This should enable trivial mapping between similar
>>   ldbl and f128 symbols, saving a little codespace.
> 
> I don't think it should be present for the new functions; that would mean 
> e.g. extending legacy __kernel_standard code, which otherwise could remain 
> untouched, to handle more types.  I think there's a strong case for 
> several of the preliminary patches to deal with deprecation of matherr and 
> setting up a new set of macroized wrappers that don't use 
> __kernel_standard but handle errno setting directly without reference to 
> _LIB_VERSION (on most architectures for existing types maybe they'd only 
> be used in static libm unless we decide to add new symbol versions for 
> many libm functions, for new architectures and new types they'd be used in 
> both shared and static libm).

Those macros only appear to be used by the wrapper functions, so
removing them for the new variants shouldn't be too convoluted without
adding too much bloat to the library?

> 
> Given appropriate obsoletion of matherr support for new binaries (meaning 
> matherr and _LIB_VERSION become compat symbols, so that in new links libm 
> will never refer to the program's copy of them), then of course future 
> support for long double on powerpc64le being __float128 would have the 
> long double functions not supporting matherr at all (this wouldn't be any 
> sort of problematic inconsistency between types for users, because no 
> newly linked program could use matherr for any type).

Would that require versioning all the existing wrappers? It might save
a little space on platforms with a binary128 ldbl. Though, such a change
sounds quite complex by itself.

> 
>> As for source, we should avoid duplication of non-trivial assets, and
>> that requires refactoring most of the ldbl-128 sources. I'd rather
>> not use Makefile/script tricks to generate the files. The only truly
>> ugly thing I've encountered thus far is using a macro to add the
>> correct suffix (L for long double, Q for __float128).
> 
> I think macros like that are indeed needed.  It's critical that the 
> conversion is scripted, as reviewability of the conversion will mean that 
> what's reviewed must be a small clean script that does the conversion and 
> maybe a small subsequent fix-up patch, not an enormous patch with massive 
> semi-automatic source changes which are effectively unreviewable.  (Of 
> course it should also be tested that such a conversion does not change the 
> generated code for some existing configuration using ldbl-128.)
> 
> There is one way in which the extent of macro use can be reduced.  Given 
> that we want to support these APIs, there's a clear case for them existing 
> on architectures where long double has binary128 representation, as 
> aliases for the long double functions (with the usual issues about 
> defining aliases between functions with incompatible types).  What that 
> indicates to me is:
> 
> * sysdeps/ieee754/float128 (for example) is the primary location of the 
> sources for these functions, whenever these functions are present.  It 
> defines e.g. __ieee754_<func>f128 or __<func>f128 (depending on the 
> function) as internal names, with appropriate *f128 aliases as exported 
> names.

Ideally, such a change seems sensible, but ultimately is it not a trivial
naming change which carries a more intensive verification?

Likewise, should these also expose appropriate *_finite symbols too? Or,
is such even permissible under this standard?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]