Rainer Orth <r...@cebitec.uni-bielefeld.de> writes:

> Prompted by the recent failures of c-c++-common/gomp/pr60823-2.c on
> Solaris/x86 with Sun as
>
>       http://gcc.gnu.org/ml/gcc-patches/2014-05/msg00943.html
>
> I've reworked the clearing of hardware capabilities via linker maps for
> Sun ld, which is currently replicated in several places all over the
> testsuite.  I've chosen to use TEST_ALWAYS_FLAGS or ALWAYS_CXXFLAGS to
> pass on the necessary linker flags.

It turned out that more is needed to deal with the new gcc.dg/gomp and
g++.dg/gomp failures:

        https://gcc.gnu.org/ml/gcc-patches/2014-05/msg01185.html

The following patch implements what I've outlined there: it introduces a
Solaris-specific new -mclear-hwcap option, checking which version of
the mapfile syntax works, if any.  This way, all the duplication in the
testsuite and libitm can go.

Do deal with the OpenMP declare simd failures, this option/mapfile is
automatically activated with -fopenmp*.

Initial testing has concluded successfully, also on an Solaris 10/x86
system where ld only understands the old mapfile syntax.  Mainline
bootstraps on i386-pc-solaris2.11 (as/ld, gas/ld, gas/gld),
i386-pc-solaris2.10 (as/ld, gas/ld), and sparc-sun-solaris2.11 (as/ld)
are still running.  x86_64-unknown-linux-gnu didn't finish due to
unrelated libgo breakage.  Also, i386-pc-solaris2.9 bootstrap running on
the 4.9 branch which is equally affected by the testsuite failures.

Ok for mainline and 4.9 branch if those pass?

Thanks.
        Rainer


2014-05-13  Rainer Orth  <r...@cebitec.uni-bielefeld.de>

        gcc:
        * configure.ac ($gcc_cv_ld_clearcap): New test.
        * configure: Regenerate.
        * config.in: Regenerate.
        * config/sol2.opt (mclear-hwcap): New option.
        * config/sol2.h (LINK_CLEARCAP_SPEC): Define.
        * config/sol2-clearcap.map: Moved here from
        testsuite/gcc.target/i386/clearcap.map.
        * config/sol2-clearcapv2.map: Move here from
        gcc.target/i386/clearcapv2.map.
        * config/t-sol2 (install): Depend on install-clearcap-map.
        (install-clearcap-map): New target.
        * doc/invoke.texi (Option Summary, Solaris 2 Options): Document
        -mclear-hwcap.

        gcc/testsuite:
        * lib/clearcap.exp: New file.
        * gcc.dg/vect/vect.exp: Load clearcap.exp.
        Remove clearcap_ldflags handling.
        Call clearcap-init, clearcap-finish.
        * gcc.target/i386/i386.exp: Likewise.
        * gcc.target/i386/clearcap.map: Move to ../config/sol2-clearcap.map.
        * gcc.target/i386/clearcapv2.map: Move to
        ../config/sol2-clearcapv2.map.
        * gcc.target/x86_64/abi/avx/abi-avx.exp: Likewise.
        * gcc.target/x86_64/abi/avx512f/abi-avx512f.exp: Likewise.

        libitm:
        * acinclude.m4 (LIBITM_CHECK_LINKER_HWCAP): Check for
        -mclear-hwcap instead.
        * configure: Regenerate.
        * clearcap.map: Remove.

# HG changeset patch
# Parent 8bc292d22fc4feb31bf4225a4f6d3ee7f39c9a68
Centralise clearing hardware capabilities with Sun ld

diff --git a/gcc/testsuite/gcc.target/i386/clearcap.map b/gcc/config/sol2-clearcap.map
rename from gcc/testsuite/gcc.target/i386/clearcap.map
rename to gcc/config/sol2-clearcap.map
--- a/gcc/testsuite/gcc.target/i386/clearcap.map
+++ b/gcc/config/sol2-clearcap.map
@@ -1,3 +1,2 @@
-# clear all hardware capabilities emitted by Sun as: the tests here
-# guard against execution at runtime
+# Clear all hardware capabilities emitted by Sun as.
 hwcap_1 = V0x0 OVERRIDE;
