Message ID | c181bb02acf87e7db4d94652aa7ae659433645e0.1527684557.git.segher@kernel.crashing.org |
---|---|
State | New |
Headers | show |
Series | rs6000: Fix mangling for 128-bit float | expand |
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
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
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
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
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
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
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
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 --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; }