Resend: Potential upcoming changes in mangling to PowerPC GCC

Michael Meissner meissner@linux.ibm.com
Thu Aug 4 17:48:51 GMT 2022


This is the same message I sent out before.  I'm resending it to include
libc-alpha@sourceware.org in the To: list.

Sorry for the scatter shot mail that covers C++, Objective C++, Glibc,
etc. developers, but I wanted to discuss and get buy-in on changes to the
PowerPC GCC compiler that I would like to do in the endless project of
supporting IEEE 128-bit floating point.  Sorry if I spammed your inbox if this
doesn't concern you.

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 there are 3 modes:

    *	KFmode: IEEE 128-bit floating point;
    *	IFmode: IBM 128-bit floating point; (and)
    *	TFmode: Either IEEE 128-bit or IBM 128-bit floating point.

But internally within the compiler there are mostly only two separate types, an
IEEE 128-bit and IBM 128-bit floating point.

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.

If a file is compiled when long double uses IBM 128-bit floating point, then
the __float128 type uses the _Float128 type, and both types use KFmode.  The
__ibm128 type uses the long double type, and both types use TFmode.

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.  The tests that
fail are:

    *	gcc.dg/torture/float128-nan.c
    *	gcc.target/powerpc/nan128-1.c
    *	gcc.target/powerpc/pr105334.c

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.

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)

    *	Long double would not share an internal type with either _Float128,
	__float128, or __ibm128.  It would always use TFmode.

One of the issues that comes up is the mangling support.  I wanted to get
buy-in on the solutions from the affected users:

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; }

You would have to write on a system with long double being IBM 128-bit:

	double convert (__float128  x) { return x; }
	double convert (long double x) { return x; }

or on a system with long double being IEEE 128-bit:

	double convert (__ibm128    x) { return x; }
	double convert (long double x) { return x; }

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.  This shows up in the test suite
	g++.target/powerpc/pr85657.C.

We probably should think about the reverse case of separating explict
__float128 from long double that happens to use the IEEE 128-bit encoding.  I
suspect the right solution is to change the mangling on __float128 and leave
long double alone.  If so, any ideas on the mangling we should use?  Perhaps we
should use "DF128" which is the mangling for ISO/IEC TS 18661 _Float<N> type.

But in changing the mangling, we have the potential to create compatibility
issues, of code compiled with previous GCC's that use explicit __ibm128 and
__float128 keywords.  I don't how the users of these keywords (i.e. typically
libstdc++ and glibc developers, but potentially others as well).

-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: meissner@linux.ibm.com


More information about the Libc-alpha mailing list