diff --git a/gcc/testsuite/gcc.target/i386/clearcapv2.map b/gcc/config/sol2-clearcapv2.map
rename from gcc/testsuite/gcc.target/i386/clearcapv2.map
rename to gcc/config/sol2-clearcapv2.map
--- a/gcc/testsuite/gcc.target/i386/clearcapv2.map
+++ b/gcc/config/sol2-clearcapv2.map
@@ -1,6 +1,6 @@
-# clear all hardware capabilities emitted by Sun as: the tests here
-# guard against execution at runtime
-# uses mapfile v2 syntax which is the only way to clear AT_SUN_CAP_HW2 flags
+# Clear all hardware capabilities emitted by Sun as.
+#
+# Uses mapfile v2 syntax which is the only way to clear AT_SUN_CAP_HW2 flags.
 $mapfile_version 2
 CAPABILITY {
   HW = ;
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -268,12 +268,21 @@ along with GCC; see the file COPYING3.  
 #define LINK_LIBGCC_MAPFILE_SPEC ""
 #endif
 
+/* Clear hardware capabilities, either explicitly or with OpenMP:
+   #pragma openmp declare simd creates clones for SSE2, AVX, and AVX2.  */
+#ifdef HAVE_LD_CLEARCAP
+#define LINK_CLEARCAP_SPEC " %{mclear-hwcap|fopenmp*:-M %sclearcap.map}"
+#else
+#define LINK_CLEARCAP_SPEC ""
+#endif
+
 #undef  LINK_SPEC
 #define LINK_SPEC \
   "%{h*} %{v:-V} \
    %{!shared:%{!static:%{rdynamic: " RDYNAMIC_SPEC "}}} \
    %{static:-dn -Bstatic} \
-   %{shared:-G -dy %{!mimpure-text:-z text}} " LINK_LIBGCC_MAPFILE_SPEC " \
+   %{shared:-G -dy %{!mimpure-text:-z text}} " \
+   LINK_LIBGCC_MAPFILE_SPEC LINK_CLEARCAP_SPEC " \
    %{symbolic:-Bsymbolic -G -dy -z text} \
    %(link_arch) \
    %{Qy:} %{!Qn:-Qy}"
diff --git a/gcc/config/sol2.opt b/gcc/config/sol2.opt
--- a/gcc/config/sol2.opt
+++ b/gcc/config/sol2.opt
@@ -27,6 +27,10 @@ Driver Joined
 Ym,
 Driver Joined
 
+mclear-hwcap
+Target Report
+Clear hardware capabilities when linking
+
 mimpure-text
 Target Report
 Pass -z text to linker
diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2
--- a/gcc/config/t-sol2
+++ b/gcc/config/t-sol2
@@ -35,3 +35,10 @@ sol2-stubs.o: $(srcdir)/config/sol2-stub
 sol2.o: $(srcdir)/config/sol2.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
+
+# Install clearcap.map if present.
+install: install-clearcap-map
+
+# Ignore failures: file only exists if linker supports it.
+install-clearcap-map:
+	-$(INSTALL_DATA) clearcap.map $(DESTDIR)$(libdir)
diff --git a/gcc/configure.ac b/gcc/configure.ac
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4737,6 +4737,21 @@ if test x"$gcc_cv_ld_as_needed" = xyes; 
 [Define to the linker option to keep unused dependencies.])
 fi
 
+AC_MSG_CHECKING(linker mapfile support for clearing hardware capabilities)
+saved_LDFLAGS="$LDFLAGS"
+for clearcap_map in sol2-clearcapv2.map sol2-clearcap.map; do
+  LDFLAGS="$saved_LDFLAGS -Wl,-M,${srcdir}/config/$clearcap_map"
+  AC_LINK_IFELSE([int main(void) {return 0;}],
+    [gcc_cv_ld_clearcap=yes; break], [gcc_cv_ld_clearcap=no])
+done
+LDFLAGS="$saved_LDFLAGS"
+if test "x$gcc_cv_ld_clearcap" = xyes; then
+  AC_DEFINE([HAVE_LD_CLEARCAP], 1,
+[Define if the linker supports clearing hardware capabilities via mapfile.])
+  AC_CONFIG_LINKS([clearcap.map:${srcdir}/config/$clearcap_map])
+fi
+AC_MSG_RESULT($gcc_cv_ld_clearcap)
+
 case "$target:$tm_file" in
   powerpc64-*-freebsd* | powerpc64*-*-linux* | powerpc*-*-linux*rs6000/biarch64.h*)
   case "$target" in
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -982,7 +982,7 @@ See RS/6000 and PowerPC Options.
 -mpretend-cmove -mtas}
 
 @emph{Solaris 2 Options}
