diff mbox series

rs6000: Fix mangling for 128-bit float

Message ID c181bb02acf87e7db4d94652aa7ae659433645e0.1527684557.git.segher@kernel.crashing.org
State New
Headers show
Series rs6000: Fix mangling for 128-bit float | expand

Commit Message

Segher Boessenkool May 30, 2018, 12:58 p.m. UTC
This patch changes the (C++) mangling of the 128-bit float types:

	__ieee128 becomes u9__ieee128
	__ibm128 becomes u8__ieee128
	__float128 is not a type anymore
	IEEE long double becomes u9__ieee128
	IBM long double stays g

This is a necessary ABI break.  It will need backporting to 8, too.

Bootstrapped and tested on powerpc64-linux {-m32,-m64} (Power7) and
on powerpc64le-linux (Power9).  Also tested manually; testsuite
patches will follow soon.

I'll commit this later today if nothing comes up.


Segher


2018-05-30  Segher Boessenkool  <segher@kernel.crashing.org>

	* config/rs6000/rs6000.c (rs6000_mangle_type): Change the mangling of
	the 128-bit floating point types.

---
 gcc/config/rs6000/rs6000.c | 27 +++++++++++----------------
 1 file changed, 11 insertions(+), 16 deletions(-)

Comments

Segher Boessenkool May 30, 2018, 1:07 p.m. UTC | #1
On Wed, May 30, 2018 at 12:58:49PM +0000, Segher Boessenkool wrote:
> This patch changes the (C++) mangling of the 128-bit float types:
> 
> 	__ieee128 becomes u9__ieee128
> 	__ibm128 becomes u8__ieee128

	__ibm128 becomes u8__ibm128
of course.

> 	__float128 is not a type anymore
> 	IEEE long double becomes u9__ieee128
> 	IBM long double stays g
> 
> This is a necessary ABI break.  It will need backporting to 8, too.
> 
> Bootstrapped and tested on powerpc64-linux {-m32,-m64} (Power7) and
> on powerpc64le-linux (Power9).  Also tested manually; testsuite
> patches will follow soon.
> 
> I'll commit this later today if nothing comes up.
> 
> 
> Segher
> 
> 
> 2018-05-30  Segher Boessenkool  <segher@kernel.crashing.org>
> 
> 	* config/rs6000/rs6000.c (rs6000_mangle_type): Change the mangling of
> 	the 128-bit floating point types.
> 
> ---
>  gcc/config/rs6000/rs6000.c | 27 +++++++++++----------------
>  1 file changed, 11 insertions(+), 16 deletions(-)
> 
> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index fab8ee3..f140816 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -32001,21 +32001,6 @@ rs6000_mangle_type (const_tree type)
>    if (type == bool_int_type_node) return "U6__booli";
>    if (type == bool_long_long_type_node) return "U6__boolx";
>  
> -  /* Use a unique name for __float128 rather than trying to use "e" or "g". Use
> -     "g" for IBM extended double, no matter whether it is long double (using
> -     -mabi=ibmlongdouble) or the distinct __ibm128 type.  */
> -  if (TARGET_FLOAT128_TYPE)
> -    {
> -      if (type == ieee128_float_type_node)
> -	return "U10__float128";
> -
> -      if (type == ibm128_float_type_node)
> -	return "u8__ibm128";
> -
> -      if (TARGET_LONG_DOUBLE_128 && type == long_double_type_node)
> -	return (TARGET_IEEEQUAD) ? "U10__float128" : "g";
> -    }
> -
>    /* Mangle IBM extended float long double as `g' (__float128) on
>       powerpc*-linux where long-double-64 previously was the default.  */
>    if (TYPE_MAIN_VARIANT (type) == long_double_type_node
> @@ -32024,7 +32009,17 @@ rs6000_mangle_type (const_tree type)
>        && !TARGET_IEEEQUAD)
>      return "g";
>  
> -  /* For all other types, use normal C++ mangling.  */
> +  if (TARGET_FLOAT128_TYPE)
> +    {
> +      if (type == ieee128_float_type_node
> +          || (type == long_double_type_node && TARGET_LONG_DOUBLE_128))
> +	return "u9__ieee128";
> +
> +      if (type == ibm128_float_type_node)
> +	return "u8__ibm128";
> +    }
> +
> +  /* For all other types, use the default mangling.  */
>    return NULL;
>  }
>  
> -- 
> 1.8.3.1
Jakub Jelinek May 30, 2018, 1:15 p.m. UTC | #2
On Wed, May 30, 2018 at 12:58:49PM +0000, Segher Boessenkool wrote:
> This patch changes the (C++) mangling of the 128-bit float types:
> 
> 	__ieee128 becomes u9__ieee128
> 	__ibm128 becomes u8__ieee128

