On Wed, Sep 09, 2020 at 02:42:36PM +0100, Jonathan Wakely wrote: > Sorry for the slow reply to this. > > On Fri, 7 Aug 2020 at 22:14, Michael Meissner <meiss...@linux.ibm.com> wrote: > > > > One issue with doing the transition is what mangling should be used with the > > new long double. > > > > At the moment, the current mangling is: > > long double "g" > > __float128 "u9__ieee128" > > __ibm128 "g" > > > > Obviously this will have to change in the future. It is unfortunate that we > > choose "g" to mean IBM extended double many many years ago, when it should > > have > > been used for IEEE 128-bit floating point. But that is long ago, so I > > think we > > need to keep it. > > > > But assuming we want compatibility with libraries like glibc and libstdc++, > > I > > think we will have to continue to use "g" for __ibm128. > > > > With the long double change, I tend to view this as an ABI change. But if > > the > > user doesn't use long double, they should be able to link without changes. > > > > I would propose using a new mangling for IEEE 128-bit long double. I would > > prefer to get agreement on what the new mangling should be so we don't have > > an > > issue like we had in GCC 8.1 going to GCC 8.2, where we changed the > > mangling, > > and had to provide aliases for the old name. > > > > At the moment I think the mangling should be: > > long double "g" if long double is IBM > > long double "u12_ieee128_ld" if long double is IEEE > > __float128 "u9__ieee128" > > __ibm128 "g" > > What's the benefit of having __float128 and IEEE long double be > distinct types? That complicates things for libraries like libstdc++. > If we want to support using "__float128" with C++ iostreams then we > need yet another set of I/O routines, even though it's identical to > one of the types we already handle. Why not just keep __float128 and > __ieee128 and "long double when long double is IEEE" as three > different aliases for the same type, so that C++ code like > _Z4funcu9__ieee128 works for all of them, instead of needing to also > define _Z4funcu12__ieee128_ld?
The Boost library has methods that have both long double and __float128 in it. My main concern is not to break user code like Boost that the users may added __float128. Obviously with glibc and libstdc++ we have people who understand the issues, but who knows what other libraries people have come up with. So if we configure long double to be IEEE 128-bit, under the current code it would be an error. Consider this silly code. Yes it likely would be a template, but the issue is if the user mixes __float128 and long double, is it an error if long double has the same representation as IEEE 128-bit: class foo { public: double add (double a, double b) { return a+b; } long double add (long double a, long double b) { return a+b; } __float128 add (__float128 a, __float128 b) { return a+b; } }; foo x; __float128 bletch_f128 (__float128 a, __float128 b) { return x.add (a, b); } long double bletch_ld (long double a, long double b) { return x.add (a, b); } If we compile this with the current compiler, it compiles fine if long double uses the IBM extended double. But if we compile it with -Wno-psabi -mabi=ieeelongdouble, we get: In file included from foo-class.cpp:1: foo-class.h:5:14: error: ‘long double foo::add(long double, long double)’ cannot be overloaded with ‘long double foo::add(long double, long double)’ 5 | __float128 add (__float128 a, __float128 b) { return a+b; } | ^~~ foo-class.h:4:15: note: previous declaration ‘long double foo::add(long double, long double)’ 4 | long double add (long double a, long double b) { return a+b; } | ^~~ Because right now the compiler only has two types, whatever long double is, and whatever is not long double. You have the same issue right now with __ibm128 and the current long double, but I'm not convinced anybody outside of glibc and libstdc++ really uses it. Since people do use __float128, since the x86_64 port supports it, it is an issue. If you use the -mlong-double-128 option on the X86_64 compiler, you get an error, though in this case it is a more cryptic error message (compiler used was a 10.2 compiler): foo-class.cpp:15:1: error: Two symbols with same comdat_group are not linked by the same_comdat_group list. 15 | } | ^ _ZN3foo3addEgg/2 (__float128 foo::add(__float128, __float128)) @0x7f0068b922d0 Type: function definition analyzed Visibility: public weak comdat comdat_group:_ZN3foo3addEgg one_only previous sharing asm name: 1 References: Referring: Function flags: body Called by: _Z7bletch1gg/4 Calls: _ZN3foo3addEgg/1 (long double foo::add(long double, long double)) @0x7f0068b92168 Type: function definition analyzed Visibility: public weak comdat comdat_group:_ZN3foo3addEgg one_only next sharing asm name: 2 References: Referring: Function flags: body Called by: _Z7bletch2gg/5 Calls: foo-class.cpp:15:1: internal compiler error: symtab_node::verify failed 0xb9f9d9 symtab_node::verify_symtab_nodes() /home/meissner/fsf-src/gcc-10.2.0/gcc/symtab.c:1354 0xbb2444 symtab_node::checking_verify_symtab_nodes() /home/meissner/fsf-src/gcc-10.2.0/gcc/cgraph.h:667 0xbb2444 symbol_table::compile() /home/meissner/fsf-src/gcc-10.2.0/gcc/cgraphunit.c:2738 0xbb450c symbol_table::compile() /home/meissner/fsf-src/gcc-10.2.0/gcc/cgraphunit.c:2735 0xbb450c symbol_table::finalize_compilation_unit() /home/meissner/fsf-src/gcc-10.2.0/gcc/cgraphunit. > What about the "__ieee128" type, would that be mangled as > "u12_ieee128_ld" or "u9__ieee128"? Please use __float128 and not __ieee128 in public code. The user visible keyword is __float128, not __ieee128. Internally within the compiler, the real keyword is __ieee128, and there is a macro '__float128'. This uglyness was needed in previous compilers to allow disabling __float128 as a public keyword, but to allow the libraries to still use it (due to Boost's usage of __float128). -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797