-@gccoptlist{-mimpure-text  -mno-impure-text @gol
+@gccoptlist{-mclear-hwcap -mno-clear-hwcap -mimpure-text  -mno-impure-text @gol
 -pthreads -pthread}
 
 @emph{SPARC Options}
@@ -20885,6 +20885,13 @@ patterns.  This can result in faster cod
 These @samp{-m} options are supported on Solaris 2:
 
 @table @gcctabopt
+@item -mclear-hwcap
+@opindex mclear-hwcap
+@option{-mclear-hwcap} tells the compiler to remove the hardware
+capabilities generated by the Solaris assembler.  This is only necessary
+when object files use ISA extensions not supported by the current
+machine, but check at runtime whether or not to use them.
+
 @item -mimpure-text
 @opindex mimpure-text
 @option{-mimpure-text}, used in addition to @option{-shared}, tells
diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp
--- a/gcc/testsuite/gcc.dg/vect/vect.exp
+++ b/gcc/testsuite/gcc.dg/vect/vect.exp
@@ -18,6 +18,7 @@
 
 # Load support procs.
 load_lib gcc-dg.exp
+load_lib clearcap.exp
 
 # Set up flags used for tests that don't specify options.
 global DEFAULT_VECTCFLAGS
@@ -41,30 +42,9 @@ if ![check_vect_support_and_set_flags] {
 # These flags are used for all targets.
 lappend DEFAULT_VECTCFLAGS "-ftree-vectorize" "-fno-vect-cost-model" "-fno-common"
 
-# If the linker used understands -M <mapfile>, pass it to clear hardware
-# capabilities set by the Sun assembler.
-# Try mapfile syntax v2 first which is the only way to clear hwcap_2 flags.
-set clearcap_ldflags "-Wl,-M,$srcdir/gcc.target/i386/clearcapv2.map"
-
-if ![check_no_compiler_messages mapfilev2 executable {
-    int main (void) { return 0; }
-} $clearcap_ldflags ] {
-    # If this doesn't work, fall back to the less capable v1 syntax.
-    set clearcap_ldflags "-Wl,-M,$srcdir/gcc.target/i386/clearcap.map"
-
-    if ![check_no_compiler_messages mapfile executable {
-	int main (void) { return 0; }
-    } $clearcap_ldflags ] {
-	unset clearcap_ldflags
-    }
-}
-
-if [info exists clearcap_ldflags] {
-    lappend DEFAULT_VECTCFLAGS $clearcap_ldflags
-}
-
 # Initialize `dg'.
 dg-init
+clearcap-init
 
 global VEC_FLAGS
 set VEC_FLAGS $DEFAULT_VECTCFLAGS
@@ -308,4 +288,5 @@ dg-runtest [lsort [glob -nocomplain $src
 set dg-do-what-default ${save-dg-do-what-default}
 
 # All done.
+clearcap-finish
 dg-finish
diff --git a/gcc/testsuite/gcc.target/i386/i386.exp b/gcc/testsuite/gcc.target/i386/i386.exp
--- a/gcc/testsuite/gcc.target/i386/i386.exp
+++ b/gcc/testsuite/gcc.target/i386/i386.exp
@@ -23,6 +23,7 @@ if { ![istarget i?86*-*-*] && ![istarget
 
 # Load support procs.
 load_lib gcc-dg.exp
+load_lib clearcap.exp
 
 # Return 1 if attribute ms_hook_prologue is supported.
 proc check_effective_target_ms_hook_prologue { } {
@@ -307,39 +308,6 @@ proc check_effective_target_sha { } {
     } "-O2 -msha" ]
 }
 
-# If the linker used understands -M <mapfile>, pass it to clear hardware
-# capabilities set by the Sun assembler.
-# Try mapfile syntax v2 first which is the only way to clear hwcap_2 flags.
-set clearcap_ldflags "-Wl,-M,$srcdir/$subdir/clearcapv2.map"
-
-if ![check_no_compiler_messages mapfilev2 executable {
-    int main (void) { return 0; }
-} $clearcap_ldflags ] {
-    # If this doesn't work, fall back to the less capable v1 syntax.
-    set clearcap_ldflags "-Wl,-M,$srcdir/$subdir/clearcap.map"
-
-    if ![check_no_compiler_messages mapfile executable {
-	int main (void) { return 0; }
-    } $clearcap_ldflags ] {
-	unset clearcap_ldflags
-    }
-}
-
-if [info exists clearcap_ldflags] {
-  if { [info procs gcc_target_compile] != [list] \
-	&& [info procs saved_gcc_target_compile] == [list] } {
-    rename gcc_target_compile saved_gcc_target_compile
-
-    proc gcc_target_compile { source dest type options } {
-      global clearcap_ldflags
-      # Always pass -Wl,-M,<mapfile>, but don't let it show up in gcc.sum.
-      lappend options "additional_flags=$clearcap_ldflags"
-
-      return [saved_gcc_target_compile $source $dest $type $options]
-    }
-  }
-}
-
 # If a testcase doesn't have special options, use these.
 global DEFAULT_CFLAGS
 if ![info exists DEFAULT_CFLAGS] then {
@@ -348,6 +316,7 @@ if ![info exists DEFAULT_CFLAGS] then {
 
 # Initialize `dg'.
 dg-init
+clearcap-init
 
 # Special case compilation of vect-args.c so we don't have to
 # replicate it 10 times.
@@ -367,4 +336,5 @@ set tests [prune $tests $srcdir/$subdir/
 dg-runtest $tests "" $DEFAULT_CFLAGS
 
 # All done.
+clearcap-finish
 dg-finish
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/avx/abi-avx.exp b/gcc/testsuite/gcc.target/x86_64/abi/avx/abi-avx.exp
--- a/gcc/testsuite/gcc.target/x86_64/abi/avx/abi-avx.exp
+++ b/gcc/testsuite/gcc.target/x86_64/abi/avx/abi-avx.exp
@@ -20,6 +20,7 @@
 load_lib c-torture.exp
 load_lib target-supports.exp
 load_lib torture-options.exp
+load_lib clearcap.exp
 
 if { (![istarget x86_64-*-*] && ![istarget i?86-*-*])
      || ![is-effective-target lp64]
@@ -28,20 +29,10 @@ if { (![istarget x86_64-*-*] && ![istarg
 }
 
 
-# If the linker used understands -M <mapfile>, pass it to clear hardware
-# capabilities set by the Sun assembler.
-set flags ""
-set clearcap_ldflags "-Wl,-M,$srcdir/gcc.target/i386/clearcap.map"
-
-if [check_no_compiler_messages mapfile executable {
-	int main (void) { return 0; }
-  } $clearcap_ldflags ] {
-  set flags $clearcap_ldflags
-}
-
 torture-init
+clearcap-init
 set-torture-options $C_TORTURE_OPTIONS
-set additional_flags "-W -Wall -mavx $flags"
+set additional_flags "-W -Wall -mavx"
 
 foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] {
     if {[runtest_file_p $runtests $src]} {
@@ -58,4 +49,5 @@ foreach src [lsort [glob -nocomplain $sr
     }
 }
 
+clearcap-finish
 torture-finish
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/avx512f/abi-avx512f.exp b/gcc/testsuite/gcc.target/x86_64/abi/avx512f/abi-avx512f.exp
--- a/gcc/testsuite/gcc.target/x86_64/abi/avx512f/abi-avx512f.exp
+++ b/gcc/testsuite/gcc.target/x86_64/abi/avx512f/abi-avx512f.exp
@@ -20,6 +20,7 @@
 load_lib c-torture.exp
 load_lib target-supports.exp
 load_lib torture-options.exp
+load_lib clearcap.exp
 
 if { (![istarget x86_64-*-*] && ![istarget i?86-*-*])
      || ![is-effective-target lp64]
@@ -28,20 +29,10 @@ if { (![istarget x86_64-*-*] && ![istarg
 }
 
 
-# If the linker used understands -M <mapfile>, pass it to clear hardware
-# capabilities set by the Sun assembler.
-set flags ""
-set clearcap_ldflags "-Wl,-M,$srcdir/gcc.target/i386/clearcap.map"
-
-if [check_no_compiler_messages mapfile executable {
-	int main (void) { return 0; }
-  } $clearcap_ldflags ] {
-  set flags $clearcap_ldflags
-}
-
 torture-init
+clearcap-init
 set-torture-options $C_TORTURE_OPTIONS
-set additional_flags "-W -Wall -mavx512f $flags"
+set additional_flags "-W -Wall -mavx512f"
 
 foreach src [lsort [glob -nocomplain $srcdir/$subdir/test_*.c]] {
     if {[runtest_file_p $runtests $src]} {
@@ -58,4 +49,5 @@ foreach src [lsort [glob -nocomplain $sr
     }
 }
 
+clearcap-finish
 torture-finish
diff --git a/gcc/testsuite/lib/clearcap.exp b/gcc/testsuite/lib/clearcap.exp
new file mode 100644
--- /dev/null
+++ b/gcc/testsuite/lib/clearcap.exp
@@ -0,0 +1,58 @@
+# Copyright (C) 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Clear hardware capabilities on Solaris.
+if [istarget *-*-solaris2*] {
+    set clearcap_ldflags "-mclear-hwcap"
+}
+
+#
+# clearcap-init -- called at the start of each subdir of tests
+#
+
+proc clearcap-init { args } {
+    global TEST_ALWAYS_FLAGS
+    global ALWAYS_CXXFLAGS
+    global clearcap_saved_TEST_ALWAYS_FLAGS
+    global clearcap_ldflags
+
+    if [info exists TEST_ALWAYS_FLAGS] {
+	set clearcap_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS
+    }
+    if [info exists clearcap_ldflags] {
+	if [info exists ALWAYS_CXXFLAGS] {
+	    set ALWAYS_CXXFLAGS [concat "{ldflags=$clearcap_ldflags}" $ALWAYS_CXXFLAGS]
+	} else {
+	    append TEST_ALWAYS_FLAGS " $clearcap_ldflags"
+	}
+    }
+    return 0
+}
+
+#
+# clearcap-finish -- called at the start of each subdir of tests
+#
+
+proc clearcap-finish { args } {
+    global TEST_ALWAYS_FLAGS
+    global clearcap_saved_TEST_ALWAYS_FLAGS
+
+    if [info exists clearcap_saved_TEST_ALWAYS_FLAGS] {
+	set TEST_ALWAYS_FLAGS $clearcap_saved_TEST_ALWAYS_FLAGS
+    } else {
+	unset TEST_ALWAYS_FLAGS
+    }
+}
diff --git a/libitm/acinclude.m4 b/libitm/acinclude.m4
--- a/libitm/acinclude.m4
+++ b/libitm/acinclude.m4
@@ -301,10 +301,10 @@ 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 capabilities.  This is only supported on Solaris at the moment.
 dnl
 dnl Defines:
-dnl  HWCAP_LDFLAGS='-Wl,-M,clearcap.map' if possible
+dnl  HWCAP_LDFLAGS=-mclear-hwcap if possible
 dnl  LD (as a side effect of testing)
 dnl
 AC_DEFUN([LIBITM_CHECK_LINKER_HWCAP], [
@@ -312,12 +312,12 @@ AC_DEFUN([LIBITM_CHECK_LINKER_HWCAP], [
   AC_REQUIRE([AC_PROG_LD])
 
   ac_save_LDFLAGS="$LDFLAGS"
-  LDFLAGS="$LFLAGS -Wl,-M,$srcdir/clearcap.map"
+  LDFLAGS="$LFLAGS -mclear-hwcap"
 
-  AC_MSG_CHECKING([for ld that supports -Wl,-M,mapfile])
+  AC_MSG_CHECKING([for -mclear-hwcap])
   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"
+    HWCAP_LDFLAGS="-mclear-hwcap $HWCAP_LDFLAGS"
   fi
   AC_MSG_RESULT($ac_hwcap_ldflags)
 
diff --git a/libitm/clearcap.map b/libitm/clearcap.map
deleted file mode 100644
--- a/libitm/clearcap.map
+++ /dev/null
@@ -1,14 +0,0 @@
-# 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;
-#};
-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

Reply via email to