public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems
@ 2020-09-24 20:20 Michael Meissner
  2020-09-24 20:31 ` [PATCH 1/9] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
                   ` (12 more replies)
  0 siblings, 13 replies; 21+ messages in thread
From: Michael Meissner @ 2020-09-24 20:20 UTC (permalink / raw)
  To: gcc-patches, Michael Meissner, Segher Boessenkool,
	David Edelsohn, Bill Schmidt, Peter Bergner, Jeff Law,
	Jonathan Wakely

This series of 9 patches is an attempt to gather together all of the patches
that are needed to be able to configure and build a little endian 64-bit
PowerPC Linux GCC compiler where the defualt long double format uses the IEEE
128-bit representation.

I have created an IBM vendor branch that includes these patches (along the
other outstanding patches that I have for IEEE 128-bit min/max/cmove on
power10, and power10 PCREL_OPT support):

	vendors/ibm/ieee-longdouble-001

You will need a new enough GLIBC in order to do this configuration.  The
Advance Toolchain AT14.0 from IBM includes the changes in the library that are
needed to build a compiler with this default.

Note, with these patches, we need the libstdc++ work that was begun last year
to be finished and committed.  This shows up in trying to build the Spec 2017
511.parest_r (rate) benchmark when long double uses the IEEE representation.

Using the steps outlined below, I have build and bootstraped current GCC
sources, comparing builds where the default long double is the current IBM
extended double to builds where long double uses the IEEE 128-bit
representation.  The only difference in C, C++, LTO, and Fortran tests are 3
Fortran tests that either were marked as XFAIL or just failed now pass.

The patches that will be posted include:

    #1	Map built-in function names for long double;
    #2	Update error messages intermixing the 2 128-bit types;
    #3	Fixes libgcc conversions between the 2 128-bit types;
    #4	Add support for converting IEEE 128-bit <-> Decimal;
    #5	Update tests to run with IEEE 128-bit long double;
    #6	Map nanq, nansq, etc. to long double if long double is IEEE;
    #7	Update power10 __float128 tests to work with IEEE long double;
    #8	Use __float128 in some of the tests instead of __ieee128; (and)
    #9	Use __builtin_pack_ieee128 in libgcc if IEEE long double.

I put the following file in the branch:

	gcc/config/rs6000/gcc-with-ieee-128bit-longdouble.txt

This is a short memo of how to build a GCC 11 compiler where the long double
type is IEEE 128-bit instead of using the IBM extended double format on the
PowerPC 64-bit little endian Linux environment.

You will likely need the Advance Toolchain AT14.0 library, as it has all of the
changes to support switching the long double default to IEEE 128-bit.

    *	https://www.ibm.com/support/pages/advance-toolchain-linux-power

You will need a recent version of binutils.  I've used the binutils that I
downloaded via git on September 14th, 2020:

    *	git clone git://sourceware.org/git/binutils-gdb.git

You will need appropriate versions of the gmp, mpfr, and mpc libraries:

    *	http://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2
    *	http://gcc.gnu.org/pub/gcc/infrastructure/mpfr-3.1.4.tar.bz2
    *	http://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.0.3.tar.gz

Currently, I use --without-ppl --without-cloog --without-isl so I haven't used
those libraries.

I currently disable plug-in support.  If you want plug-in support, you will
likely need to build a binutils with the first compiler, to use with the second
and third compilers.  If you use a binutils compiled with a compiler where the
long double format is IBM extended double, it may not work.

I found I needed the configuration option --with-system-zlib to avoid some
issues when doing a bootstrap build.

Build the first PowerPC GCC compiler (non-bootstrap) using at least the
following options:

	--prefix=<first-gcc-install>
	--enable-stage1-languages=c,c++,fortran
	--disable-bootstrap
	--disable-plugin
	--with-long-double-format=ieee
	--with-advance-toolchain=at14.0
	--with-system-zlib
	--with-native-system-header-dir=/opt/at14.0/include
	--without-ppl
	--without-cloog
	--without-isl

Other configuration options that I use but may not affect switching the long
double default include:

	--enable-checking
	--enable-languages=c,c++,fortran
	--enable-stage1-checking
	--enable-gnu-indirect-function
	--enable-decimal-float
	--with-long-double-128
	--enable-secureplt
	--enable-threads=posix
	--enable-__cxa_atexit
	--with-as=<as location>
	--with-ld=<ld location>
	--with-gnu-as=<as location>
	--with-gnu-ld=<ld location>
	--with-cpu=power9		(or --with-cpu=power8)

Build and install the first compiler.

