Message ID | ydd4nxxlgyq.fsf@manam.CeBiTec.Uni-Bielefeld.DE |
---|---|
State | New |
Headers | show |
On 11/21/2011 05:53 AM, Rainer Orth wrote: > The libitm execution tests are currently failing on Solaris 10 and up > with Sun as/ld: > > ld.so.1: cancel.exe: fatal: /var/gcc/regression/trunk/11-gcc/build/i386-pc-solaris2.11/./libitm/.libs/libitm.so.0: hardware capability (CA_SUNW_HW_1) unsupported: 0x20000000 [ AVX ] > FAIL: libitm.c/cancel.c execution test > > This is the same issue solved by > gcc/testsuite/gcc.target/i386/clearcap.map, and the following patch > adresses it in the same way: > > * Detect if the linker used supports -M <map file>. > > * Use it when linking libitm.so. > > Right now, it is only possible to clear the hardware capabilities > completely, while the new v2 mapfile syntax supports selectively adding > and removing capabilities. It is only available in Solaris 11 and > Solaris 10 Update 10, though, so I'm restricting us to the v1 syntax for > now. This is only ok if the compiler and library are build with default options. If you use --with-arch=corei7-avx then we may well use AVX insns all through the library, not just in the one interface that will only be used if the user of the library is using avx. Can you auto-foo this based on CC+CFLAGS? E.g. compile-time tests for the various __SSE__ / __AVX__ macros? r~
Richard Henderson <rth@redhat.com> writes: > This is only ok if the compiler and library are build with default options. > If you use --with-arch=corei7-avx then we may well use AVX insns all through > the library, not just in the one interface that will only be used if the > user of the library is using avx. > > Can you auto-foo this based on CC+CFLAGS? E.g. compile-time tests for the > various __SSE__ / __AVX__ macros? Probably, but it occured to me that it might be easier to just apply the mapfile to x86_avx.o unconditionally before linking libitm.la. Rainer
On 11/21/2011 09:23 AM, Rainer Orth wrote: > Richard Henderson <rth@redhat.com> writes: > >> This is only ok if the compiler and library are build with default options. >> If you use --with-arch=corei7-avx then we may well use AVX insns all through >> the library, not just in the one interface that will only be used if the >> user of the library is using avx. >> >> Can you auto-foo this based on CC+CFLAGS? E.g. compile-time tests for the >> various __SSE__ / __AVX__ macros? > > Probably, but it occured to me that it might be easier to just apply the > mapfile to x86_avx.o unconditionally before linking libitm.la. Possibly. Though you'd want to do the same thing for x86_sse.o too. Again, that file is only used if the main program uses SSE. r~
From: Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> Date: Mon, 21 Nov 2011 14:53:33 +0100 > Right now, it is only possible to clear the hardware capabilities > completely, while the new v2 mapfile syntax supports selectively adding > and removing capabilities. It is only available in Solaris 11 and > Solaris 10 Update 10, though, so I'm restricting us to the v1 syntax for > now. I really wish Sun had never added this hwcap checking, 99 times out of 100 it's a nuisance rather than a help in any way.
David Miller <davem@davemloft.net> writes: > From: Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> > Date: Mon, 21 Nov 2011 14:53:33 +0100 > >> Right now, it is only possible to clear the hardware capabilities >> completely, while the new v2 mapfile syntax supports selectively adding >> and removing capabilities. It is only available in Solaris 11 and >> Solaris 10 Update 10, though, so I'm restricting us to the v1 syntax for >> now. > > I really wish Sun had never added this hwcap checking, 99 times out of > 100 it's a nuisance rather than a help in any way. I beg to differ: I prefer a ld.so.1 message telling me that my executable or library uses ISA extension x, but my machine doesn't support that, over the same binary beginning to run, but crashing with a SIGILL every time. I posit that's similar to symbol versioning where the runtime linker can tell me: you're trying to use interface x in liby.so.3, but the library doesn't provide it. That's far better than letting the programs start and crash later with an unsupported insn or missing symbol, perhaps losing work. True, you may be lucky and not hit that codepath, but I'd rather not depend on my luck if running software ;-) I suppose that everyone who's able to play cute tricks with code selection at runtime depending on machine hardware capabilities is smart enough to deal with the linker's hwcap stuff, too. As an aside, in Solaris 10 Update 10 and Solaris 11, there's direct support in ld and ld.so.1 to select different implementations of the same interface, depending on hardware capabilites present: http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter2-13.html#giskh Rainer
On 11/22/2011 10:14 AM, Rainer Orth wrote: > As an aside, in Solaris 10 Update 10 and Solaris 11, there's direct > support in ld and ld.so.1 to select different implementations of the > same interface, depending on hardware capabilites present: > > http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter2-13.html#giskh Hum. So, not entirely incompatible with the gnu ifunc extension, but certainly not exactly like it either. Off and on I've been pondering, post-toplevel-libgcc-move, whether it would make sense to implement the functions therein with different ISAs and either select the proper version with pre-processor macros (generating a target-specific libgcc) or with ifuncs if available. What support does the Solaris 11 assembler have for this feature? The documentation only mentions the compiler... r~
Richard Henderson <rth@redhat.com> writes: > What support does the Solaris 11 assembler have for this feature? > The documentation only mentions the compiler... I've asked exactly the same question when the spec was posted early last year: http://arc.opensolaris.org/caselog/PSARC/2010/022/mail Unfortunately, there was none at the time. The assembler manuals mention nothing either, but they are incomplete and outdated, unfortuantely. There's nothing obvious even in the last beta (12.3) of the Studio compilers either, so it seems you'll have to use the ld mapfile trick to convert from object capabilities to symbol capabilities for now, which feels clumsy. I'll ask the linker engineers that developed that feature. Rainer
Richard Henderson <rth@redhat.com> writes: > On 11/21/2011 05:53 AM, Rainer Orth wrote: >> The libitm execution tests are currently failing on Solaris 10 and up >> with Sun as/ld: >> >> ld.so.1: cancel.exe: fatal: /var/gcc/regression/trunk/11-gcc/build/i386-pc-solaris2.11/./libitm/.libs/libitm.so.0: hardware capability (CA_SUNW_HW_1) unsupported: 0x20000000 [ AVX ] >> FAIL: libitm.c/cancel.c execution test >> >> This is the same issue solved by >> gcc/testsuite/gcc.target/i386/clearcap.map, and the following patch >> adresses it in the same way: >> >> * Detect if the linker used supports -M <map file>. >> >> * Use it when linking libitm.so. >> >> Right now, it is only possible to clear the hardware capabilities >> completely, while the new v2 mapfile syntax supports selectively adding >> and removing capabilities. It is only available in Solaris 11 and >> Solaris 10 Update 10, though, so I'm restricting us to the v1 syntax for >> now. > > This is only ok if the compiler and library are build with default options. > If you use --with-arch=corei7-avx then we may well use AVX insns all through > the library, not just in the one interface that will only be used if the > user of the library is using avx. > > Can you auto-foo this based on CC+CFLAGS? E.g. compile-time tests for the > various __SSE__ / __AVX__ macros? My first attempt was to apply the equivalent of ld -r -M clearcap.map to x86_avx.lo and x86_sse.lo. While this works fine if calling ld -r directly, you need to get this through libtool and this is where things start breaking in all sorts of ways: I tried $ libtool --mode=link --tag=CC gcc -r -Wl,-M,clearcap.map -o x86_nhc.lo x86_sse.lo libtool: link: collect-ld -r -o x86_nhc.o .libs/x86_sse.o libtool: link: collect-ld -r -o x86_nhc.lo .libs/x86_sse.o This is of no use at all since -Wl,-M,clearcap.map is lost completely and I've found no way to get this through libtool at all. This beast tries to be smart and messes everything up completely. But even if I could get that part to work, what happens is still wrong: the .lo file is a real object file now, not the usual text file, so once I try to link the shared lib, libtool rightly complains. While the libtool docs claim that this relinking (.lo -> .lo) should work, it obviously does not, even with libtool 2.2.4 ;-( So unless I'm overlooking something, I'll have to go the route you outlined above and check for __SSE__/__AVX__ to make the decision. Rainer
# HG changeset patch # Parent fe631cce39f95ae2f718499a8e82260c18149752 Clear hardware capabilities on libitm.so with Sun ld diff --git a/libitm/Makefile.am b/libitm/Makefile.am --- a/libitm/Makefile.am +++ b/libitm/Makefile.am @@ -21,7 +21,7 @@ AM_CFLAGS = $(XCFLAGS) AM_CXXFLAGS = -std=gnu++0x -funwind-tables -fno-exceptions -fno-rtti \ $(XCFLAGS) $(abi_version) AM_CCASFLAGS = $(XCFLAGS) -AM_LDFLAGS = $(XLDFLAGS) $(SECTION_LDFLAGS) $(OPT_LDFLAGS) +AM_LDFLAGS = $(XLDFLAGS) $(SECTION_LDFLAGS) $(OPT_LDFLAGS) $(HWCAP_LDFLAGS) toolexeclib_LTLIBRARIES = libitm.la nodist_toolexeclib_HEADERS = libitm.spec diff --git a/libitm/acinclude.m4 b/libitm/acinclude.m4 --- a/libitm/acinclude.m4 +++ b/libitm/acinclude.m4 @@ -256,6 +256,34 @@ AC_DEFUN([LIBITM_CHECK_LINKER_FEATURES], dnl +dnl Check if the linker used supports linker maps to clear hardware +dnl capabilities. This is only supported by Sun ld at the moment. +dnl +dnl Defines: +dnl HWCAP_LDFLAGS='-Wl,-M,clearcap.map' if possible +dnl LD (as a side effect of testing) +dnl +AC_DEFUN([LIBITM_CHECK_LINKER_HWCAP], [ + test -z "$HWCAP_LDFLAGS" && HWCAP_LDFLAGS='' + AC_REQUIRE([AC_PROG_LD]) + + ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LFLAGS -Wl,-M,$srcdir/clearcap.map" + + AC_MSG_CHECKING([for ld that supports -Wl,-M,mapfile]) + AC_TRY_LINK([], [return 0;], [ac_hwcap_ldflags=yes],[ac_hwcap_ldflags=no]) + if test "$ac_hwcap_ldflags" = "yes"; then + HWCAP_LDFLAGS="-Wl,-M,$srcdir/clearcap.map $HWCAP_LDFLAGS" + fi + AC_MSG_RESULT($ac_hwcap_ldflags) + + LDFLAGS="$ac_save_LDFLAGS" + + AC_SUBST(HWCAP_LDFLAGS) +]) + + +dnl dnl Add version tags to symbols in shared library (or not), additionally dnl marking other symbols as private/local (or not). dnl diff --git a/libitm/clearcap.map b/libitm/clearcap.map new file mode 100644 --- /dev/null +++ b/libitm/clearcap.map @@ -0,0 +1,14 @@ +# Clear hardware capabilities emitted by Sun as: calls to the x86_avx.c +# functions are only emitted with -mavx. +# +# The v1 mapfile syntax has no support for clearing specific capabilities, +# so clear everything. +# +hwcap_1 = V0x0 OVERRIDE; +# +# If we can assume mapfile v2 syntax, we can specificially clear AVX. +# +#$mapfile_version 2 +#CAPABILITY { +# HW -= AVX; +#}; diff --git a/libitm/configure.ac b/libitm/configure.ac --- a/libitm/configure.ac +++ b/libitm/configure.ac @@ -208,10 +208,11 @@ GCC_LINUX_FUTEX(:) # See if we support thread-local storage. GCC_CHECK_TLS -# See what sort of export controls are availible. +# See what sort of export controls are available. LIBITM_CHECK_ATTRIBUTE_VISIBILITY LIBITM_CHECK_ATTRIBUTE_DLLEXPORT LIBITM_CHECK_ATTRIBUTE_ALIAS +LIBITM_CHECK_LINKER_HWCAP LIBITM_ENABLE_SYMVERS if test $enable_symvers = gnu; then