^^^^^^ what is the advantage/reason for the above, rather than mangling it
as g?

> 	__float128 is not a type anymore
> 	IEEE long double becomes u9__ieee128
> 	IBM long double stays g

I mean, the above change will mean a significant burden e.g. on libstdc++,
when we have to export all symbols that refer to the
long double/__ieee128/__ibm128 types 4 times, once as aliases to symbols
with double instead (with the exception when there is no such double
symbol) using mangling e, then make sure libstdc++ files are all compiled
with long double equal to IBM to get the g mangling, then add aliases to
those for u8__ieee128 and finally build with __ieee128 or long double equal
to IEEE754 quad to get the u9__ieee128 mangling.
And besides libstdc++ on everything else that wants to achieve ABI
compatibility with both formats.

The above doesn't make long double distinct type from __ieee128 when it
is the same binary type anyway, so why should long double be distinct from
__ibm128 when long double is the same binary type as __ibm128?

If you need to keep g for compatibility (you do), then why not just have
e (long double is double)
g (long double when matching __ibm128, or explicit __ibm128)
u9__ieee128 (long double when matching __ieee128, or explicit __ieee128)

	Jakub
Segher Boessenkool May 30, 2018, 1:45 p.m. UTC | #3
On Wed, May 30, 2018 at 03:15:21PM +0200, Jakub Jelinek wrote:
> On Wed, May 30, 2018 at 12:58:49PM +0000, Segher Boessenkool wrote:
> > This patch changes the (C++) mangling of the 128-bit float types:
> > 
> > 	__ieee128 becomes u9__ieee128
> > 	__ibm128 becomes u8__ieee128
> 
> ^^^^^^ what is the advantage/reason for the above, rather than mangling it
> as g?
> 
> > 	__float128 is not a type anymore
> > 	IEEE long double becomes u9__ieee128
> > 	IBM long double stays g
> 
> I mean, the above change will mean a significant burden e.g. on libstdc++,
> when we have to export all symbols that refer to the
> long double/__ieee128/__ibm128 types 4 times, once as aliases to symbols
> with double instead (with the exception when there is no such double
> symbol) using mangling e, then make sure libstdc++ files are all compiled
> with long double equal to IBM to get the g mangling, then add aliases to
> those for u8__ieee128 and finally build with __ieee128 or long double equal
> to IEEE754 quad to get the u9__ieee128 mangling.
> And besides libstdc++ on everything else that wants to achieve ABI
> compatibility with both formats.
> 
> The above doesn't make long double distinct type from __ieee128 when it
> is the same binary type anyway, so why should long double be distinct from
> __ibm128 when long double is the same binary type as __ibm128?
> 
> If you need to keep g for compatibility (you do), then why not just have
> e (long double is double)
> g (long double when matching __ibm128, or explicit __ibm128)
> u9__ieee128 (long double when matching __ieee128, or explicit __ieee128)

"g" means __float128.  Which is __ieee128.  And it has to be, because
so much code expects that already, and it will only become more.  But
"g" is demangled as __float128.  Confusion galore.

We need to keep "g" mangling for compatibility, but over time everything
will default to quad precision long double so people will only see the
explicit __ibm128 anymore (if they use __ibm128 at all).

The plan is to have the compiler generate the aliases (g vs. u8__ibm128)
by itself, btw.


