On Thu, Mar 09, 2023 at 05:14:11PM +0000, Richard Sandiford wrote: > We decided to keep the current mangling of __bf16 and use it for > std::bfloat16_t too. __bf16 will become a non-standard arithmetic type. > This will be an explicit diversion from the Itanium ABI. > > I think that's equivalent to your (2) without the part about following > the Itanium ABI.
I'm afraid I have no idea how can the above work though. Diversion from the Itanium ABI is doable, we have various examples where we mangle things differently, say on powerpc* where long double is mangled as g if it is IBM double double format (i.e. Itanium __float128) while for long double the spec says e, and as u9__ieee128 if it is IEEE quad. __float128 also mangles as u9__ieee128 and so does __ieee128. The problem is if __bf16 needs to be treated differently from decltype (0.0bf16) aka std::bfloat16_t (the former being a non-standard arithmetic type, the latter being C++23 extended floating-point type, then they need to be distinct types. And distinct types need to mangle differently. Consider #include <stdfloat> template <typename T> void bar () {} void baz () { bar<__bf16> (); bar<decltype (0.0bf16)> (); bar<std::bfloat16_t> (); } If __bf16 is distinct from the latter two which are the same type, then it will instantiate bar twice, for both of those types, but if they are mangled the same, will emit two functions with the same name and assembler will reject it (or LTO might ICE etc.). Note, e.g. void foo (__float128, __ieee128, long double, _Float128) {} template <typename T> void bar () {} void baz () { bar <__float128> (); bar <__ieee128> (); bar <long double> (); } works on powerpc64le-linux with -mlong-double-128 -mabi=ieeelongdouble because __float128, __ieee128 and long double types are in that case the same type, not distinct, so e.g. bar is instantiated just once (only _Float128 mangles differently above). With -mlong-double-128 -mabi=ibmlongdouble __float128 and __ieee128 are the same (non-standard) type, while long double mangles differently (g) and _Float128 too, so bar is instantiated twice. So, either __bf16 should be also extended floating-point type like decltype (0.0bf16) and std::bfloat16_t and in that case it is fine if it mangles u6__bf16, or __bf16 will be a distinct type from the latter two, __bf16 non-standard arithmetic type while the latter two extended floating-point types, but then they need to mangle differently, most likely u6__bf16 vs. DF16b. Jakub