Hi! On powerpc64le-linux target, one can select between two incompatible long double formats (both of them are 16-byte), __ibm128 which is a sum of two doubles, and __float128 (note, not implemented through libquadmath), which is IEEE754 quad format. The default for long double can be selected with --with-long-double-format={ieee,ibm} configure options. AFAIK no distributions switched to --with-long-double-format=ieee yet (correct me if I'm wrong), but the goal is that eventually all distros switch to that (like they've switched from the --with-long-double-64 default to --with-long-double-128 on powerpc64-linux, s390*-linux etc. years ago).
libstdc++ has been changed already last year, so that the same libstdc++.so.6 is ABI compatible with both configurations, in C++ the IEEE quad long double mangles differently from IBM double double long double and so it is possible (with quite some work) to achieve that. Other C++ libraries not shipped as part of gcc are either lucky and don't use long double on any of its public APIs, then they are compatible with both, or developers can go the same painful way and support both ABIs in the same shared library, or they are simply ABI incompatible. But, I believe --with-long-double-format={ieee,ibm} configure time choice doesn't change just the meaning of long double, but also of real(kind=16) and complex(kind=32), but Fortran name mangling just appends _ and doesn't encode types. So, the choices for libgfortran.so.5 are either don't do anything, then we have from GCC the same SONAME but based on what --with-long-double-format={ieee,ibm} distributions choose ABI incompatible libraries, or bump libgfortran SONAME in GCC 12 on all targets (the problem is that it unnecessarily changes the SONAME even on targets that don't really need it - unless there are important ABI changes in the queue for GCC 12 already), but that to be effective would basically require that all distros change to --with-long-double-format=ieee together with GCC 12, or change the SONAME only on powerpc64le somehow (still the problem that all distros have to change at once), or add some kind=16 suffix letter into the SONAME if configured --with-long-double-format=ieee (so we'd have libgfortran.so.5ieee or whatever, and when we'd bump to libgfortran.so.6 on all arches libgfortran.so.6ieee etc.). Or the last option would be to try to make libgfortran.so.5 ABI compatible with both choices on powerpc64le-linux. From quick skimming of libgfortran, we have lots of generated functions, which use HAVE_GFC_REAL_16 and GFC_REAL_16 etc. macros. So, we could perhaps arrange for the compiler to use r16i or r17 instead of r16 in the names when real(kind=16) is the IEEE quad on powerpc64le and keep using r16 for the IBM double double. For the *.F90 generated files, one could achieve it by making sure the *r16* files are compiled with -mabi=ibmlongdouble, for *r16i* or *r17* with -mabi=ieeelongdouble and otherwise use kind=16 in those, for *.c generated files the *GFC_* macros could just ensure that it doesn't use long double but __ibm128 or __float128 depending on which one is needed. But then I see e.g. the io routines to just pass in kind and so switch (kind) // or len { case ...: *(GFC_REAL_*) = ...; } etc. Could we just pretend in the compiler to libgfortran ABI that powerpc64le-linux real(kind=16) is kind 17 and make sure that if anything would actually think it is 17 bytes it uses 16 instead (though, kind=10 on x86-64 or i686 also isn't 10 bytes but 16 or 12, right?). Your thoughts on this? Jakub