Segher
Jason Merrill May 30, 2018, 3:03 p.m. UTC | #4
On Wed, May 30, 2018 at 9:45 AM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> On Wed, May 30, 2018 at 03:15:21PM +0200, Jakub Jelinek wrote:
>> On Wed, May 30, 2018 at 12:58:49PM +0000, Segher Boessenkool wrote:
>> > This patch changes the (C++) mangling of the 128-bit float types:
>> >
>> >     __ieee128 becomes u9__ieee128
>> >     __ibm128 becomes u8__ieee128
>>
>> ^^^^^^ what is the advantage/reason for the above, rather than mangling it
>> as g?
>>
>> >     __float128 is not a type anymore
>> >     IEEE long double becomes u9__ieee128
>> >     IBM long double stays g
>>
>> I mean, the above change will mean a significant burden e.g. on libstdc++,
>> when we have to export all symbols that refer to the
>> long double/__ieee128/__ibm128 types 4 times, once as aliases to symbols
>> with double instead (with the exception when there is no such double
>> symbol) using mangling e, then make sure libstdc++ files are all compiled
>> with long double equal to IBM to get the g mangling, then add aliases to
>> those for u8__ieee128 and finally build with __ieee128 or long double equal
>> to IEEE754 quad to get the u9__ieee128 mangling.
>> And besides libstdc++ on everything else that wants to achieve ABI
>> compatibility with both formats.
>>
>> The above doesn't make long double distinct type from __ieee128 when it
>> is the same binary type anyway, so why should long double be distinct from
>> __ibm128 when long double is the same binary type as __ibm128?
>>
>> If you need to keep g for compatibility (you do), then why not just have
>> e (long double is double)
>> g (long double when matching __ibm128, or explicit __ibm128)
>> u9__ieee128 (long double when matching __ieee128, or explicit __ieee128)
>
> "g" means __float128.  Which is __ieee128.  And it has to be, because
> so much code expects that already, and it will only become more.  But
> "g" is demangled as __float128.  Confusion galore.
>
> We need to keep "g" mangling for compatibility, but over time everything
> will default to quad precision long double so people will only see the
> explicit __ibm128 anymore (if they use __ibm128 at all).
>
> The plan is to have the compiler generate the aliases (g vs. u8__ibm128)
> by itself, btw.

Then how about

e (long double is double)
u8__ibm128 (long double when matching __ibm128, or explicit __ibm128)
u9__ieee128 (long double when matching __ieee128, or explicit __ieee128)

and 'g' only in compatibility aliases?

Jason
Segher Boessenkool May 30, 2018, 3:32 p.m. UTC | #5
On Wed, May 30, 2018 at 11:03:39AM -0400, Jason Merrill wrote:
> On Wed, May 30, 2018 at 9:45 AM, Segher Boessenkool
> <segher@kernel.crashing.org> wrote:
> > On Wed, May 30, 2018 at 03:15:21PM +0200, Jakub Jelinek wrote:
> >> On Wed, May 30, 2018 at 12:58:49PM +0000, Segher Boessenkool wrote:
> >> > This patch changes the (C++) mangling of the 128-bit float types:
> >> >
> >> >     __ieee128 becomes u9__ieee128
> >> >     __ibm128 becomes u8__ieee128
> >>
> >> ^^^^^^ what is the advantage/reason for the above, rather than mangling it
> >> as g?
> >>
> >> >     __float128 is not a type anymore
> >> >     IEEE long double becomes u9__ieee128
> >> >     IBM long double stays g
> >>
> >> I mean, the above change will mean a significant burden e.g. on libstdc++,
> >> when we have to export all symbols that refer to the
> >> long double/__ieee128/__ibm128 types 4 times, once as aliases to symbols
> >> with double instead (with the exception when there is no such double
> >> symbol) using mangling e, then make sure libstdc++ files are all compiled
> >> with long double equal to IBM to get the g mangling, then add aliases to
> >> those for u8__ieee128 and finally build with __ieee128 or long double equal
> >> to IEEE754 quad to get the u9__ieee128 mangling.
> >> And besides libstdc++ on everything else that wants to achieve ABI
> >> compatibility with both formats.
> >>
> >> The above doesn't make long double distinct type from __ieee128 when it
> >> is the same binary type anyway, so why should long double be distinct from
> >> __ibm128 when long double is the same binary type as __ibm128?
> >>
> >> If you need to keep g for compatibility (you do), then why not just have
> >> e (long double is double)
> >> g (long double when matching __ibm128, or explicit __ibm128)
> >> u9__ieee128 (long double when matching __ieee128, or explicit __ieee128)
> >
> > "g" means __float128.  Which is __ieee128.  And it has to be, because
> > so much code expects that already, and it will only become more.  But
> > "g" is demangled as __float128.  Confusion galore.
> >
> > We need to keep "g" mangling for compatibility, but over time everything
> > will default to quad precision long double so people will only see the
> > explicit __ibm128 anymore (if they use __ibm128 at all).
> >
> > The plan is to have the compiler generate the aliases (g vs. u8__ibm128)
> > by itself, btw.
> 
> Then how about
> 
> e (long double is double)
> u8__ibm128 (long double when matching __ibm128, or explicit __ibm128)
> u9__ieee128 (long double when matching __ieee128, or explicit __ieee128)
> 
> and 'g' only in compatibility aliases?

