public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Resend: Potential upcoming changes in mangling to PowerPC GCC
@ 2022-08-04 17:48 Michael Meissner
  2022-08-04 20:53 ` Segher Boessenkool
  2022-08-10 19:55 ` Tulio Magno Quites Machado Filho
  0 siblings, 2 replies; 7+ messages in thread
From: Michael Meissner @ 2022-08-04 17:48 UTC (permalink / raw)
  To: GCC Development, Michael Meissner, Segher Boessenkool, Kewen.Lin,
	David Edelsohn, Peter Bergner, Will Schmidt, Jason Merrill,
	Nathan Sidwell, Mike Stump, Iain Sandoe, Joseph Myers,
	Tulio Magno Quites Machado Filho, Alan Modra, Nick Clifton,
	Jeff Law, Jakub Jelinek, Richard Biener, David S. Miller,
	Carlos O'Donell, libc-alpha

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Resend: Potential upcoming changes in mangling to PowerPC GCC
  2022-08-04 17:48 Resend: Potential upcoming changes in mangling to PowerPC GCC Michael Meissner
@ 2022-08-04 20:53 ` Segher Boessenkool
  2022-08-08 21:44   ` Michael Meissner
  2022-08-10 19:55 ` Tulio Magno Quites Machado Filho
  1 sibling, 1 reply; 7+ messages in thread
From: Segher Boessenkool @ 2022-08-04 20:53 UTC (permalink / raw)
  To: Michael Meissner, GCC Development, Kewen.Lin, David Edelsohn,
	Peter Bergner, Will Schmidt, Jason Merrill, Nathan Sidwell,
	Mike Stump, Iain Sandoe, Joseph Myers,
	Tulio Magno Quites Machado Filho, Alan Modra, Nick Clifton,
	Jeff Law, Jakub Jelinek, Richard Biener, David S. Miller,
	Carlos O'Donell, libc-alpha

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Resend: Potential upcoming changes in mangling to PowerPC GCC
  2022-08-04 20:53 ` Segher Boessenkool
@ 2022-08-08 21:44   ` Michael Meissner
  2022-08-10 17:14     ` Segher Boessenkool
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Meissner @ 2022-08-08 21:44 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Michael Meissner, GCC Development, Kewen.Lin, David Edelsohn,
	Peter Bergner, Will Schmidt, Jason Merrill, Nathan Sidwell,
	Mike Stump, Iain Sandoe, Joseph Myers,
	Tulio Magno Quites Machado Filho, Alan Modra, Nick Clifton,
	Jeff Law, Jakub Jelinek, Richard Biener, David S. Miller,
	Carlos O'Donell, libc-alpha

On Thu, Aug 04, 2022 at 03:53:55PM -0500, Segher Boessenkool wrote:
> 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.

Yes if we could go back 5 years it would have been simpler to do that way.  But
we are stuck with moving what we have forward.

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

I am saying right now, they are separate types when -mabi=ieeelongdouble is
used.  They are the same type when -mabi=ibmlongdouble is used.  I think they
should be the same type, no matter which way long double is defined.

But there are a bunch of assumptions within the compiler that need to be
changed due to these 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.

It isn't so simple, since as I've said in the past, it essentially will require
a gimple pass to determine that types are used to set the bits.  Right now,
because the bits are being set because of modes used, there are false
positives.  If you are volunteering to do the work go ahead.

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

My point is __ibm128 can potentionally be separate and always use IFmode.
Hence my question.

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

Of course, but I want to scope out the work.

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Resend: Potential upcoming changes in mangling to PowerPC GCC
  2022-08-08 21:44   ` Michael Meissner
@ 2022-08-10 17:14     ` Segher Boessenkool
  0 siblings, 0 replies; 7+ messages in thread
From: Segher Boessenkool @ 2022-08-10 17:14 UTC (permalink / raw)
  To: Michael Meissner, GCC Development, Kewen.Lin, David Edelsohn,
	Peter Bergner, Will Schmidt, Jason Merrill, Nathan Sidwell,
	Mike Stump, Iain Sandoe, Joseph Myers,
	Tulio Magno Quites Machado Filho, Alan Modra, Nick Clifton,
	Jeff Law, Jakub Jelinek, Richard Biener, David S. Miller,
	Carlos O'Donell, libc-alpha

On Mon, Aug 08, 2022 at 05:44:36PM -0400, Michael Meissner wrote:
> On Thu, Aug 04, 2022 at 03:53:55PM -0500, Segher Boessenkool wrote:
> > On Thu, Aug 04, 2022 at 01:48:51PM -0400, Michael Meissner wrote:
> > 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.
> 
> Yes if we could go back 5 years it would have been simpler to do that way.

It does not require time machines: we can change the current code *now*.

> > > 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?
> 
> I am saying right now, they are separate types when -mabi=ieeelongdouble is
> used.  They are the same type when -mabi=ibmlongdouble is used.  I think they
> should be the same type, no matter which way long double is defined.

Ah, good.

> But there are a bunch of assumptions within the compiler that need to be
> changed due to these 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.
> 
> It isn't so simple,

Yes it is.  It *is* a clear bug.

Solving it might be some work, but it has to be done, it can not be
avoided.

> > It cannot always use IFmode?  Generic code uses TFmode for long double
> > (which can be double-double).
> 
> My point is __ibm128 can potentionally be separate and always use IFmode.
> Hence my question.