Configure, build, and install gmp 6.1.0 using the first compiler built above
with following configuration options:

	--prefix=<gmp-install>
	--enable-static
	--disable-shared
	--enable-cxx
	CPPFLAGS=-fexceptions

Configure, build, and install mpfr 3.1.4 using the first compiler build above
with the following configuration options:

	--prefix=<mprf-install>
	--enable-static
	--disable-shared
	--with-gmp=<gmp-install>

Configure, build, and install mpc 1.0.3 using the first compiler build above
with the following configuration options:

	--prefix=<mpc-install>
	--enable-static
	--disable-shared
	--with-gmp=<gmp-install>
	--with-mpfr=<mpfr-install>

Configure, build, and install the second compiler using the first compiler to
build the second compiler, and using the gmp, mpfr, and mpc libraries built
above.  You could skip this step, but I found during development, it was useful
to shake things out before diving into a bootstrap build.  The notable
configuration options used are:

	--prefix=<second-gcc-install>
	--enable-stage1-languages=c,c++,fortran
	--disable-bootstrap
	--disable-plugin
	--with-long-double-format=ieee
	--with-system-zlib
	--with-advance-toolchain=at14.0
	--with-native-system-header-dir=/opt/at14.0/include
	--with-gmp=<gmp-install>
	--with-mpfr=<mpfr-install>
	--with-mpc=<mpc-install>
	--without-ppl
	--without-cloog
	--without-isl

As before, I tend to add these options as well:

	--enable-checking
	--enable-languages=c,c++,fortran
	--enable-stage1-checking
	--enable-gnu-indirect-function
	--enable-decimal-float
	--with-long-double-128
	--enable-secureplt
	--enable-threads=posix
	--enable-__cxa_atexit
	--with-as=<as location>
	--with-ld=<ld location>
	--with-gnu-as=<as location>
	--with-gnu-ld=<ld location>
	--with-cpu=power9		(or --with-cpu=power8)

Assuming the second compiler builds and installs, now go onto building a
bootstrap third compiler, using the second compiler to build stage1.  The
options I used include:

	--prefix=<third-gcc-install>
	--disable-plugin
	--with-long-double-format=ieee
	--with-cpu=power9
	--with-system-zlib
	--with-advance-toolchain=at14.0
	--with-native-system-header-dir=/opt/at14.0/include
	--with-gmp=<gmp-location>
	--with-mpfr=<mpfr-location>
	--with-mpc=<mpc-location>
	--without-ppl
	--without-cloog
	--without-isl

As before, I tend to add these options as well:

	--enable-languages=c,c++,fortran
	--enable-checking
	--enable-stage1-checking
	--enable-gnu-indirect-function
	--enable-decimal-float
	--with-long-double-128
	--enable-secureplt
	--enable-threads=posix
	--enable-__cxa_atexit
	--with-as=<as location>
	--with-ld=<ld location>
	--with-gnu-as=<as location>
	--with-gnu-ld=<ld location>
	--with-cpu=power9		(or --with-cpu=power8)

Three fortran tests that used to fail now succeed:

gfortran.dg/default_format_2.f90		(marked XFAIL)
gfortran.dg/default_format_denormal_2.f90	(marked XFAIL)
gfortran.dg/ieee/large_2.f90			(not marked XFAIL)

I built Spec 2017 rate benchmarks with the newest compiler.

    1)	The 500.perlbench_r benchmark uses long double in the sv.c module.  It
	looks like perl uses long double as the universal type in the sv.c
	module.  There are 2 conversions from double to long double, 1
	conversion from long double back to double, and 3 long double
	comparisons.

	In looking at the sv.c in the Spec 2017 suite, there are a bunch of
	#ifdef's to control how perl optimizes the use of long double.  The
	Spec options disables these #ifdef's, but it is likely these same
	#ifdef's are used in the current version of perl used by the
	distributions.  It is likely that if the long double change is made on
	a system wide basis, that the perl configuration will need to be
	tweaked to know that long double uses the IEEE 128-bit format.

    2)	The 510.parest_r benchmark fails to link because there are missing
	functions in libstdc++.  I'm including a simplification of the error
	messages below:

<...>/ld: source/lac/full_matrix.o: in function `dealii::FullMatrix<std::complex<__ieee128> >::ExcNotRegular::print_info(std::ostream&) const':
<...>/include/lac/full_matrix.h:1206: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)'

<...>/ld: source/lac/full_matrix.o: in function `void dealii::LogStream::print<std::complex<__ieee128> >(std::complex<__ieee128> const&)':
<...>/include/base/logstream.h:441: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)'