Yes, but we can't switch to that until we have the aliases :-)

And we may not want to switch on (older) archs that cannot have ieee128
at all.


Segher
Jason Merrill May 30, 2018, 4:30 p.m. UTC | #6
On Wed, May 30, 2018 at 11:32 AM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> On Wed, May 30, 2018 at 11:03:39AM -0400, Jason Merrill wrote:
>> On Wed, May 30, 2018 at 9:45 AM, Segher Boessenkool
>> <segher@kernel.crashing.org> wrote:
>> > On Wed, May 30, 2018 at 03:15:21PM +0200, Jakub Jelinek wrote:
>> >> On Wed, May 30, 2018 at 12:58:49PM +0000, Segher Boessenkool wrote:
>> >> > This patch changes the (C++) mangling of the 128-bit float types:
>> >> >
>> >> >     __ieee128 becomes u9__ieee128
>> >> >     __ibm128 becomes u8__ieee128
>> >>
>> >> ^^^^^^ what is the advantage/reason for the above, rather than mangling it
>> >> as g?
>> >>
>> >> >     __float128 is not a type anymore
>> >> >     IEEE long double becomes u9__ieee128
>> >> >     IBM long double stays g
>> >>
>> >> I mean, the above change will mean a significant burden e.g. on libstdc++,
>> >> when we have to export all symbols that refer to the
>> >> long double/__ieee128/__ibm128 types 4 times, once as aliases to symbols
>> >> with double instead (with the exception when there is no such double
>> >> symbol) using mangling e, then make sure libstdc++ files are all compiled
>> >> with long double equal to IBM to get the g mangling, then add aliases to
>> >> those for u8__ieee128 and finally build with __ieee128 or long double equal
>> >> to IEEE754 quad to get the u9__ieee128 mangling.
>> >> And besides libstdc++ on everything else that wants to achieve ABI
>> >> compatibility with both formats.
>> >>
>> >> The above doesn't make long double distinct type from __ieee128 when it
>> >> is the same binary type anyway, so why should long double be distinct from
>> >> __ibm128 when long double is the same binary type as __ibm128?
>> >>
>> >> If you need to keep g for compatibility (you do), then why not just have
>> >> e (long double is double)
>> >> g (long double when matching __ibm128, or explicit __ibm128)
>> >> u9__ieee128 (long double when matching __ieee128, or explicit __ieee128)
>> >
>> > "g" means __float128.  Which is __ieee128.  And it has to be, because
>> > so much code expects that already, and it will only become more.  But
>> > "g" is demangled as __float128.  Confusion galore.
>> >
>> > We need to keep "g" mangling for compatibility, but over time everything
>> > will default to quad precision long double so people will only see the
>> > explicit __ibm128 anymore (if they use __ibm128 at all).
>> >
>> > The plan is to have the compiler generate the aliases (g vs. u8__ibm128)
>> > by itself, btw.
>>
>> Then how about
>>
>> e (long double is double)
>> u8__ibm128 (long double when matching __ibm128, or explicit __ibm128)
>> u9__ieee128 (long double when matching __ieee128, or explicit __ieee128)
>>
>> and 'g' only in compatibility aliases?
>
> Yes, but we can't switch to that until we have the aliases :-)

> And we may not want to switch on (older) archs that cannot have ieee128
> at all.

Sure.  But they can continue to be the same type, and therefore use
the same mangling, whichever mangling that is.  :)