It cannot be.  Generic code (on double-double configs) uses TFmode.

It is a good idea for us to use IFmode in the backend code, certainly.


Segher

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Resend: Potential upcoming changes in mangling to PowerPC GCC
  2022-08-04 17:48 Resend: Potential upcoming changes in mangling to PowerPC GCC Michael Meissner
  2022-08-04 20:53 ` Segher Boessenkool
@ 2022-08-10 19:55 ` Tulio Magno Quites Machado Filho
  2022-08-10 20:04   ` Segher Boessenkool
  1 sibling, 1 reply; 7+ messages in thread
From: Tulio Magno Quites Machado Filho @ 2022-08-10 19:55 UTC (permalink / raw)
  To: Michael Meissner via Gcc, GCC Development, Michael Meissner,
	Segher Boessenkool, Kewen.Lin, David Edelsohn, Peter Bergner,
	Will Schmidt, Jason Merrill, Nathan Sidwell, Mike Stump,
	Iain Sandoe, Joseph Myers, Alan Modra, Nick Clifton, Jeff Law,
	Jakub Jelinek, Richard Biener, David S. Miller,
	Carlos O'Donell, libc-alpha

Michael Meissner via Gcc <gcc@gcc.gnu.org> writes:

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

Does that mean, when long double is IEEE 128-bit, the compiler won't support
_Float128/__float128 ?

-- 
Tulio Magno

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Resend: Potential upcoming changes in mangling to PowerPC GCC
  2022-08-10 19:55 ` Tulio Magno Quites Machado Filho
@ 2022-08-10 20:04   ` Segher Boessenkool
  2022-08-10 21:38     ` Tulio Magno Quites Machado Filho
  0 siblings, 1 reply; 7+ messages in thread
From: Segher Boessenkool @ 2022-08-10 20:04 UTC (permalink / raw)
  To: Tulio Magno Quites Machado Filho
  Cc: Michael Meissner via Gcc, Michael Meissner, Kewen.Lin,
	David Edelsohn, Peter Bergner, Will Schmidt, Jason Merrill,
	Nathan Sidwell, Mike Stump, Iain Sandoe, Joseph Myers,
	Alan Modra, Nick Clifton, Jeff Law, Jakub Jelinek,
	Richard Biener, David S. Miller, Carlos O'Donell, libc-alpha

On Wed, Aug 10, 2022 at 04:55:42PM -0300, Tulio Magno Quites Machado Filho wrote:
> Michael Meissner via Gcc <gcc@gcc.gnu.org> writes:
> > 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; }
> 
> Does that mean, when long double is IEEE 128-bit, the compiler won't support
> _Float128/__float128 ?

You can write
	double convert (__ibm128  x) { return x; }
	double convert (__ieee128 x) { return x; }
as well.  "__ieee128" and "long double" are the same type then (and the
same as _Float128 and __float128 as well).


Segher

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Resend: Potential upcoming changes in mangling to PowerPC GCC
  2022-08-10 20:04   ` Segher Boessenkool
@ 2022-08-10 21:38     ` Tulio Magno Quites Machado Filho
  0 siblings, 0 replies; 7+ messages in thread
From: Tulio Magno Quites Machado Filho @ 2022-08-10 21:38 UTC (permalink / raw)
  To: Segher Boessenkool, Michael Meissner
  Cc: Jakub Jelinek, Michael Meissner via Gcc, Mike Stump, Iain Sandoe,
	Carlos O'Donell, libc-alpha, Alan Modra, Joseph Myers,
	David S. Miller, Jeff Law, Richard Biener, Nathan Sidwell

Segher Boessenkool <segher@kernel.crashing.org> writes:

> You can write
> 	double convert (__ibm128  x) { return x; }
> 	double convert (__ieee128 x) { return x; }
> as well.  "__ieee128" and "long double" are the same type then (and the
> same as _Float128 and __float128 as well).

Oh! I see.  Thanks!

Going back to Mike's original question:

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

In glibc, we use __ibm128 only once in a place that always has to be
double-double regardless of the long double type.
Everywhere else, when a double-double type is expected, long double is used.
This is also how glibc users are expected to use double-double functions from
glibc.

Meanwhile, _Float128/_float128 is used everywhere along with long double,
regardless if long double is double-double or __float128.

With that said, glibc code was designed with this in mind (thanks Joseph!), but
AFAIK nobody ever tested building glibc for ppc64le with the proposal you have
here.

If this proposal is adopted, we'd need a way to distinguish between the previous
and the new behavior, i.e. a macro.

Anyway, I believe that a newer GCC will have trouble compiling on a
system with an older glibc.
An older glibc will also have trouble building with a newer GCC, but that might
be less important.

Likewise for libdfp.

-- 
Tulio Magno

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-08-10 21:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-04 17:48 Resend: Potential upcoming changes in mangling to PowerPC GCC Michael Meissner
2022-08-04 20:53 ` Segher Boessenkool
2022-08-08 21:44   ` Michael Meissner
2022-08-10 17:14     ` Segher Boessenkool
2022-08-10 19:55 ` Tulio Magno Quites Machado Filho
2022-08-10 20:04   ` Segher Boessenkool
2022-08-10 21:38     ` Tulio Magno Quites Machado Filho

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).