Resend: Potential upcoming changes in mangling to PowerPC GCC
Segher Boessenkool
segher@kernel.crashing.org
Thu Aug 4 20:53:55 GMT 2022
Hi!
On Thu, Aug 04, 2022 at 01:48:51PM -0400, Michael Meissner wrote:
> At the moment, GCC 12 on the server PowerPC systems supports multiple 128-bit
> floating point types:
>
> * _Float128 (in the C language): IEEE 128-bit floating point;
>
> * __float128 (in the C and C++ languages): IEEE 128-bit floating point;
>
> * long double: One of IEEE 128-bit floating, IBM 128-bit floating point,
> or 64-bit floating point; (and)
>
> * __ibm128: Explicit IBM 128-bit floating point.
And __ieee128, which (unlike __float128) explicitly is IEEE QP float
(and as a bonus that is obvious in every context, too).
> If a file is compiled when long double uses the IEEE 128-bit floating point
> type, then the __float128 type is the long double type and it uses the TFmode
> mode. And while the _Float128 type is distinct from long double, it also uses
> TFmode. The __ibm128 type is distinct, and it uses IFmode.
It would be a lot simpler and less roundabout and inside out if we could
do this the other way around: start with the QP float and double-double
types and modes, and point the long double type and TFmode at that. But
alas.
> While things mostly work with this setup, there are some things that don't work
> as well. For example, 3 of the tests fail when you are using a system like
> Fedora 36 where IEEE 128-bit long double is default. These 3 tests use the
> 'nanqs' built-in function, which is mapped to 'nanf128s' and it delivers a
> _Float128 signaling NaN. But since __float128 uses a different type, the
> signaling NaN is converted and it loses the signaling property.
So you are saying __float128 and _Float128 should *not* be separate
types? Or, the testcases are buggy, make unwarranted assumptions?
> In addition, it would be nice if we could refine the setting of bits in the ELF
> header so that if you pass an explicit __float128 or __ibm128 object, it
> doesn't set the bits that you used long double of the appropriate type. But
> the code that sets these bits is done in the RTL stages, and it only looks at
> modes, not at types.
So fix that? It is a clear bug.
> Now, I'm working on patches to 'do the right thing':
>
> * Make _Float128 and __float128 always use the same distinct type and
> always use KFmode;
>
> * Make __ibm128 use a distinct type and always use IFmode; (and)
It cannot always use IFmode? Generic code uses TFmode for long double
(which can be double-double).
> Because long double mangles the same as either __float128 or __ibm128, you
> cannot write programs like:
>
> double convert (__ibm128 x) { return x; }
> double convert (__float128 x) { return x; }
> double convert (long double x) { return x; }
I proposed separate mangling for long double, all those years ago, but
long double is the same type as either __ibm128 or __ieee128, always.
Mangling it differently only causes huge complications and it solves
nothing.
> At the moment, the mangling rules are:
>
> * If the type uses the IBM 128-bit encoding, use "g" for mangling;
>
> * If the type uses the IEEE 128-bit encoding, use "u9__ieee128" for
> mangling.
>
> I would suggest at least adding the rule:
>
> * If the type is explicitly __ibm128, use "u8__ibm128" for the mangling,
> and if it is long double that uses the IBM 128-bit encoding, continue
> to use "g" for the mangling.
That is wrong. The same type should mangle the same in all cases.
> But in changing the mangling, we have the potential to create compatibility
> issues,
s/potential to/surety this will/
Please open PRs for the broken testcases (one for each, unless of course
you are confident they are the same problems: it is much easier to join
PRs than to split them).
Segher
More information about the Libc-alpha
mailing list