Jason
Jakub Jelinek May 30, 2018, 4:43 p.m. UTC | #7
On Wed, May 30, 2018 at 08:45:22AM -0500, Segher Boessenkool wrote:
> > If you need to keep g for compatibility (you do), then why not just have
> > e (long double is double)
> > g (long double when matching __ibm128, or explicit __ibm128)
> > u9__ieee128 (long double when matching __ieee128, or explicit __ieee128)
> 
> "g" means __float128.  Which is __ieee128.  And it has to be, because
> so much code expects that already, and it will only become more.  But
> "g" is demangled as __float128.  Confusion galore.

Is that such a big deal?  It hasn't been a problem in the past decade when
it was similarly wrong too.  And, with the intent to phase out long double
as __ibm128 (at least on powerpc64le) shortly only libstdc++ and perhaps a
couple of other libraries will have this demangling glitch (and those will
have it in any case, because there will be the compatibility aliases that
will demangle as __float128).  So I really don't see any advantages of
changing the __ibm128 and/or long double that is __ibm128 mangling from
g to something else.  But I see severe disadvantages.

The libstdc++ changes to support both __ibm128 and __ieee128 will be very
hard themselves, there is no need to complicate it further.

	Jakub
Segher Boessenkool May 31, 2018, 7:20 p.m. UTC | #8
On Wed, May 30, 2018 at 06:43:23PM +0200, Jakub Jelinek wrote:
> On Wed, May 30, 2018 at 08:45:22AM -0500, Segher Boessenkool wrote:
> > > If you need to keep g for compatibility (you do), then why not just have
> > > e (long double is double)
> > > g (long double when matching __ibm128, or explicit __ibm128)
> > > u9__ieee128 (long double when matching __ieee128, or explicit __ieee128)
> > 
> > "g" means __float128.  Which is __ieee128.  And it has to be, because
> > so much code expects that already, and it will only become more.  But
> > "g" is demangled as __float128.  Confusion galore.
> 
> Is that such a big deal?  It hasn't been a problem in the past decade when
> it was similarly wrong too.  And, with the intent to phase out long double
> as __ibm128 (at least on powerpc64le) shortly only libstdc++ and perhaps a
> couple of other libraries will have this demangling glitch (and those will
> have it in any case, because there will be the compatibility aliases that
> will demangle as __float128).  So I really don't see any advantages of
> changing the __ibm128 and/or long double that is __ibm128 mangling from
> g to something else.  But I see severe disadvantages.
> 
> The libstdc++ changes to support both __ibm128 and __ieee128 will be very
> hard themselves, there is no need to complicate it further.

We're running some tests now with "g" mangling for everything double-double
(and u9__ieee128 for everything IEEE quad-precision float).

We think it will all work out, certainly for systems where double-double
in the future is just a bad memory (and for other systems the problems
are nothing new).

Thanks to you all for all the input,


Segher
diff mbox series

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index fab8ee3..f140816 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -32001,21 +32001,6 @@  rs6000_mangle_type (const_tree type)
   if (type == bool_int_type_node) return "U6__booli";
   if (type == bool_long_long_type_node) return "U6__boolx";
 
-  /* Use a unique name for __float128 rather than trying to use "e" or "g". Use
-     "g" for IBM extended double, no matter whether it is long double (using
-     -mabi=ibmlongdouble) or the distinct __ibm128 type.  */
-  if (TARGET_FLOAT128_TYPE)
-    {
-      if (type == ieee128_float_type_node)
-	return "U10__float128";
-
-      if (type == ibm128_float_type_node)
-	return "u8__ibm128";
-
-      if (TARGET_LONG_DOUBLE_128 && type == long_double_type_node)
-	return (TARGET_IEEEQUAD) ? "U10__float128" : "g";
-    }
-
   /* Mangle IBM extended float long double as `g' (__float128) on
      powerpc*-linux where long-double-64 previously was the default.  */
   if (TYPE_MAIN_VARIANT (type) == long_double_type_node
@@ -32024,7 +32009,17 @@  rs6000_mangle_type (const_tree type)
       && !TARGET_IEEEQUAD)
     return "g";
 
-  /* For all other types, use normal C++ mangling.  */
+  if (TARGET_FLOAT128_TYPE)
+    {
+      if (type == ieee128_float_type_node
+          || (type == long_double_type_node && TARGET_LONG_DOUBLE_128))
+	return "u9__ieee128";
+
+      if (type == ibm128_float_type_node)
+	return "u8__ibm128";
+    }
+
+  /* For all other types, use the default mangling.  */
   return NULL;
 }