<...>/ld: source/lac/full_matrix.o: in function `void dealii::FullMatrix<std::complex<__ieee128> >::print<std::ostream>(std::ostream&, unsigned int, unsigned int) const':
<...>/include/lac/full_matrix.h:1499: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)'

<...>/ld: source/lac/full_matrix.o: in function `dealii::FullMatrix<std::complex<__ieee128> >::print_formatted(std::ostream&, unsigned int, bool, unsigned int, char const*, double, double) const':
<...>/include/lac/full_matrix.templates.h:1479: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)'

<...>/ld: source/lac/vector.o: in function `dealii::Vector<std::complex<__ieee128> >::print(std::ostream&, unsigned int, bool, bool) const':
<...>/include/lac/vector.templates.h:800: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)'

<...>/ld: source/lac/vector.o:<...>/include/lac/vector.templates.h:797: more undefined references to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <__ieee128, char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >, std::complex<__ieee128> const&)' follow
collect2: error: ld returned 1 exit status

With the discusion:

    *	https://gcc.gnu.org/pipermail/gcc/2020-August/233338.html

the agreement was to continue having essentially two types (& three modes) in
the compiler.

    *	When long double uses the IEEE 128-bit representation, the type node
	for __float128/_Float128 is the same as the type node for long double,
	and __ibm128 has a unique node.

    *	When long double uses the IBM extended double representation (current
	behavior), the type node for __ibm128 is the same as for long double,
	and __float128/_Float128 have a unique node.

This means that when the long double format changes, C++ libraries cannot mix
functions with the same name using __float128 and long double types.  I.e. the
following would generate an error:

	class foo {
	  long double add (long double a, long double b) { return a+b; }
	  __float128 add (__float128 a, __float128 b) { return a+b; }
	};

But C++ users would be able say:

	class foo {
	  long double add (long double a, long double b) { return a+b; }
	  __ibm128 add (__ibm128 a, __ibm128 b) { return a+b; }
	};

The boost library is believed to have both __float128 and long double in a
class.  Boost would need to be tweaked so that if the default long double is
IEEE 128-bit, not to enable the explicit __float128 support.

The compiler defines the following macros based on the long double support:

	#define __LONG_DOUBLE_IEEE128__	1 /* if long double is IEEE 128-bit.  */
	#define __LONG_DOUBLE_IBM128__	1 /* if long double is IBM 128-bit.  */
	#define __LONG_DOUBLE_128__	1 /* if sizeof (long double) == #16.  */


-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2020-10-19 21:51 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-24 20:20 [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
2020-09-24 20:31 ` [PATCH 1/9] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
2020-10-01 23:05   ` Joseph Myers
2020-10-08  5:20     ` Michael Meissner
2020-09-24 20:33 ` [PATCH 2/9] PowerPC: Update __float128 and __ibm128 error messages Michael Meissner
2020-09-24 20:34 ` [PATCH 3/9] PowerPC: Update IEEE <-> IBM 128-bit floating point conversions Michael Meissner
2020-09-24 20:35 ` [PATCH 4/9] PowerPC: Add IEEE 128-bit <-> Decimal conversions Michael Meissner
2020-09-24 20:36 ` [PATCH 5/9] PowerPC: Update tests to run if long double is IEEE 128-bit Michael Meissner
2020-09-24 20:40 ` [PATCH 6/9] PowerPC: If long double is IEEE 128-bit, map q built-ins to *l instead of *f128 Michael Meissner
2020-09-24 20:42 ` [PATCH 7/9] PowerPC: Update IEEE 128-bit built-in functions to work if long double is IEEE 128-bit Michael Meissner
2020-09-24 20:45 ` [PATCH 8/9] PowerPC: Change tests to use __float128 instead of __ieee128 Michael Meissner
2020-09-24 20:47 ` [PATCH 9/9] PowerPC: Use __builtin_pack_ieee128 if long double is IEEE 128-bit Michael Meissner
2020-10-09  4:35 ` [PATCH 1/9, revised] PowerPC: Map long double built-in functions if IEEE 128-bit long double Michael Meissner
2020-10-16 20:30   ` Segher Boessenkool
2020-10-19 19:30     ` Michael Meissner
2020-10-19 21:24     ` Michael Meissner
2020-10-12 23:16 ` Ping: [PATCH 0/9] PowerPC: Patches to enable changing the long double default to IEEE 128-bit on little endian PowerPC 64-bit Linux systems Michael Meissner
2020-10-16 14:37 ` Ping #2: " Michael Meissner
2020-10-16 19:14 ` Segher Boessenkool
2020-10-19 19:12   ` Michael Meissner
2020-10-19 21:50     ` Segher Boessenkool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).