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