Re: [power-iee128] How to specify linker flags
On Sun, Jan 02, 2022 at 11:58:29PM +0100, Thomas Koenig wrote: > Hi Michael, > > > If you are building libraries that contain modules with multiple long double > > types, you must use the '-mno-gnu-attribute'. We also use the '-Wno-psabi' > > option, which silences the warning that you are switching long double types > > (if > > glibc is not 2.34 or newer). We may need to tweak -Wno-psabi for use with > > Fortran. > > I am now at the point where the object files are also compiled correctly > for the gfortran specifics: > > <_gfortran_specific__abs_r17>: >0: 09 00 43 f4 lxv vs34,0(r3) >4: 48 16 40 fc xsabsqp v2,v2 >8: 20 00 80 4e blr > > However, the linker complains, as you said it would, about the different > formats: > > /opt/at15.0/bin/ld: .libs/maxloc0_4_r16.o uses IBM long double, > .libs/_abs_r17.o uses IEEE long double > /opt/at15.0/bin/ld: failed to merge target specific data of file > .libs/_abs_r17.o > > I know next to nothing about libtool, so I do not know how to > add the flags so the linker can find them. > > Any pointers? > > (I have not yet committed the changes because I do not want to > commit something that does not compile. If anybody wants to > take a look, it's on the ieee128 virtual machine under > /home/tkoenig/ieee ). I'm just getting back into things after being off-line for the winter holidays. As others have said, you need to use the GCC option -mno-gnu-attributes on any module that handles one of the long double types if you are building libraries that can handle both. Note, for C/C++ languages, you should add -Wno-psabi to the options as well as -mabi={ieee,ibm}longdouble. This suppresses the warning that says you are changing the long double type. If you have configred GCC against GLIBC 2.32 or newer, then you don't need the -Wno-psabi option. Unfortunately, you can't use -Wno-psabi on languages like Fortran. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [power-ieee128] libquadmath: Use -mno-gnu-attribute in libquadmath
On Mon, Jan 03, 2022 at 04:24:50PM +0100, Jakub Jelinek wrote: > Hi! > > Testing found that we also need libquadmath to be built with > -mno-gnu-attribute, otherwise -mabi=ieeelongdouble programs don't link. > > Ok for power-ieee128? > > 2022-01-03 Jakub Jelinek > > * configure.ac: Set XCFLAGS to -mno-gnu-attribute on > powerpc64le*-linux*. > * configure: Regenerated. I'm wondering whether we want to change things so that Fortran never uses long double on PowerPC, but instead it explicitly uses __float128 and __ibm128. But this breaks down in using printf/scanf, which don't have format options for those types. Unfortunately this won't work with the current code, since passing any of the 128-bit floating point types causes the flag 'rs6000_passes_long_double' to be set (and then the gnu attribute #4 is set). In theory, that should be set only if an explicit long double type is used. But the problem is when those things are set, you tend to only have modes and not types. To do it 'right', you probably need a GIMPLE pass that looks at the actual types used, not the modes. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [power-ieee128] RFH: LTO broken
On Tue, Jan 04, 2022 at 12:07:49PM +0100, Jakub Jelinek wrote: > On Mon, Jan 03, 2022 at 11:43:57PM +0100, Thomas Koenig wrote: > > > clearly there is still work to fix (but seems e.g. most of the lto tests > > > are related to the gnu attributes stuff:( ). > > > > This is looking better than what I expected. Apart from LTO, I expect > > I've just verified that LTO is broken even in C/C++, it isn't just gfortran. > Just do > make check-gcc RUNTESTFLAGS='--target_board=unix\{-mabi=ieeelongdouble\} > lto.exp' > on a system where gcc is configured to default to -mabi=ibmlongdouble > with glibc 2.32 or later and watch all the FAILs. > All the failures look like: > /home/jakub/gcc/obj/gcc/xgcc -B/home/jakub/gcc/obj/gcc/ c_lto_20081024_0.o > -mabi=ieeelongdouble -fdiagnostics-plain-output -O0 -flto > -flto-partition=none -o gcc- > dg-lto-20081024-01.exe > lto1: warning: Using IEEE extended precision 'long double' [-Wpsabi] > FAIL: gcc.dg/lto/20081024 c_lto_20081024_0.o-c_lto_20081024_0.o link, -O0 > -flto -flto-partition=none > > Michael, do you think you could have a look? Either it is the ELF object > created for debug info or the one created by lto1. > > Jakub > The problem is in rs6000_option_override_internal. I allowed C and C++ to change the long double format, but not other languages. I forgot that LTO is another front end. I have a patch to remove the checks for C/C++. I hope to validate it and send it out before the end of the night for me. Note, I have a day surgery tomorrow, and I will be offline for at least part of the day. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [power-ieee128] RFH: LTO broken
On Tue, Jan 04, 2022 at 12:07:49PM +0100, Jakub Jelinek wrote: > On Mon, Jan 03, 2022 at 11:43:57PM +0100, Thomas Koenig wrote: > > > clearly there is still work to fix (but seems e.g. most of the lto tests > > > are related to the gnu attributes stuff:( ). > > > > This is looking better than what I expected. Apart from LTO, I expect > > I've just verified that LTO is broken even in C/C++, it isn't just gfortran. > Just do > make check-gcc RUNTESTFLAGS='--target_board=unix\{-mabi=ieeelongdouble\} > lto.exp' > on a system where gcc is configured to default to -mabi=ibmlongdouble > with glibc 2.32 or later and watch all the FAILs. > All the failures look like: > /home/jakub/gcc/obj/gcc/xgcc -B/home/jakub/gcc/obj/gcc/ c_lto_20081024_0.o > -mabi=ieeelongdouble -fdiagnostics-plain-output -O0 -flto > -flto-partition=none -o gcc- > dg-lto-20081024-01.exe > lto1: warning: Using IEEE extended precision 'long double' [-Wpsabi] > FAIL: gcc.dg/lto/20081024 c_lto_20081024_0.o-c_lto_20081024_0.o link, -O0 > -flto -flto-partition=none > > Michael, do you think you could have a look? Either it is the ELF object > created for debug info or the one created by lto1. Here is the patch: | From 22b778e6ea951774df921a2a49c0cf75a2b512a3 Mon Sep 17 00:00:00 2001 | From: Michael Meissner | Date: Wed, 5 Jan 2022 22:23:19 -0500 | Subject: [PATCH] Allow other languages to change long double format. With Fortran adding support for changing the long double format, this patch removes the code that only allowed C/C++ to change the long double format for GLIBC 2.32 and later without a warning. gcc/ 2022-01-05 Michael Meissner * config/rs6000/rs6000.c (rs6000_option_override_internal): Remove checks for only C/C++ front ends before allowing the long double format to change without a warning. --- gcc/config/rs6000/rs6000.c | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 319182e94d9..0e3481c8327 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -4221,13 +4221,11 @@ rs6000_option_override_internal (bool global_init_p) if (rs6000_ieeequad != TARGET_IEEEQUAD_DEFAULT && TARGET_LONG_DOUBLE_128) { /* Determine if the user can change the default long double type at -compilation time. Only C and C++ support this, and you need GLIBC -2.32 or newer. Only issue one warning. */ +compilation time. You need GLIBC 2.32 or newer to be able to +change the long double type. Only issue one warning. */ static bool warned_change_long_double; - if (!warned_change_long_double - && (!glibc_supports_ieee_128bit () - || (!lang_GNU_C () && !lang_GNU_CXX ( + if (!warned_change_long_double && !glibc_supports_ieee_128bit ()) { warned_change_long_double = true; if (TARGET_IEEEQUAD) -- 2.33.1 -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [power-ieee128] RFH: LTO broken
On Tue, Jan 04, 2022 at 12:07:49PM +0100, Jakub Jelinek wrote: > On Mon, Jan 03, 2022 at 11:43:57PM +0100, Thomas Koenig wrote: > > > clearly there is still work to fix (but seems e.g. most of the lto tests > > > are related to the gnu attributes stuff:( ). > > > > This is looking better than what I expected. Apart from LTO, I expect > > I've just verified that LTO is broken even in C/C++, it isn't just gfortran. > Just do > make check-gcc RUNTESTFLAGS='--target_board=unix\{-mabi=ieeelongdouble\} > lto.exp' > on a system where gcc is configured to default to -mabi=ibmlongdouble > with glibc 2.32 or later and watch all the FAILs. > All the failures look like: > /home/jakub/gcc/obj/gcc/xgcc -B/home/jakub/gcc/obj/gcc/ c_lto_20081024_0.o > -mabi=ieeelongdouble -fdiagnostics-plain-output -O0 -flto > -flto-partition=none -o gcc- > dg-lto-20081024-01.exe > lto1: warning: Using IEEE extended precision 'long double' [-Wpsabi] > FAIL: gcc.dg/lto/20081024 c_lto_20081024_0.o-c_lto_20081024_0.o link, -O0 > -flto -flto-partition=none > > Michael, do you think you could have a look? Either it is the ELF object > created for debug info or the one created by lto1. I pushed the patch to the branch. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [power-ieee128] OPEN CONV
On Sat, Jan 08, 2022 at 03:18:07PM +0100, Jakub Jelinek wrote: > On Sat, Jan 08, 2022 at 03:13:10PM +0100, Thomas Koenig wrote: > > > > On 08.01.22 15:02, Jakub Jelinek via Fortran wrote: > > > Note, as for byteswapping, apparently it wasn't ever working right fox > > > the IBM extended real(kind=16) and complex(kind=16). > > > > The lack of bug reports since the conversion feature was introduced in > > 2006, more than 15 years ago, tells us something, I guess... > > powerpc64le was only introduced in GCC 4.8 in 2013, so slightly less > than that, but still. > Either nobody interchanges/shares fortran unformatted data between > powerpc big and little endian, or if they do, they don't use real(kind=16) > or complex(kind=16) in there... I still wish I had had the forethought when we were setting up the LE ABI to change the default 128-bit format to IEEE instead of IBM. But alas, I didn't. You would still need converters between the big endian IBM format and little endian IEEE format, but it would have avoided a lot of the problems where GCC assumes there is only one floating point format for each size. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [power-ieee128] OPEN CONV
On Sat, Jan 08, 2022 at 02:15:14PM -0500, David Edelsohn wrote: > On Sat, Jan 8, 2022 at 1:59 PM Michael Meissner > wrote: > > > > On Sat, Jan 08, 2022 at 03:18:07PM +0100, Jakub Jelinek wrote: > > > On Sat, Jan 08, 2022 at 03:13:10PM +0100, Thomas Koenig wrote: > > > > > > > > On 08.01.22 15:02, Jakub Jelinek via Fortran wrote: > > > > > Note, as for byteswapping, apparently it wasn't ever working right fox > > > > > the IBM extended real(kind=16) and complex(kind=16). > > > > > > > > The lack of bug reports since the conversion feature was introduced in > > > > 2006, more than 15 years ago, tells us something, I guess... > > > > > > powerpc64le was only introduced in GCC 4.8 in 2013, so slightly less > > > than that, but still. > > > Either nobody interchanges/shares fortran unformatted data between > > > powerpc big and little endian, or if they do, they don't use real(kind=16) > > > or complex(kind=16) in there... > > > > I still wish I had had the forethought when we were setting up the LE ABI to > > change the default 128-bit format to IEEE instead of IBM. But alas, I > > didn't. > > You would still need converters between the big endian IBM format and little > > endian IEEE format, but it would have avoided a lot of the problems where > > GCC > > assumes there is only one floating point format for each size. > > Mike, > > The LE ABI initial target was Power8 and IEEE128 hardware support was > added to Power9. The ABI was a conscious decision. IEEE 128 was not a > viable requirement for the LE ABI at the time of the transition. Yes I know, but my memory is we (the GCC group within IBM) at least knew that IEEE 128-bit was coming towards the end of the ABI definition period. But perhaps not. In any case, it doesn't much matter now, as it is all ancient history. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Fix Fortran rounding issues, PR fortran/96983.
Fix Fortran rounding issues, PR fortran/96983. I was looking at Fortran PR 96983, which fails on the PowerPC when trying to run the test PR96711.F90. The compiler ICEs because the PowerPC does not have a floating point type with a type precision of 128. The reason is that the PowerPC has 3 different 128 bit floating point types (__float128/_Float128, __ibm128, and long double). Currently long double uses the IBM extended double type, but we would like to switch to using IEEE 128-bit long doubles in the future. In order to prevent the compiler from converting explicit __ibm128 types to long double when long double uses the IEEE 128-bit representation, we have set up the precision for __ibm128 to be 128, long double to be 127, and __float128/_Float128 to be 126. Originally, I was trying to see if for Fortran, I could change the precision of long double to be 128 (Fortran doesn't access __ibm128), but it quickly became hard to get the changes to work. I looked at the Fortran code in build_round_expr, and I came to the conclusion that there is no reason to promote the floating point type. If you just do a normal round of the value using the current floating point format and then convert it to the integer type. We don't have an appropriate built-in function that provides the equivalent of llround for 128-bit integer types. This patch fixes the compiler crash. However, while with this patch, the PowerPC compiler will not crash when building the test case, it will not run on the current default installation. The failure is because the test is explicitly expecting 128-bit floating point to handle 10384593717069655257060992658440192_16 (i.e. 2**113). By default, the PowerPC uses IBM extended double used for 128-bit floating point. The IBM extended double format is a pair of doubles that provides more mantissa bits but does not grow the expoenent range. The value in the test is fine for IEEE 128-bit floating point, but it is too large for the PowerPC extended double setup. I have built the following tests with this patch: * I have built a bootstrap compiler on a little endian power9 Linux system with the default long double format (IBM extended double). The pr96711.f90 test builds, but it does not run due to the range of the real*16 exponent. There were no other regressions in the C/C++/Fortran tests. * I have built a bootstrap compiler on a little endian power9 Linux system with the default long double format set to IEEE 128-bit. I used the Advance Toolchain 14.0-2 to provide the IEEE 128-bits. The compiler was configured to build power9 code by default, so the test generated native power9 IEEE 128-bit instructions. The pr96711.f90 test builds and runs correctly in this setup. * I have built a bootstrap compiler on a big endian power8 Linux system with the default long double format (IBM extended double). Like the first case, the pr96711.f90 test does not crash the compiler, but the test fails due to the range of the real*16 exponent.There were no other regressions in the C/C++/Fortran tests. * I built a bootstrap compiler on my x86_64 laptop. There were no regressions in the tests. Can I check this change into the GCC trunk? I've not contributed to the Fortran front end before. If the maintainers like the patch, can somebody point out if I need to do additional things to commit the patch? gcc/fortran/ 2021-04-19 Michael Meissner PR gfortran/96983 * trans-intrinsic.c (build_round_expr): If int type is larger than long long, do the round and convert to the integer type. Do not try to find a floating point type the exact size of the integer type. --- gcc/fortran/trans-intrinsic.c | 26 -- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 5e53d1162fa..cceef8f34ac 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -386,30 +386,20 @@ build_round_expr (tree arg, tree restype) argprec = TYPE_PRECISION (argtype); resprec = TYPE_PRECISION (restype); - /* Depending on the type of the result, choose the int intrinsic - (iround, available only as a builtin, therefore cannot use it for - __float128), long int intrinsic (lround family) or long long - intrinsic (llround). We might also need to convert the result - afterwards. */ + /* Depending on the type of the result, choose the int intrinsic (iround, + available only as a builtin, therefore cannot use it for __float128), long + int intrinsic (lround family) or long long intrinsic (llround). If we + don't have an appropriate function that converts directly to the integer + type (such as kind == 16), just use ROUND, and then convert the result to + an integer. We might also need to convert the result afterwards. */ if (resprec <= INT
Re: Fix Fortran rounding issues, PR fortran/96983.
On Wed, Apr 21, 2021 at 10:10:07AM +0200, Tobias Burnus wrote: > On 20.04.21 08:58, Richard Biener via Fortran wrote: > >On Mon, Apr 19, 2021 at 9:40 PM Michael Meissner via Fortran > > wrote: > Is there any reason to not only send the email to fortran@ _and_ > gcc-patches@ but sending it to 13 Fortran maintainers explicitly? (Now > removed) Sorry about that. With PowerPC backend changes, I generally do explicitly add the maintainers so things don't get lost. > >>Fix Fortran rounding issues, PR fortran/96983. > >> > >>Can I check this change into the GCC trunk? > >The patch looks fine technically and is definitely an improvement since the > >intermediate conversion looks odd. But it might be that the standard > >requires such dance though the preceeding cases handled don't seem to > >care. I'm thinking of a FP format where round(1.6) == 3 because of lack > >of precision but using an intermediate FP format with higher precision > >would "correctly" compute 2. > > The patched build_round_expr is only called by ANINT / NINT; > NINT is real → integer; ANINT is real → real > [And the modified code is only called for NINT, reason: see comment far > below.] > > NINT (A[, KIND]) is described (F2018) as "Nearest integer": > * Result Characteristics. Integer. If KIND is present, the kind type parameter > is that specified by the value of KIND; > otherwise, the kind type parameter is that of default integer type. > * The result is the integer nearest A, or if there are two > integers equally near A, the result is whichever such integer has the > greater > magnitude. > * Example. NINT (2.783) has the value 3. > > ANINT (A[, KIND]) as "Nearest whole number": > * The result is of type real. If KIND is present, the kind type parameter is > that > specified by the value of KIND; otherwise, the kind type parameter is that > of A. > * The result is the integer nearest A, or if there are two integers equally > near A, > the result is whichever such integer has the greater magnitude. > * Examples. ANINT (2.783) has the value 3.0. ANINT (−2.783) has the value > −3.0. > > >Of course the current code doesn't handle this correctly for the > >case if llroundf either. > >>I've not contributed to the Fortran front end before. If the maintainers > >>like > >>the patch, can somebody point out if I need to do additional things to > >>commit > >>the patch? > Nothing special: a testcase already exists, committing is done as usual > and a PR to update you have as well. Given GCC 11 has branched, is it ok to backport the patch to the GCC 11 branch as well? I assume it is, since it fixes a regression in the compiler. -- 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
Re: [RFC, Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
On Wed, Aug 04, 2021 at 02:14:07PM -0600, Sandra Loosemore wrote: > I was trying last week to run my not-yet-committed TS29113 testsuite > on a powerpc64le-linux-gnu target and ran into some problems with > the kind constants c_float128 and c_float128_complex from the > ISO_C_BINDING module; per the gfortran manual they are supposed to > represent the kind of the gcc extension type __float128 and the > corresponding complex type. They were being set to -4 (e.g., not > supported) instead of 16, although this target does define > __float128 and real(16) is accepted as a supported type by the > Fortran front end. > > Anyway, the root of the problem is that the definition of these > constants only looked at gfc_float128_type_node, which only gets set > if TFmode is not the same type as long_double_type_node. I > experimented with setting gfc_float128_type_node = > long_double_type_node but that caused various Bad Things to happen > elsewhere in code that expected them to be distinct types, so I > ended up with this minimally intrusive patch that only tweaks the > definitions of the c_float128 and c_float128_complex constants. > > I'm not sure this is completely correct, though. I see PowerPC > supports 2 different 128-bit encodings and it looks like TFmode/long > double is mapped onto the one selected by the ABI and/or > command-line options; that's the only one the Fortran front end > knows about. All of TFmode, IFmode, and KFmode would map onto kind > 16 anyway (in spite of having different TYPE_PRECISION values) so > Fortran wouldn't be able to distinguish them. The thing that > confuses me is how/when the rs6000 backend defines __float128; it > looks like the documentation in the GCC manual doesn't agree with > the code, and I'm not sure what the intended behavior really is. Is > it possible that __float128 could end up defined but specifying a > different type than TFmode, and if so is there a target-independent > way to identify that situation? Can the PowerPC experts help > straighten me out? > > -Sandra At the moment, we only fully support C and C++ when changing the long double format (between IEEE 128-bit, IBM 128-bit, and 64-bit) when the compiler is invoked (and assuming you are using GLIBC 2.32 or newer). For Fortran and the other languages, the only way to change the floating point format is to configure the compiler with the '--with-long-double-format=ieee' configuration option. This makes TFmode use IEEE 128-bit floating point instead of IBM 128-bit floating point. It would take somebody familar with the Fortran front end and libraries to make the same sort of modifications that were made for the C and C++ languages. Basically you need build libgfortran so that it has support for both floating point formats, using different names. You would need to modify the fortran front end to call the alternate functions when the switch is used to change the floating point format. It might be nice to have a Fortran specific way to specify which of the two floating point formats are used for REAL*16 (similar to the use of __float128 and __ibm128 in C/C++, and also _Float128 in just C). If you are going to do it, good luck. FWIW, I have built GCC compilers with the alternate floating point format, and I've been able to run the test suite and compile the Spec 2017 test suite with it. Generally to build a bootstrap compiler with the alternate long double representation I go through the following steps. 1) Make sure you have a GLIBC that supports switching long double representation (2.32 or new). I tend to use the IBM Advance Toolchain AT 14.0-3 to provide the new library, but if the native GLIBC on your system is new enough you could use that. I've discovered that there are problems if the GCC zlib is use, so I use the system zlib. The options I use when configuring the compiler include: --with-advance-toolchain=at14.0 --with-system-zlib --with-native-system-header-dir=/opt/at14.0/include If you are building and running on a power9 system, it is helpful if you add the option to set the default CPU to power9, since that way the compiler will automatically use the hardware IEEE 128-bit instructions that were added in power9. Otherwise it has to go through a call to do each operation. If you are running on a power9, we use the ifunc attribute to select modules that are built to use the hardware instruction. --with-cpu=power9 2) Build a non-bootstrap compiler with the '--with-long-double-format=ieee' configuration option, and install it somewhere. 3) With the compiler built in step #2, build the three libraries GCC uses (MPC, MPFR, and GMP), and install them some place. You need to do this because these libraries have functions in them with long double arguments. GCC doesn't actually use the functions with the long double arguments, but you will get a linker warning about mixing long double floating point type. 4) With the compiler built in step #2 a
Re: [RFC, Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
On Thu, Aug 05, 2021 at 12:19:37PM -0600, Sandra Loosemore wrote: > On 8/5/21 11:33 AM, Michael Meissner wrote: > >At the moment, we only fully support C and C++ when changing the long double > >format (between IEEE 128-bit, IBM 128-bit, and 64-bit) when the compiler is > >invoked (and assuming you are using GLIBC 2.32 or newer). > > > >For Fortran and the other languages, the only way to change the floating > >point > >format is to configure the compiler with the '--with-long-double-format=ieee' > >configuration option. This makes TFmode use IEEE 128-bit floating point > >instead of IBM 128-bit floating point. > > My understanding from reading the code is is that for GNU/Linux > targets, PowerPC already defaults to the IEEE format for TFmode? > I'm not sure what targets the IBM format might be the default on. All PowerPC systems that I'm aware of that use 128-bit floating point use the IBM format. It is anticipated that one or more Linux distributions in the future may move to IEEE 128-bit format, but right now, I'm not aware that any have moved. > >It would take somebody familar with the Fortran front end and libraries to > >make > >the same sort of modifications that were made for the C and C++ languages. > >Basically you need build libgfortran so that it has support for both floating > >point formats, using different names. You would need to modify the fortran > >front end to call the alternate functions when the switch is used to change > >the > >floating point format. It might be nice to have a Fortran specific way to > >specify which of the two floating point formats are used for REAL*16 (similar > >to the use of __float128 and __ibm128 in C/C++, and also _Float128 in just > >C). > > > >If you are going to do it, good luck. > > Well, I am actually not at all interested in doing that. My > questions for the PowerPC experts are: > > (1) When is the __float128 type defined, and which format does it > specify? Is it always the IEEE format, or does it specify the same > format as TFmode/long double? __float128 (and _Float128 in C) is always IEEE 128-bit, if IEEE 128-bit is supported. By default, IEEE 128-bit is only supported on little endian PowerPC 64-bit systems. For C (but not C++), you can declare constants with the f128 suffix so that they would be compatible with the _Float128 type. > > (2) If __float128 is not always the same 128-bit format as > TFmode/long double, how can I detect that in the Fortran front end > in a target-independent way? Is it possible without adding a new > target hook? You can look at the constants in float.h: For a system with IBM long double: FLT_RADIX= 2 LDBL_MANT_DIG= 106 LDBL_DIG = 31 LDBL_MIN_EXP = -968 LDBL_MIN_10_EXP = -291 LDBL_MAX_EXP = 1024 LDBL_MAX_10_EXP = 308 For a system with IEEE long double: FLT_RADIX= 2 LDBL_MANT_DIG= 113 LDBL_DIG = 33 LDBL_MIN_EXP = -16381 LDBL_MIN_10_EXP = -4931 LDBL_MAX_EXP = 16384 LDBL_MAX_10_EXP = 4932 For a system that uses 64-bit numbers for long double: FLT_RADIX= 2 LDBL_MANT_DIG= 53 LDBL_DIG = 15 LDBL_MIN_EXP = -1021 LDBL_MIN_10_EXP = -307 LDBL_MAX_EXP = 1024 LDBL_MAX_10_EXP = 308 In addition, the PowerPC GCC defines __LONG_DOUBLE_IEEE128__ if long double is IEEE 128-bit, and __LONG_DOUBLE_IBM128__ if long double IBM 128-bit. If long double is 64-bit, the macro __LONG_DOUBLE_128__ is not defined. > (3) Can we do anything about the "Additional Floating Types" section > in extend.texi? It's not clear on the answer to (1), and I think > the stuff about "future versions of GCC" is bit-rotten as it goes > back to at least GCC 6. (Either it's been implemented by now, or > the idea was discarded.) > > Basically, I want the Fortran front end to define c_float128 to 16 > if C supports __float128 and it corresponds to TFmode, otherwise it > ought to continue to define c_float128 to -4. I do not want to make > the Fortran front end support multiple 128-bit encodings at the same > time, just accurately define c_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
Re: [Patch v3 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
On Wed, Aug 11, 2021 at 05:55:39AM -0500, Segher Boessenkool wrote: > Hi! > > On Tue, Aug 10, 2021 at 04:46:11PM -0600, Sandra Loosemore wrote: > > OK. I used your wording verbatim for the first one. For the second > > one, I'm still pretty confused as I think it is at least theoretically > > possible on PowerPC to have a target with 64-bit long double (AIX?) that > > Some embedded and embedded-like subtargets use 64-bit long double by > default. You can also configure this on any Power target (not that it > will necessarily work ;-) ) It will work on Linux LE systems with glibc 2.32 (it may work with earlier glibcs). I've built parallel toolchains with all 3 long double formats. There are some tests in the test suite that fail if you configure 64-bit long doubles. -- 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
Re: libgfortran.so SONAME and powerpc64le-linux ABI changes
On Mon, Oct 04, 2021 at 12:07:54PM +0200, Jakub Jelinek wrote: > 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? I tried this at one point. There are a lot of hidden assumptions that the kind number is the number of bytes. I'm sure it can be tracked down, but the problem is with these assumptions is you can't prove a negative (i.e. you never know that you've missed some). Note the PowerPC has a third configure option for long double with the configure option --without-long-double-128. This option makes long double on C/C++ be 64-bits instead of 128-bits. In terms of enabling IEEE outside of PowerPC 64 LE Linux systems there are two roadblocks: 1) The default configuration of BE systems is still Power4. You need at least Altivec registers to be able to pass and return IEEE 128-bit values. However, I am skeptical that configuring for a power6 could produce workable code, so power7 is the theoretical minimum that could be used. I limited it to power8 because the code needed direct moves and other ISA 3.0 support. PowerPC 64-bit LE has a minimum base level of power8, so it isn't an issue on that system. 2) The big stumbling block was that GLIBC only has IEEE 128-bit support for the LE systems. If there is BE glibc support, we could certainly add support for enabling IEEE 128-bit in BE systems if the compiler was configured for power8 or higher. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: libgfortran.so SONAME and powerpc64le-linux ABI changes
On Wed, Oct 06, 2021 at 10:17:44AM -0500, Segher Boessenkool wrote: > On Wed, Oct 06, 2021 at 08:59:53AM +0200, Thomas Koenig wrote: > > On 05.10.21 23:54, Segher Boessenkool wrote: > > >>There is also the issue of binary data. If some user has written > > >>out data in double double and wants to read it in as IEEE quad, > > >>the results are going to be garbage. Another option for CONVERT > > >>might be the solution to that, or, as you wrote, having a > > >>REAL(KIND=15). It should be inaccessible via SELECTED_REAL_KIND, > > >>though. > > > > > >That means flipping the default on all PowerPC to no longer be double- > > >double. This means that you should have IEEE QP work everywhere, or the > > >people who do need more than double precision will have no recourse. > > > > I think we can exclude big-endian POWER from this - they do not have > > IEEE QP support, correct? So, exclude that from the SONAME change. > > Not correct, no. IEEE QP works fine in either endianness. > > I don't know what the libraries do, but in GCC it works just fine. It only has the support if you add the options to enable IEEE 128-bit support when compiling programs. It is off by default. > > So this would only be critical for people on little-endian POWER8 > > who use double double. Hmm... can the POWER8 handle the IEEE QP > > instructions, or would that be trap and emulate? What is the > > plan there? > > The registers used by the QP insns are the VRs. Trying to use the QP > insns on a p8 will trap. There is no kernel emulation for them afaik. > > But, for p8 there is software emulation, that GCC can generate. This > follows the ABI as for p9 and later. If the code is compiled for power8, it always uses the software functions to do the support. Buried inside of libgcc are ifunc functions that use the hardware instructions if the user is running on power9 or power10. It would be nice if any distro that changed the default used power9 as a base, instead of power8. > Converting double-double to IEEE QP should not be hard or slow? There are a lot of corner cases to get it right. IIRC, there are a few values that double double can represent that are not expressable with exact precision in IEEE 128-bit. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: libgfortran.so SONAME and powerpc64le-linux ABI changes
On Thu, Oct 07, 2021 at 08:08:21AM +0200, Thomas Koenig wrote: > On 07.10.21 05:35, Michael Meissner via Fortran wrote: > > I tried this at one point. There are a lot of hidden assumptions that the > > kind > > number is the number of bytes. I'm sure it can be tracked down, but the > > problem is with these assumptions is you can't prove a negative (i.e. you > > never > > know that you've missed some). > > So, summing up from the Fortran side, I'd say the best course of action > is to > > - make KIND=16 into IEEE QP This is probably the right thing to do. Note, it will effectively mean that any fortran users on BE systems will no longer be able to use KIND=16. It will also be a compatibility issue if users have code compiled on a LE system with GCC 11 and earlier with KIND=16, it will not link with GCC 12. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: libgfortran.so SONAME and powerpc64le-linux ABI changes
I've played with some patches to PowerPC to set the defaults for fortran. But without doing a full rebuild like you would do with a new distribution, I think it will be problematical, unless you build everything with the default long double set to IEEE 128-bit. First off all, libquadmath is currently built on Linux 64-bit systems. I never removed building libquadmath once we got the official glibc 2.34 support So to go in more detail of what I've tried. I added an undocumented switch -mfortran that says set the defaults for Fortran. This switch would be used to build libgfortran, and also set with TARGET_F951_OPTIONS for all Fortran invocations. I tried to switch to float128_type_node instead of long_double_type_node. I ran into problems with gimplify in that it could not do a conversion from _Float128 to float. I suspect I didn't actually use the right type. I then went to patches where -mfortran silently switches the long double type to IEEE 128-bit. There you get into various compatibility issues where the linker complains that you are calling between the different long double types. For instance because we are still building libquadmath, libquadmath is marked as having long double being IBM 128-bit, but it is called from Fortran modules that have long double being IEEE 128-bit. I then did a build supressing building libquadmath since I was using LE with glibc 2.34, and I got much further. This time instead of a lot of failures, I got 29 failures, due to libgfortran still being marked as IBM long double and the fortran modules are marked as IEEE long double. Right now, the only way to avoid these things is to build the entire toolchain defaulting to IEEE 128-bit. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: libgfortran.so SONAME and powerpc64le-linux ABI changes (work in progress patches)
Here are the patches I worked on today. It does seem to fix KIND=16 to use Float128, but by not considering long double for KIND processing, it breaks the tests that want to do ISO C binding to long double. Feel free to completely ignore the patches and go off in a different direction. But I thought it would be useful to share what I've done. > From 443773ac040383311384577b48ecc0bd957ff328 Mon Sep 17 00:00:00 2001 > From: Michael Meissner > Date: Thu, 28 Oct 2021 23:23:53 -0400 > Subject: [PATCH] Initial patch for PowerPC Fortran KIND=16 This is a work in progress patch. It attempts to make Fortran KIND=16 to always mean Float128 on PowerPC VSX systems. Unfortunately, in changing KIND=16 to Float128, it breaks all of the ISO C bindings for long double support in Fortran. gcc/ 2021-10-28 Michael Meissner * config/rs6000/rs6000.h (FORTRAN_USE_FLOAT128): New macro. (FORTRAN_USE_LONG_DOUBLE): New macro. * tree.h (complex_float128_type_node): Define. * doc/tm.texi.in (FORTRAN_USE_FLOAT128): Add documentation. (FORTRAN_USE_LONG_DOUBLE): Likewise. * doc/tm.texi: Regenerate. gcc/fortran/ 2021-10-28 Michael Meissner * f95-lang.c (gfc_init_builtin_functions): Flesh out more Float128 support. * gfortran.h (FORTRAN_USE_LONG_DOUBLE): Provide default definition. (FORTRAN_USE_FLOAT128): Likewise. * trans-types.c (gfc_init_kinds): Add support for FORTRAN_USE_LONG_DOUBLE and FORTRAN_USE_FLOAT128. (gfc_build_real_type): Likewise. (gfc_build_complex_type): Add support for Float128 complex. --- gcc/config/rs6000/rs6000.h | 10 ++ gcc/doc/tm.texi| 13 + gcc/doc/tm.texi.in | 13 + gcc/fortran/f95-lang.c | 28 gcc/fortran/gfortran.h | 13 + gcc/fortran/trans-types.c | 24 +--- gcc/tree.h | 2 ++ 7 files changed, 96 insertions(+), 7 deletions(-) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 3eba1c072cf..4e016e548db 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2691,3 +2691,13 @@ while (0) rs6000_asm_output_opcode (STREAM); \ } \ while (0) + +/* Whether Fortran should use long double or __float128 for KIND=16. If we + support IEEE 128-bit and long double is not IEEE 128-bit, then use the + _Float128 type for KIND=16. Otherwise use long double. */ +#undef FORTRAN_USE_FLOAT128 +#define FORTRAN_USE_FLOAT128 (TARGET_FLOAT128_TYPE && !TARGET_IEEEQUAD) + +#undef FORTRAN_USE_LONG_DOUBLE +#define FORTRAN_USE_LONG_DOUBLE(!FORTRAN_USE_FLOAT128) + diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 902402d7503..13ecca2605c 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -12612,3 +12612,16 @@ counters are incremented using atomic operations. Targets not supporting 64-bit atomic operations may override the default value and request a 32-bit type. @end deftypefn + +@defmac FORTRAN_USE_LONG_DOUBLE +Define this macro to return true if Fortran should enable @code{long +double} support for @code{KIND} processing. If you do not define this +macro, Fortran always uses the @code{long double} type. +@end defmac + +@defmac FORTRAN_USE_LONG_DOUBLE +Define this macro to return true if Fortran should enable +@code{_Float128} support for @code{KIND} processing. If you do not +define this macro, Fortran will enable @code{_Float128} support if the +quadmath library is built, and the mode @code{TFmode} is enabled. +@end defmac diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 86352dc9bd2..012ef1ecc98 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -8187,3 +8187,16 @@ maintainer is familiar with. @hook TARGET_MEMTAG_UNTAGGED_POINTER @hook TARGET_GCOV_TYPE_SIZE + +@defmac FORTRAN_USE_LONG_DOUBLE +Define this macro to return true if Fortran should enable @code{long +double} support for @code{KIND} processing. If you do not define this +macro, Fortran always uses the @code{long double} type. +@end defmac + +@defmac FORTRAN_USE_LONG_DOUBLE +Define this macro to return true if Fortran should enable +@code{_Float128} support for @code{KIND} processing. If you do not +define this macro, Fortran will enable @code{_Float128} support if the +quadmath library is built, and the mode @code{TFmode} is enabled. +@end defmac diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index 58dcaf01d75..b8117dc72b4 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -674,9 +674,11 @@ gfc_init_builtin_functions (void) tree mfunc_float[6]; tree mfunc_double[6]; tree mfunc_longdouble[6]; + tree mfunc_float128[6]; tree mfunc_cfloat[6]; tree mfunc_cdouble[6]; tree mfunc_clongdouble[6]; + tree mfunc_cfloat128[6]; tree func_cfloat_float, func_flo
Re: libgfortran.so SONAME and powerpc64le-linux ABI changes (work in progress patches)
On Fri, Oct 29, 2021 at 09:07:38PM +0200, Thomas Koenig wrote: > Hi Michael, > > I tried this out on the one POWER machine where I can get something > installed :-) It runs Ubuntu 20.04, but does not appear to have the > right glibc version; it has > > $ lsb_release -a > No LSB modules are available. > Distributor ID: Ubuntu > Description:Ubuntu 20.04.1 LTS > Release:20.04 > Codename: focal > $ ldd --version > ldd (Ubuntu GLIBC 2.31-0ubuntu9.1) 2.31 > > Configure was > > ./trunk/configure --prefix=$HOME --enable-languages=c,c++,fortran > --with-advance-toolchain=at15.0 > --with-native-system-header-dir=/opt/at15.0/include > --with-long-double-format=ieee > > and the error message > > msgfmt -o fr.mo ../../../../trunk/libstdc++-v3/po/fr.po > msgfmt: /lib/powerpc64le-linux-gnu/libm.so.6: version `GLIBC_2.32' not found > (required by > /home/ig25/trunk-bin/powerpc64le-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6) > msgfmt: /lib/powerpc64le-linux-gnu/libc.so.6: version `GLIBC_2.33' not found > (required by > /home/ig25/trunk-bin/powerpc64le-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6) > msgfmt: /lib/powerpc64le-linux-gnu/libc.so.6: version `GLIBC_2.34' not found > (required by > /home/ig25/trunk-bin/powerpc64le-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6) > msgfmt: /lib/powerpc64le-linux-gnu/libc.so.6: version `GLIBC_2.32' not found > (required by > /home/ig25/trunk-bin/powerpc64le-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6) > msgfmt: /lib/powerpc64le-linux-gnu/libc.so.6: version `GLIBC_2.34' not found > (required by /home/ig25/trunk-bin/./gcc/libgcc_s.so.1) > > and so on. > > Since gcc135 is also too old, that exhausts my possibilities at testing. > > Any hints on how best to proceed? > > Best regards As I've delved into it, it looks glibc 2.34 is really only needed for switching long double over to IEEE 128-bit, since it has all of the F128 functions that would be needed. That is because Fortran uses the 'q' names which are in libquadmath (that should be built). I built the original version with: --prefix=/home/meissner/fsf-install-ppc64le/fortran-orig \ --enable-languages=c,c++,fortran \ --disable-plugin \ --enable-checking \ --enable-stage1-checking \ --enable-gnu-indirect-function \ --disable-libgomp \ --enable-decimal-float \ --enable-secureplt \ --enable-threads=posix \ --enable-__cxa_atexit \ --with-long-double-128 \ --with-long-double-format=ibm \ --with-cpu=power9 \ --with-as=/opt/at12.0/bin/as \ --with-ld=/opt/at12.0/bin/ld \ --with-gnu-as=/opt/at12.0/bin/as \ --with-gnu-ld=/opt/at12.0/bin/ld \ --with-gmp=/home/meissner/tools-compiler/ppc64le \ --with-mpfr=/home/meissner/tools-compiler/ppc64le \ --with-mpc=/home/meissner/tools-compiler/ppc64le \ --without-ppl \ --without-cloog \ --without-isl I needed to build my own version of mpfs, mpc, and gmp. I built them without shared libraries, because I get messages like you get. I have a new version of the patch that makes new target hooks to allow the backend to specify KIND numbers for types. I choose kind=16 to always be IEEE 128-bit, and kind=15 to be long double if long double is IBM (since I discovered yesterday, Fortran needs to be able to deal with long double). I'm in the middle of the build an on internal IBM system, and I will start the build on gcc135 shortly. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: libgfortran.so SONAME and powerpc64le-linux ABI changes (work in progress patches)
On Fri, Oct 29, 2021 at 11:21:33PM +0200, Bernhard Reutner-Fischer wrote: > Michael, > > On Thu, 28 Oct 2021 23:36:20 -0400 > Michael Meissner via Fortran wrote: > > ISTM the second > @defmac FORTRAN_USE_LONG_DOUBLE > in tm.texi.in should be FORTRAN_USE_FLOAT128 Thanks. I had noticed that afterwards. Note, the next patches will delete those macros, because I discovered it was unworkable. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: libgfortran.so SONAME and powerpc64le-linux ABI changes (2nd patch)
This patch replaces the first patch. Instead of disallowing long double and only dealing with float128 types, this patch tries to accommodate the two. It adds target hooks so the back end can overwrite the kind number for types. I made the IBM long double type use KIND=15 instead of KIND=16, and Float128 uses KIND=16 as we've discussed. The tests for long double are still failing, so I suspect we will need some way of signalling about the long double which uses a funky kind (king=15). Again, this patch may be completely wild and crazy, as I don't really grok the Fortran internals. But perhaps it will help somebody to take the concepts and come up with a more workable solution. Note, the fleshing out of full F128 support is only partially done. I discovered that we don't have a complete set of FLOAT128 built-in functions defined, so I couldn't just add code to DO_DEFINE_MATH_BUILTIN to make every math function have the float128 counterpart declared. Note, that code is probably not used right now, since the float128 support uses the 'q' functions in libquadmath. Too fully utilize the f128 functions, you will need glibc 2.34 or later. > From 80d617264d80eb86806aecb2db5f37adb9b37ff6 Mon Sep 17 00:00:00 2001 > From: Michael Meissner > Date: Fri, 29 Oct 2021 18:35:42 -0400 > Subject: [PATCH] Second patch for PowerPC Fortran KIND=16. This replaces the first patch, and it is a work in progress. This patch adds three target hooks to allow the backend to control the fortran KIND numbers. I have modified the PowerPC back end so that KIND==16 is always IEEE 128-bit on systems support IEEE 128-bit, and KIND=15 is the long double type if long double is IBM 128-bit. gcc/ 2021-10-29 Michael Meissner * config/rs6000/rs6000.c (TARGET_FORTRAN_REAL_KIND_NUMBER): Set target hook. (TARGET_FORTRAN_REAL_KIND_TYPE): Likewise. (TARGET_FORTRAN_REAL_KIND_FLOAT128_P): Likewise. (rs6000_fortran_real_kind_number): New target hook. (rs6000_fortran_real_kind_type): Likewise. (rs6000_fortran_real_kind_float128_p): Likewise. * target.def (fortran_real_kind_number): New target hook. (fortran_real_kind_type): Likewise. (fortran_real_kind_float128_p): Likewise. * targhooks.c (default_fortran_real_kind_number): New default target hooks for Fortran kind support. (default_fortran_real_kind_type): Likewise. (default_fortran_real_kind_float128_p): Likewise. * targhooks.h (default_fortran_real_kind_number): New declaration. (default_fortran_real_kind_type): Likewise. (default_fortran_real_kind_float128_p): Likewise. * tree.h (complex_float128_type_node): New define. * doc/tm.texi.in (TARGET_FORTRAN_REAL_KIND_*): Document new target hooks. * doc/tm.texi: Regenerate. gcc/fortran/ 2021-10-29 Michael Meissner * f95-lang.c (gfc_init_builtin_functions): Flesh out more Float128 support. * trans-types.c (gfc_init_kinds): Add support for using target hooks to allow the backend to control KIND numbers. (gfc_build_real_type): Likewise. (gfc_build_complex_type): Add support for complex Float128. --- gcc/config/rs6000/rs6000.c | 101 + gcc/doc/tm.texi| 17 +++ gcc/doc/tm.texi.in | 6 +++ gcc/fortran/f95-lang.c | 28 ++ gcc/fortran/trans-types.c | 32 gcc/target.def | 22 +++- gcc/targhooks.c| 37 ++ gcc/targhooks.h| 3 ++ gcc/tree.h | 2 + 9 files changed, 236 insertions(+), 12 deletions(-) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 22f5d701908..70595e58ac2 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1787,6 +1787,15 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_INVALID_CONVERSION #define TARGET_INVALID_CONVERSION rs6000_invalid_conversion + +#undef TARGET_FORTRAN_REAL_KIND_NUMBER +#define TARGET_FORTRAN_REAL_KIND_NUMBER rs6000_fortran_real_kind_number + +#undef TARGET_FORTRAN_REAL_KIND_TYPE +#define TARGET_FORTRAN_REAL_KIND_TYPE rs6000_fortran_real_kind_type + +#undef TARGET_FORTRAN_REAL_KIND_FLOAT128_P +#define TARGET_FORTRAN_REAL_KIND_FLOAT128_P rs6000_fortran_real_kind_float128_p /* Processor table. */ @@ -28376,6 +28385,98 @@ rs6000_globalize_decl_name (FILE * stream, tree decl) } #endif + + +/* PowerPC support for Fortran KIND support. Given a MODE, return a kind + number to be used for real modes. If we support IEEE 128-bit, make KIND=16 + always be IEEE 128-bit, and make KIND=15 be the IBM 128-bit double-double + format. */ + +static int +rs6000_fortran_real_kind_number (machine_mode mode) +{ + if (TARGET_FLOAT128_TYPE) +{ + /* If long double is IEEE 128-bit, return 16 for long double and 15 for +__ibm128,
Re: [RFC] User-visible changes for powerpc64-le-linux ABI changes
On Mon, Nov 01, 2021 at 10:54:27AM -0500, Bill Schmidt wrote: > Hi Thomas, > > To me this looks excellent. If you feel that support for both forms is > achievable, > that's certainly superior. We had previously been concerned about whether the > necessary name mangling support would be possible, but it sounds like you > aren't > overly worried about that. > > I'll let Mike weigh in about using the same options as are present for C/C++, > which > I think should be the right approach, but I know I don't know all the > subtleties. > That would also help determine whether -freal-16=ibm is the right default. I > think > it probably is, but I'll let those more familiar with the details weigh in. > > Thanks again! > Bill Lets see if I can describe the C/C++ side of things. Internally, we have 3 floating point types: * KFmode: IEEE 128-bit * IFmode: IBM 128-bit * TFmode: What long double maps to (either IEEE 128-bit or IBM 128-bit) In general, you should use TFmode if the 128-bit type matches long double, and only use IFmode/KFmode if you are using a 128-bit type that does not match long double. We support 3 keywords: * __float128: Historic keywork for IEEE 128-bit (both C/C++) * _Float128: IEEE 128-bit (from ISO/IEC TS 18661-‐3:2015, C only) * __ibm128: Keyword to access current IBM 128-bit. There are 2 naming conventions for 128-bit IEEE functions: * Libquadmath: Math functions end in 'q'. * ISO/IEC TS 18661-2:2015: Math functions end in 'f128'. While we still build libquadmath, the C/C++ compiler and Glibc no longer generate the 'q' names. Instead we use the new names that end in f128. Starting with glibc 2.34, the glibc library supports the f128 names on PowerPC 64-bit little endian systems. As far as I know, glibc does not not provide the f128 names for big endian systems. We do build libquadmath and those interfaces could be used (much like the x86_64 does), but you may get issues of whether you are using a 'q' or 'f128' function. With glibc 2.34 and beyond, math.h remaps all of the math functions from 'l' suffix to 'f128' suffix if long double is IEEE 128-bit. In addition, the PowerPC back end does this mapping for built-in functions if you call the function without including math.h. Hence if you build a toolchain that defaults to IEEE 128-bit long double, Fortran calls to these functions are mapped. I believe glibc only does the IEEE 128-bit mapping if either long double is IEEE 128-bit or: * __STDC_WANT_IEC_60559_FUNCS_EXT__ is defined. * __STDC_WANT_IEC_60559_TYPES_EXT__ might also need to be defined. However, not all of the math functions have built-in counterparts to the name. The compiler does not map these functions. The libstdc++ library also does this mapping, starting wtih GCC 11. While we typically talk of going between IBM and IEEE 128-bit long doubles, the PowerPC compiler actually has 3 long double variants: * -mabi=ieeelongdouble: Long double is IEEE 128-bit if long doubles are 128-bits. * -mabi=ibmlongdouble: Long double is IBM 128-bit if long doubles are 128-bits. * -mlong-double-64: Long double is 64-bits and the -mabi=ieeelongdouble and -mabi=ibmlongdouble are not used. The following macros are defined: * __LONG_DOUBLE_IEEE128__: if long doubles are IEEE 128-bit; * __LONG_DOUBLE_IBM128__: If long doubles are IBM 128-bit; * __LONG_DOUBLE_128__: If long doubles are 128-bits (either IBM or IEEE). The ELF object file uses .gnu_attribute #4 to encode the current long double format. This is only set if calls are made using long double types (note, it is somewhat buggy, and it misses things like using long double in the code, but not doing a call, and the bit for 64-bit long doubles gets set if you pass or return normal 64-bit doubles when the 64-bit long switch is set. The bits are: * 0x1: Hardware 32/64-bit floating point is used. * 0x2: Software 32/64-bit floating point is used. Note, this bit is not set if IEEE 128-bit is emulated (power8). * Bits 0x4 and 0x8 are a 2 bit field: * 0x4: 64-bit long doubles are passed and returned; * 0x8: IBM 128-bit long doubles are passed and returned; * 0xc: IEEE 128-bit long doubles are passed and returned. If you are building libraries that contain modules with multiple long double types, you must use the '-mno-gnu-attribute'. We also use the '-Wno-psabi' option, which silences the warning that you are switching long double types (if glibc is not 2.34 or newer). We may need to tweak -Wno-psabi for use with Fortran. For shared libraries, the linker complains if any of the modules in the library set .gnu_attribute #4 to a different value than the current modules. When building the glibc and libstdc++ libraries There are 3 configuration options to chose the long double type: * --with-long-double-format=ibm: Chooses IBM 128-bit long double; * --with-long-double-format=ieee: Chooses IEEE 128-bit long double; * --without-long-double-128: Choose 64-bit lo
Re: libgfortran.so SONAME and powerpc64le-linux ABI changes (work in progress patches)
On Mon, Nov 01, 2021 at 10:56:33AM -0500, Bill Schmidt wrote: > Would starting from Advance Toolchain 15 with the most recent glibc make > things easier for Thomas to test? The problem is gcc135 runs Centos 7.x which is not compatible with AT 13-15. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [RFC] User-visible changes for powerpc64-le-linux ABI changes
On Tue, Nov 02, 2021 at 07:19:10AM +0100, Thomas Koenig wrote: > > On 01.11.21 18:45, Jakub Jelinek wrote: > > Note, if we go the way of C/C++ with -mabi=ieeelongdouble vs. > > -mabi=ibmlongdouble choosing between the two ABIs and libgfortran being > > ABI compatible with both, then we don't need to bump soname. > > Sounds like one major pain solved. I think we should do if it possible. > > > But, if we don't bump it, we need to keep double double there backwards > > compatible (i.e. _r16 etc. being the double double, not IEEE). > > Correct. I would actually go for 17 for the IEEE because it is > the larger number, but that is a pure style issue and has no > impact on something that is user visible :-) > > > When in the future we bump the soname, we can swap those two and > > make _r16 newly stand for IEEE quad and _r15 or _r16d or whatever > > for double double. > > Yep. > > We do need to do something about the generated module files, though, to > make programs compiled with one option incompatible with the other ones > on that level. In general, I wouldn't expect mixing and matching long double options to work. But you do want the library to have both versions of the library functions with different names. And as I've found out, outside of the official libraries, you run into smaller libraries (like gmp, mpfr, and mpc used in the compiler) that also need to be compiled with the right options because they have random functions that have long double elements (even if the app doesn't use the long double arguments). For example, in the C world, we need to have 3 versions of each of the *printf functions, since printf can be passed long double. > Or are people expected to get that right? :-) In terms of testing, it isn't ideal, but if you make a branch that we (IBM) can access, we can run it on our various systems. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [RFC] User-visible changes for powerpc64-le-linux ABI changes
On Mon, Nov 15, 2021 at 09:27:38PM +0100, Thomas Koenig wrote: > Hi, > > is there an update on this? I am still waiting on a response for > the account on the development machine. > > I assume we would to the development on a branch. My git fu > is extremely weak, so I would appreciate if somebody did that > for me. Sure, we can create an IBM vendor branch. > Is it actually possible to implement what I wrote in the draft > documentation patch, or is there some problem (like gmp > or mpfr depending on one of the types at compile-time)? > > If so, I think we should go for it; if not, then we have to make > another decision. Well there are a couple of things that need to be done. A lot are fortran specific type things, so while I can attempt to do these things, I don't know the structure of the front end or library. >From my previous test patches, I think it is a disaster if KIND=16 is not the same as C/C++ long double by default. It opens up all sorts of problems. But then it may be the Fortran users would like that flexibility. That is your call. I think the most important thing is defining the library interface and naming scheme. So we need to switch calls to one name or another based on the default long double format. I don't know what naming scheme you use, but it should be fairly simple. For the C/C++/math built-ins, we use the traditional name with an 'l' suffix if long double is IBM double-double, and a 'f128' suffix if long double is IEEE 128-bit. The PowerPC backend will automatically switch names for built-ins it knows about. However, my tests showed there are a bunch of functions that are in the math library that are not built-ins. For C/C++, this is not an issue, because math.h will do this switching. We would need some way for Fortran to do it for the other functions. Once we have the naming scheme, then we need to modify the library build, so that it will build both types of modules with the appropriate flags. Once the library is set up to have both names, then we can start to think about the user overriding the defaults. This is probably a thing that needs the Fortran folk to do, since there may be various rules of what can be done. But for the initial work, I think the most important thing is getting the library so it has both names in it, so a user/distro could start to move the default floating point type. > Due to my day job, my time for working on this project is rather > limited, and in my experience it is easier to finish something if > it is actually started :-) > > So, who does what? I work on the gfortran internals (library interface) > and the library itself, but I would need some prior work to set up the > compiler so things work up to that particular point. > > Or have we missed the window due to gcc being in stage 3 now? This may be an issue for the release and Fortran maintainers. Even if we can't put it in right now, I think it is important to start work so it can be put in at a later date. In terms of my schedule, I will be available for doing whatever is needed until December 20th. I have a hard stop then as I will be doing a family trip for Christmas and I will not be available after that. I won't be back until the new year. I believe Bill and Peter feel this is one of the most important uses of my time in the next month or so. But bear in mind, I don't know much about the Fortran front end, nothing about the library, or knowing Fortran at all. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [power-ieee128] What should the math functions be annotated with?
On Fri, Dec 03, 2021 at 08:57:54AM -0600, Bill Schmidt wrote: > Hi! > > On 12/3/21 5:56 AM, Thomas Koenig wrote: > > > > Hi Jakub, > > > >> Note, we want to test both building gcc on ppc64le with older glibc > >> and newer glibc (and that libgfortran will have the same ABI between both > >> and one can move gcc including libgfortran and libquadmath from the older > >> glibc setup to newer and make -mabi=ieeelongdouble work in Fortran too). > > > > Using an older glibc is no problem - we can use gcc135 on the compile > > farm for that. > > > > As far as the other options you outlined, I think I'll defer to people > > who know more about setting up libraries than I do. I have root access, > > but chances are I would just mess up the virtual machine :-) > > Easiest is probably to install the advance toolchain. Mike said he'll work on > > that later this morning. > > Thanks! > Bill I have loaded Advance Toolchain 15.0 on the system. It is located in /opt/at15.0. AT 15 provides a GCC 11.2 compiler and GLIBC 2.34. I built a trunk compiler using the options: --enable-languages=c,c++,fortran \ --disable-plugin \ --enable-checking \ --enable-stage1-checking \ --enable-gnu-indirect-function \ --disable-libgomp \ --enable-decimal-float \ --enable-secureplt \ --enable-threads=posix \ --enable-__cxa_atexit \ --with-cpu=power8 \ --with-long-double-128 \ --with-as=/opt/at15.0/bin/as \ --with-ld=/opt/at15.0/bin/ld \ --with-gnu-as=/opt/at15.0/bin/as \ --with-gnu-ld=/opt/at15.0/bin/ld \ --with-advance-toolchain=at15.0 \ --with-system-zlib \ --with-native-system-header-dir=/opt/at15.0/include \ --without-ppl \ --without-cloog \ --without-isl I will rebuild the compiler using --with-cpu=power9 instead, since if power9 is the default CPU, we avoid the use of using an emulator for IEEE 128-bit. Note, if you are doing a bootstrap using the AT 15.0 libraries, you need a 'msgfmt' in your PATH to avoid problems that show up when the compiler is rebuilding libstdc++. I use this script: #! /bin/bash # Hack script to allow building GCC with the --with-advance-toolchain= # option and do a bootstrap. What happens is at the end of the stage1 build, # and in preparation for the stage2 build, the environment variable # LD_LIBRARY_PATH is set to the new library directory. Unfortunately this # occurs while we are building libstdc++, and the libstdc++ that is pointed to # is incomplete. The msgfmt program then aborts because it doesn't have the # right symbols. This script allows us to not use those environment variables. unset LD_LIBRARY_PATH unset RPATH_ENVVAR for x in /usr/local/bin /usr/bin /bin; do if [ -x "${x}/msgfmt" ]; then exec "${x}/msgfmt" $@ fi done echo "Could not find msgfmt" >&2 exit 1 -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [power-ieee128] What should the math functions be annotated with?
On Sat, Dec 04, 2021 at 02:42:13PM +0100, Thomas Koenig wrote: > On 04.12.21 11:29, Jakub Jelinek wrote: > > If zlib devel isn't installed, drop --with-system-zlib option > > or use --without-system-zlib. > > > > You've asked in another mail how to configure gcc to default to > > -mabi=ieeelongdouble, that is > > --with-long-double-format=ieee > > Thanks for those hints. > > I have now managed to bootstrap a compiler on that machine, but > success at running programs is somewhat limited: > > tkoenig@gcc-fortran:~/Tst$ which gcc > /home/tkoenig/bin/gcc > tkoenig@gcc-fortran:~/Tst$ cat hello.c > #include > > int main() > { > printf ("Hello, world!\n"); > return 0; > } > tkoenig@gcc-fortran:~/Tst$ gcc hello.c > tkoenig@gcc-fortran:~/Tst$ ldd ./a.out > ./a.out: /lib/powerpc64le-linux-gnu/libc.so.6: version `GLIBC_2.34' not > found (required by ./a.out) > linux-vdso64.so.1 (0x7a16a451) > libc.so.6 => /lib/powerpc64le-linux-gnu/libc.so.6 > (0x7a16a42c) > /opt/at15.0/lib64/ld64.so.2 => /lib64/ld64.so.2 (0x7a16a453) > tkoenig@gcc-fortran:~/Tst$ export LD_LIBRARY_PATH=~/lib64:/opt/at15.0/lib64/ > tkoenig@gcc-fortran:~/Tst$ ls > Segmentation fault (core dumped) > > @IBM folks: I would appreciate if you gave me access to a system > which actually worked, together with the necessary information, > so I can actually do what I volunteered to do. > > Right now, I appear to be just wasting my time. The Advance Toolchain has its own GLIBC, and it sets a different path to load up the libraries. You should not need to set the LD_LIBRARY_PATH variable. Note, the system ldd does not tend to accurately report the library dependencies for AT libraries: 15:15:03 ~/tests -gcc-fortran-> /home/meissner/fsf-install-ppc64le/trunk/bin/gcc -O2 hello.c 15:15:23 ~/tests -gcc-fortran-> ldd a.out ./a.out: /lib/powerpc64le-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./a.out) linux-vdso64.so.1 (0x796b63da) libm.so.6 => /lib/powerpc64le-linux-gnu/libm.so.6 (0x796b63c5) libc.so.6 => /lib/powerpc64le-linux-gnu/libc.so.6 (0x796b63a1) /opt/at15.0/lib64/ld64.so.2 => /lib64/ld64.so.2 (0x796b63dc) 15:15:27 ~/tests -gcc-fortran-> /opt/at15.0/bin/ldd a.out linux-vdso64.so.1 (0x70dea014) libm.so.6 => /opt/at15.0/lib64/power9/libm.so.6 (0x70dea002) libc.so.6 => /opt/at15.0/lib64/power9/libc.so.6 (0x70de9fdb) /opt/at15.0/lib64/ld64.so.2 (0x70dea016) This is done by the GCC driver setting a different dynamic linker path internally: -dynamic-linker /opt/at15.0/lib64/ld64.so.2 Tulio can probably expand on what is going on in more detail. The reason for using the Advance Toolchain is to get access to newer libraries. I don't know Ubuntu at all, but I believe the version that is installed is too old to have the necessary changes in it. There isn't a LTS (long time support) version of Ubuntu yet available that has the library. There are newer versions that aren't LTS (i.e. every 6 months you have to jump to the next release), and Peter, Bill and I have talked about upgrading the partition to use those. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [power-ieee128] What should the math functions be annotated with?
On Sun, Dec 05, 2021 at 12:16:38PM +0100, Thomas Koenig wrote: > > On 05.12.21 01:35, Peter Bergner wrote: > > Instead of setting LD_LIBRARY_PATH=/home/tkoenig/lib64 could you try > > setting it to LD_LIBRARY_PATH='$ORIGIN/lib64' instead? This would > > allow the other system binaries to not find your /home/tkoenig/lib64 > > directory so they'd behave normally. However, any binary that was > > compiled in a directory where your lib64/ exists would find your > > new libs and use them. I'm not sure if that cramps your testing > > or not, to limit yourself to compiling your tests in that one directory. > > > > If that doesn't work, could you instead not set LD_LIBRARY_PATH and > > instead compile using -L/home/bergner/lib64 -R/home/bergner/lib64 ? > > I think I shall forsake the dubious joys of dynamic linking and use > -static-libgfortran instead. Yes, I tend to use -static-libgfortran for running Fortran spec things, and -static-libstdc++ for C++, since it can be a quaqmire getting the right library when you have several libraries on the system. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com
Re: [power-ieee128] Which options for libquadmath / native ieee128
On Mon, Dec 13, 2021 at 09:29:16PM +0100, Thomas Koenig wrote: > > Hi, > > looking at what the REAL(KIND=17) numbers should be compiled for, I see > the following options that should be considered: > > a) xsaddqp and friends are not supported by the CPU; libquadmath should >be called for all operations, including simple arithmetic. Note, we do not use the emulator in libquadmath. Libgcc has support for doing software emulation of the IEEE 128-bit basic support. > b) xsaddqp and friends are supported, but glibc is too old and lacks the >*ieee128 functions. libquadmath should be called for these >functions. Yes, this would be the place to call libquadmath. Or possibly don't use libquadmath at all and don't allow KIND=17. It is probably better for the users if we use libquadmath instead of disabling it all together. > c) xsaddqp and friends are supported, and glibc is new enough. Call >the *ieee128 functions. The necessary support is in the little endian GLIBC 2.32 or newer. I don't recall if you also need Elf abi V2 (which is default on little endian). You could check via: #if (((__GLIBC__ * 1000) + __GLIBC_MINOR__) >= 2032 && \ (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \ (_CALL_ELF == 2)) If you are writing C code for the library, and using _Float128 for the type instead of using long double and using the -mabi=ieeelongdouble switch, you want to define the following macros before math.h or other system include files are included: #define __STDC_WANT_IEC_60559_TYPES_EXT__ 1 #define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1 > What is the best way to check in the library config files that the quad > precision instructions are supported (to differentiate between a) on the > one hand and b) and c) on the other? You can check whether long double is IEEE 128-bit via: #if defined(__LONG_DOUBLE_IEEE128__)/* or */ #if __LONG_DOUBLE_IEEE128__ and similarly to check for IBM 128-bit long double: #if defined(__LONG_DOUBLE_IBM128__) /* or */ #if __LONG_DOUBLE_IBM128__ To check whether IEEE 128-bit instructions are enabled: #if defined(__FLOAT128_HARDWARE__) /* or */ #if __FLOAT128_HARDWARE__ To check whether the _Float128 or __float128 keywords are available (whether or not the hardware supports the instructions): #if defined(__FLOAT128_TYPE__) /* or */ #if __FLOAT128_TYPE__ Note, that C++ does not support the _Float128 type (which is in one of the IEC papers), but it does support the non-standard __float128 keyword. Unfortunately, __float128 _Complex does not work. There is a GLIBC macro that gives the appropriate _Complex type for __float128 use in C++, but I don't remember what it is. Alternatively, it might be simpler to build the library parts using long double and build those modules with the appropriate options. > > And which options to the compiler make sure the libquadmath library > is called? The libqaudmath library should always be linked in if it is built. I had actually meant to turn off building it once all of the 2.32 support went in, but I never did. Note, I haven't tested libquadmath in a long time. To compile C/C++ code where long double is IEEE 128-bit use: -mabi=ieeelongdouble -Wno-psabi -mno-gnu-attribute For Fortran code, I think you have to remove the -Wno-psabi. But it may be buggy. Similarly to force long double to be IBM 128-bit, no matter what the defaults are use: -mabi=iibmlongdouble -Wno-psabi -mno-gnu-attribute The no-gnu-attribute says to disable setting the GNU attribute that says what the default long double type is. It is necessary when building libraries with both 128-bit types. -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: meiss...@linux.ibm.com