diff --git a/gcc-epel.spec b/gcc-epel.spec index 9a34417..547375d 100644 --- a/gcc-epel.spec +++ b/gcc-epel.spec @@ -1,10 +1,10 @@ -%global DATE 20220421 -%global gitrev 1d3172725999deb0dca93ac70393ed9a0ad0da3f +%global DATE 20221121 +%global gitrev 643e61c61b308f9c572da4ccd5f730fb %global gcc_version 11.3.1 %global gcc_major 11 # Note, gcc_release must be integer, if you want to add suffixes to # %%{release}, append them after %%{gcc_release} on Release: line. -%global gcc_release 4 +%global gcc_release 5 %global nvptx_tools_gitrev 5f6f343a302d620b0868edab376c00b15741e39e %global newlib_cygwin_gitrev 50e2a63b04bdd018484605fbb954fd1bd5147fa0 %global _unpackaged_files_terminate_build 0 @@ -44,7 +44,7 @@ %else %global build_go 0 %endif -%ifarch %{ix86} x86_64 %{arm} %{mips} s390 s390x riscv64 +%ifarch %{ix86} x86_64 %{arm} aarch64 %{mips} s390 s390x riscv64 %global build_d 1 %else %global build_d 0 @@ -115,6 +115,18 @@ %ifarch x86_64 %global multilib_32_arch i686 %endif +%if 0%{?rhel} == 9 +%ifarch x86_64 +%global build_cross 1 +%else +%global build_cross 0 +%endif +%else +%dnl rhel != 9 +%global build_cross 0 +%endif +# TODO: Add ppc64le-redhat-linux s390x-redhat-linux later. +%global cross_targets aarch64-redhat-linux # Override RHEL/derivative build options for gcc-epel %global epel_bootstrap 0 %global epel_glibc32 0 @@ -127,6 +139,7 @@ %if !0%{?epel_glibc32} %global multilib_64_archs noarch %endif +%global build_cross 0 Summary: Various compilers (C, C++, Objective-C, ...) Name: gcc-epel Version: %{gcc_version} @@ -325,9 +338,11 @@ Patch20: gcc11-relocatable-pch.patch Patch21: gcc11-dejagnu-multiline.patch Patch23: gcc11-pie.patch Patch24: gcc11-bind-now.patch -Patch25: gcc11-pr105331.patch -# This can go once we rebase from GCC 11. -Patch26: gcc11-rh2106262.patch +Patch25: gcc11-detect-sapphirerapids.patch +Patch26: gcc11-Wmismatched-dealloc-doc.patch +Patch27: gcc11-s390x-regarg-1.patch +Patch28: gcc11-s390x-regarg-2.patch +Patch29: gcc11-s390x-regarg-3.patch Patch100: gcc11-fortran-fdec-duplicates.patch Patch101: gcc11-fortran-flogical-as-integer.patch @@ -870,6 +885,45 @@ This package adds a version of the annobin plugin for gcc. This version of the plugin is explicitly built by the same version of gcc that is installed so that there cannot be any synchronization problems. +%package -n cross-gcc-aarch64 +Summary: Cross targeted AArch64 gcc for developer use. Not intended for production. +Provides: cross-gcc-aarch64 = %{version}-%{release} +%if %{build_cross} +Requires: cross-binutils-aarch64 >= 2.35 +BuildRequires: sysroot-aarch64-el9-glibc >= 2.34 +BuildRequires: cross-binutils-aarch64 >= 2.35 +%endif +# Don't provide e.g. liblto_plugin.so()(64bit). +AutoReqProv: no + +%description -n cross-gcc-aarch64 +This package contains a version of gcc that can compile code for AArch64 +(cross compiler). This cross compiler is intended for developers to use +during application development. This cross compiler is not intended for +production use, and output binary artifacts should not be used in +production. Generated binary artifacts contain binary annotations that +mark them as cross compiled. + +%package -n cross-gcc-c++-aarch64 +Summary: Cross targeted AArch64 gcc-c++ for developer use. Not intended for production. +Provides: cross-gcc-c++-aarch64 = %{version}-%{release} +%if %{build_cross} +Requires: cross-gcc-aarch64 = %{version}-%{release} +BuildRequires: sysroot-aarch64-el9-glibc >= 2.34 +BuildRequires: cross-binutils-aarch64 >= 2.35 +%endif +# ??? Otherwise this subpackage couldn't be installed, depends on libm.so +# and libgcc_s.so +AutoReqProv: no + +%description -n cross-gcc-c++-aarch64 +This package contains a version of g++ that can compile code for AArch64 +(cross compiler). This cross compiler is intended for developers to use +during application development. This cross compiler is not intended for +production use, and output binary artifacts should not be used in +production. Generated binary artifacts contain binary annotations that +mark them as cross compiled. + %prep %setup -q -n gcc-%{version}-%{DATE} -a 1 -a 2 -a 3 %patch0 -p0 -b .hack~ @@ -902,8 +956,11 @@ so that there cannot be any synchronization problems. %patch23 -p1 -b .pie~ %patch24 -p1 -b .now~ %endif -%patch25 -p0 -b .pr105331~ -%patch26 -p1 -b .rh2106262~ +%patch25 -p1 -b .detect-spr~ +%patch26 -p1 -b .Wmismatched-dealloc-doc~ +%patch27 -p1 -b .s390x-regarg-1~ +%patch28 -p1 -b .s390x-regarg-2~ +%patch29 -p1 -b .s390x-regarg-3~ %if 0%{?rhel} >= 9 %patch100 -p1 -b .fortran-fdec-duplicates~ @@ -922,7 +979,9 @@ so that there cannot be any synchronization problems. rm -f gcc/testsuite/go.test/test/fixedbugs/issue19182.go %endif -echo 'Red Hat %{version}-%{gcc_release}' > gcc/DEV-PHASE +echo 'Red Hat %{version}-%{gcc_release}' > gcc/DEV-PHASE.native +echo 'Red Hat %{version}-%{gcc_release} cross from %{_arch}' > gcc/DEV-PHASE.cross +cp -p gcc/DEV-PHASE{.native,} cp -a libstdc++-v3/config/cpu/i{4,3}86/atomicity.h @@ -1120,10 +1179,36 @@ enablelgo=,go %if %{build_d} enableld=,d %endif -CONFIGURE_OPTS="\ +# CONFIGURE_OPTS_BASE are the configure options common to the native and cross +# builds. E.g., --prefix. This cannot include arch-specific configure options. +# CONFIGURE_OPTS_NATIVE are the configure options used for the native build +# (that is, the regular non-cross build) and libgccjit. This includes arch-specific +# configure options (default -march and such). +# CONFIGURE_OPTS = CONFIGURE_OPTS_BASE + CONFIGURE_OPTS_NATIVE +# CONFIGURE_OPTS_CROSS are the configure options common to all the cross +# builds. E.g., only build C/C++. This shall not be used for the native build. +# Each cross compiler's configure options will be: +# CONFIGURE_OPTS_BASE + CONFIGURE_OPTS_CROSS + --target= + --with-sysroot= + +# It it very important that the arch-specific configure options used in +# CONFIGURE_OPTS_NATIVE are in lockstep with the +# used in the cross builds. +CONFIGURE_OPTS_BASE="\ --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir} \ --with-bugurl=http://bugzilla.redhat.com/bugzilla \ --enable-shared --enable-threads=posix --enable-checking=release \ + --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions \ + --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only \ + --enable-plugin --enable-initfini-array \ +%if %{build_isl} + --with-isl=`pwd`/isl-install \ +%else + --without-isl \ +%endif + " + +# NB: When updating CONFIGURE_OPTS_NATIVE, make sure to update the cross +# compiler options as well (look for CONFIGURE_OPTS_FOR_ARCH). +CONFIGURE_OPTS_NATIVE="\ %ifarch ppc64le --enable-targets=powerpcle-linux \ %endif @@ -1144,16 +1229,8 @@ CONFIGURE_OPTS="\ --disable-multilib \ %endif %endif - --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions \ - --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only \ %ifnarch %{mips} --with-linker-hash-style=gnu \ -%endif - --enable-plugin --enable-initfini-array \ -%if %{build_isl} - --with-isl=`pwd`/isl-install \ -%else - --without-isl \ %endif %if %{build_offload_nvptx} --enable-offload-targets=nvptx-none \ @@ -1268,6 +1345,16 @@ CONFIGURE_OPTS="\ %endif %endif " +CONFIGURE_OPTS="$CONFIGURE_OPTS_BASE $CONFIGURE_OPTS_NATIVE" + +CONFIGURE_OPTS_CROSS="\ + --enable-languages=c,c++ --disable-bootstrap --disable-libsanitizer \ + --host=%{gcc_target_platform} --build=%{gcc_target_platform} \ + --disable-multilib --disable-libstdcxx-pch --disable-libcc1 \ +%if 0 + --enable-host-pie --enable-host-bind-now \ +%endif + " CC="$CC" CXX="$CXX" CFLAGS="$OPT_FLAGS" \ CXXFLAGS="`echo " $OPT_FLAGS " | sed 's/ -Wall / /g;s/ -fexceptions / /g' \ @@ -1316,6 +1403,55 @@ make jit.sphinx.html make jit.sphinx.install-html jit_htmldir=`pwd`/../../rpm.doc/libgccjit-devel/html cd .. +# Build cross compilers here. +%if %{build_cross} +echo ==================== BUILD CROSS ========================= +# Get out of obj-%{gcc_target_platform}. +pushd .. +for crossarch in %{cross_targets}; do + mkdir obj-$crossarch + cd obj-$crossarch + + case $crossarch in + aarch64*) + CONFIGURE_OPTS_FOR_ARCH="" + ;; + s390x*) + CONFIGURE_OPTS_FOR_ARCH="" + ;; + ppc64le*) + CONFIGURE_OPTS_FOR_ARCH="" + ;; + *) + echo >&2 "ERROR: unknown cross arch $crossarch" + exit 1 + ;; + esac + + # Temporarily replace DEV-PHASE. + cp -p ../gcc/DEV-PHASE{.cross,} + + CC="$CC" CXX="$CXX" CFLAGS="$OPT_FLAGS" \ + CXXFLAGS="`echo " $OPT_FLAGS " | sed 's/ -Wall / /g;s/ -fexceptions / /g' \ + | sed 's/ -Wformat-security / -Wformat -Wformat-security /'`" \ + XCFLAGS="$OPT_FLAGS" TCFLAGS="$OPT_FLAGS" \ + ../configure $CONFIGURE_OPTS_BASE $CONFIGURE_OPTS_CROSS \ + --with-sysroot=/usr/$crossarch/sys-root/el9/ \ + --with-gxx-include-dir="/usr/$crossarch/sys-root/el9/%{_prefix}/include/c++/%{gcc_major}" \ + --target=$crossarch \ + $CONFIGURE_OPTS_FOR_ARCH + make %{?_smp_mflags} LDFLAGS_FOR_TARGET=-Wl,-z,relro,-z,now + + # Restore DEV-PHASE. + cp -p ../gcc/DEV-PHASE{.native,} + # Out of obj-$crossarch. + cd .. +done +# Go back to obj-%{gcc_target_platform}. +popd +echo ==================== BUILD CROSS END ========================= +%endif + %if %{build_isl} cp -a isl-install/lib/libisl.so.15 gcc/ %endif @@ -1518,6 +1654,126 @@ make prefix=%{buildroot}%{_prefix} mandir=%{buildroot}%{_mandir} \ chmod 644 %{buildroot}%{_infodir}/gnat* %endif +%if %{build_cross} +echo ==================== INSTALL CROSS ========================= +# Our of obj-%{gcc_target_platform}. +pushd .. +for crossarch in %{cross_targets}; do + cd obj-$crossarch + + CROSS_LIBPATH=%{buildroot}%{_prefix}/lib/gcc/$crossarch/%{gcc_major}/ + + # Temporarily replace DEV-PHASE. + cp -p ../gcc/DEV-PHASE{.cross,} + + # --with-gxx-include-dir= doesn't prefix its argument with $(DESTDIR) + # and you can't install things into /usr unless you're root. + mkdir scratch + scratchdir=`pwd`/scratch + pushd $crossarch/libstdc++-v3 + for i in `find . -name Makefile`; do + cp -a $i $i.save + sed -i -e 's?^gxx_include_dir = .*$?gxx_include_dir = '$scratchdir'?' $i + touch -r $i.save $i + done + popd + + # Use -j1, because build-many-glibcs says: + # Parallel "make install" for GCC has race conditions that can + # cause it to fail; see + # . Such + # problems are not known for binutils, but doing the + # installation in parallel within a particular toolchain build + # (as opposed to installation of one toolchain from + # build-many-glibcs.py running in parallel to the installation + # of other toolchains being built) is not known to be + # significantly beneficial, so it is simplest just to disable + # parallel install for cross tools here. + make -j1 prefix=%{buildroot}%{_prefix} mandir=%{buildroot}%{_mandir} \ + infodir=%{buildroot}%{_infodir} install + + # Restore DEV-PHASE. + cp -p ../gcc/DEV-PHASE{.native,} + + # Restore Makefiles with the old gxx_include_dir. + pushd $crossarch/libstdc++-v3 + for i in `find . -name Makefile`; do + mv -f $i.save $i + done + popd + # We're not shipping C++ headers; nuke 'em. + rm -rf $scratchdir + + # Move libgomp.spec to where it belongs for %files. + mv $crossarch/libgomp/libgomp.spec $CROSS_LIBPATH + # Likewise for libitm.spec + %if %{build_libitm} + mv $crossarch/libitm/libitm.spec $CROSS_LIBPATH + %endif + + cd .. + + pushd $CROSS_LIBPATH + mv include-fixed/syslimits.h include/syslimits.h + mv include-fixed/limits.h include/limits.h + popd + + echo '/* GNU ld script + Use the shared library, but some functions are only in + the static library. */ +OUTPUT_FORMAT(elf64-littleaarch64) +GROUP ( =/lib64/libgcc_s.so.1 libgcc.a )' > $CROSS_LIBPATH/libgcc_s.so + + echo '/* GNU ld script + Use the shared library from sysroot. */ +OUTPUT_FORMAT(elf64-littleaarch64) +INPUT ( =%{_prefix}/lib64/libgomp.so.1 )' > $CROSS_LIBPATH/libgomp.so + + echo '/* GNU ld script + Use the shared library from sysroot. */ +OUTPUT_FORMAT(elf64-littleaarch64) +INPUT ( =/%{_prefix}/lib64/libstdc++.so.6 )' > $CROSS_LIBPATH/libstdc++.so + + echo "/* GNU ld script + Use the static library from sysroot. */ +INPUT( =%{_prefix}/lib/gcc/$crossarch/%{gcc_major}/libstdc++.a )" > $CROSS_LIBPATH/libstdc++.a + + echo "/* GNU ld script + Use the static library from sysroot. */ +INPUT( =%{_prefix}/lib/gcc/$crossarch/%{gcc_major}/libsupc++.a )" > $CROSS_LIBPATH/libsupc++.a + + echo '/* GNU ld script + Use the shared library from sysroot. */ +OUTPUT_FORMAT(elf64-littleaarch64) +INPUT ( =%{_prefix}/lib64/libatomic.so.1 )' > $CROSS_LIBPATH/libatomic.so + + echo "/* GNU ld script + Use the static library from sysroot. */ +INPUT( =%{_prefix}/lib/gcc/$crossarch/%{gcc_major}/libatomic.a )" > $CROSS_LIBPATH/libatomic.a + + echo '/* GNU ld script + Use the shared library from sysroot. */ +OUTPUT_FORMAT(elf64-littleaarch64) +INPUT ( =%{_prefix}/lib64/libitm.so.1 )' > $CROSS_LIBPATH/libitm.so + + echo "/* GNU ld script + Use the static library from sysroot. */ +INPUT( =%{_prefix}/lib/gcc/$crossarch/%{gcc_major}/libitm.a )" > $CROSS_LIBPATH/libitm.a + + # Help plugins find out nvra. + echo gcc-%{version}-%{release}.%{_arch} > $CROSS_LIBPATH/rpmver + + # TODO + # Add symlink to lto plugin in the binutils plugin directory. + #%{__mkdir_p} %{buildroot}%{_libdir}/bfd-plugins/ + #ln -s ../../libexec/gcc/$crossarch/%{gcc_major}/liblto_plugin.so \ + # %{buildroot}%{_libdir}/$crossarch/bfd-plugins/ +done +# Back to obj-%{gcc_target_platform}. +popd +echo ==================== INSTALL CROSS END ========================= +%endif + FULLPATH=%{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major} FULLEPATH=%{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major} @@ -3469,7 +3725,67 @@ end %{ANNOBIN_GCC_PLUGIN_DIR}/gcc-annobin.so.0.0.0 %endif +%if %{build_cross} +%files -n cross-gcc-aarch64 +%{_prefix}/bin/aarch64-redhat-linux-cpp +%{_prefix}/bin/aarch64-redhat-linux-gcc +%{_prefix}/bin/aarch64-redhat-linux-gcc-%{gcc_major} +%{_prefix}/bin/aarch64-redhat-linux-gcc-ar +%{_prefix}/bin/aarch64-redhat-linux-gcc-nm +%{_prefix}/bin/aarch64-redhat-linux-gcc-ranlib +%{_prefix}/bin/aarch64-redhat-linux-gcov* +%{_prefix}/bin/aarch64-redhat-linux-lto-dump +%{_prefix}/libexec/gcc/aarch64-redhat-linux/%{gcc_major}/cc1 +%{_prefix}/libexec/gcc/aarch64-redhat-linux/%{gcc_major}/collect2 +%{_prefix}/libexec/gcc/aarch64-redhat-linux/%{gcc_major}/lto1 +%{_prefix}/libexec/gcc/aarch64-redhat-linux/%{gcc_major}/lto-wrapper +%{_prefix}/libexec/gcc/aarch64-redhat-linux/%{gcc_major}/liblto_plugin.so +%dir %{_prefix}/lib/gcc +%dir %{_prefix}/lib/gcc/aarch64-redhat-linux +%dir %{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major} +%dir %{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/include +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/crt*.o +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libgcc.a +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libgcc_eh.a +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libgcov.a +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/include/*.h +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/rpmver +# These are here for ld(1) purposes only. +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libgcc_s.so +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libgomp.so +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libgomp.spec +%if %{build_libatomic} +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libatomic.so +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libatomic.a +%endif +%if %{build_libitm} +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libitm.so +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libitm.a +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libitm.spec +%endif + +%files -n cross-gcc-c++-aarch64 +%{_prefix}/bin/aarch64-redhat-linux-c++ +%{_prefix}/bin/aarch64-redhat-linux-g++ +%{_prefix}/libexec/gcc/aarch64-redhat-linux/%{gcc_major}/cc1plus +%{_prefix}/libexec/gcc/aarch64-redhat-linux/%{gcc_major}/g++-mapper-server +# For ld(1) purposes only. +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libstdc++.so +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libstdc++.a +%{_prefix}/lib/gcc/aarch64-redhat-linux/%{gcc_major}/libsupc++.a +%dnl build_cross +%endif + %changelog +* Thu Jun 08 2023 Robert Scheck 11.3.1-5 +- backport from 11.3.1-4.4: s390x: add support for register arguments preserving (#2168204) +- backport from 11.3.1-4.3: compile the cross binaries as PIE/-z now (#2155452) +- backport from 11.3.1-4.2: ship libitm.spec in cross-gcc (#2154462) +- backport from 11.3.1-4.1: add cross compiler functionality for non-production uses (#2149650) +- backport from 11.3.1-4: update from releases/gcc-11-branch (#2117632) +- backport from 11.3.1-4: fix the detection of Sapphire Rapids in host_detect_local_cpu +- backport from 11.3.1-4: fix -Wmismatched-dealloc documentation (#2116635) + * Thu Nov 17 2022 Robert Scheck 11.3.1-4 - disable bootstrap mode and rebuild using gcc-epel-11.3.1-3.el9 diff --git a/gcc11-Wmismatched-dealloc-doc.patch b/gcc11-Wmismatched-dealloc-doc.patch new file mode 100644 index 0000000..134fb18 --- /dev/null +++ b/gcc11-Wmismatched-dealloc-doc.patch @@ -0,0 +1,79 @@ +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 3419483c532..a2a6b1c98be 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -255,7 +255,7 @@ in the following sections. + -Wno-inherited-variadic-ctor -Wno-init-list-lifetime @gol + -Winvalid-imported-macros @gol + -Wno-invalid-offsetof -Wno-literal-suffix @gol +--Wno-mismatched-new-delete -Wmismatched-tags @gol ++-Wmismatched-new-delete -Wmismatched-tags @gol + -Wmultiple-inheritance -Wnamespaces -Wnarrowing @gol + -Wnoexcept -Wnoexcept-type -Wnon-virtual-dtor @gol + -Wpessimizing-move -Wno-placement-new -Wplacement-new=@var{n} @gol +@@ -3966,7 +3966,7 @@ The warning is inactive inside a system header file, such as the STL, so + one can still use the STL. One may also instantiate or specialize + templates. + +-@item -Wno-mismatched-new-delete @r{(C++ and Objective-C++ only)} ++@item -Wmismatched-new-delete @r{(C++ and Objective-C++ only)} + @opindex Wmismatched-new-delete + @opindex Wno-mismatched-new-delete + Warn for mismatches between calls to @code{operator new} or @code{operator +@@ -3998,7 +3998,7 @@ The related option @option{-Wmismatched-dealloc} diagnoses mismatches + involving allocation and deallocation functions other than @code{operator + new} and @code{operator delete}. + +-@option{-Wmismatched-new-delete} is enabled by default. ++@option{-Wmismatched-new-delete} is included in @option{-Wall}. + + @item -Wmismatched-tags @r{(C++ and Objective-C++ only)} + @opindex Wmismatched-tags +@@ -5543,6 +5543,8 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}. + -Wmemset-elt-size @gol + -Wmemset-transposed-args @gol + -Wmisleading-indentation @r{(only for C/C++)} @gol ++-Wmismatched-dealloc @gol ++-Wmismatched-new-delete @r{(only for C/C++)} @gol + -Wmissing-attributes @gol + -Wmissing-braces @r{(only for C/ObjC)} @gol + -Wmultistatement-macros @gol +@@ -6428,7 +6430,7 @@ Ignoring the warning can result in poorly optimized code. + disable the warning, but this is not recommended and should be done only + when non-existent profile data is justified. + +-@item -Wno-mismatched-dealloc ++@item -Wmismatched-dealloc + @opindex Wmismatched-dealloc + @opindex Wno-mismatched-dealloc + +@@ -6461,7 +6463,7 @@ void f (void) + In C++, the related option @option{-Wmismatched-new-delete} diagnoses + mismatches involving either @code{operator new} or @code{operator delete}. + +-Option @option{-Wmismatched-dealloc} is enabled by default. ++Option @option{-Wmismatched-dealloc} is included in @option{-Wall}. + + @item -Wmultistatement-macros + @opindex Wmultistatement-macros +@@ -7951,9 +7953,9 @@ Warnings controlled by the option can be disabled either by specifying + Disable @option{-Wframe-larger-than=} warnings. The option is equivalent + to @option{-Wframe-larger-than=}@samp{SIZE_MAX} or larger. + +-@item -Wno-free-nonheap-object +-@opindex Wno-free-nonheap-object ++@item -Wfree-nonheap-object + @opindex Wfree-nonheap-object ++@opindex Wno-free-nonheap-object + Warn when attempting to deallocate an object that was either not allocated + on the heap, or by using a pointer that was not returned from a prior call + to the corresponding allocation function. For example, because the call +@@ -7970,7 +7972,7 @@ void f (char *p) + @} + @end smallexample + +-@option{-Wfree-nonheap-object} is enabled by default. ++@option{-Wfree-nonheap-object} is included in @option{-Wall}. + + @item -Wstack-usage=@var{byte-size} + @opindex Wstack-usage diff --git a/gcc11-detect-sapphirerapids.patch b/gcc11-detect-sapphirerapids.patch new file mode 100644 index 0000000..c130e4b --- /dev/null +++ b/gcc11-detect-sapphirerapids.patch @@ -0,0 +1,69 @@ +commit 63dd214dce603f4f99e2cb272255b6c2b4308c3d +Author: Cui,Lili +Date: Mon Nov 7 11:25:41 2022 +0800 + + Remove AVX512_VP2INTERSECT from PTA_SAPPHIRERAPIDS + + gcc/ChangeLog: + + * config/i386/driver-i386.cc (host_detect_local_cpu): + Move sapphirerapids out of AVX512_VP2INTERSECT. + * config/i386/i386.h: Remove AVX512_VP2INTERSECT from PTA_SAPPHIRERAPIDS + * doc/invoke.texi: Remove AVX512_VP2INTERSECT from SAPPHIRERAPIDS + + (cherry picked from commit d644dfe36d9733c767af62d37250253ced6efd8c) + +diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c +index f844a168ddb..90f84aba4ee 100644 +--- a/gcc/config/i386/driver-i386.c ++++ b/gcc/config/i386/driver-i386.c +@@ -574,15 +574,12 @@ const char *host_detect_local_cpu (int argc, const char **argv) + /* This is unknown family 0x6 CPU. */ + if (has_feature (FEATURE_AVX)) + { ++ /* Assume Tiger Lake */ + if (has_feature (FEATURE_AVX512VP2INTERSECT)) +- { +- if (has_feature (FEATURE_TSXLDTRK)) +- /* Assume Sapphire Rapids. */ +- cpu = "sapphirerapids"; +- else +- /* Assume Tiger Lake */ +- cpu = "tigerlake"; +- } ++ cpu = "tigerlake"; ++ /* Assume Sapphire Rapids. */ ++ else if (has_feature (FEATURE_TSXLDTRK)) ++ cpu = "sapphirerapids"; + /* Assume Cooper Lake */ + else if (has_feature (FEATURE_AVX512BF16)) + cpu = "cooperlake"; +diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h +index ac0e5da623c..e03279bcf39 100644 +--- a/gcc/config/i386/i386.h ++++ b/gcc/config/i386/i386.h +@@ -2562,7 +2562,7 @@ constexpr wide_int_bitmask PTA_ICELAKE_SERVER = PTA_ICELAKE_CLIENT + constexpr wide_int_bitmask PTA_TIGERLAKE = PTA_ICELAKE_CLIENT | PTA_MOVDIRI + | PTA_MOVDIR64B | PTA_CLWB | PTA_AVX512VP2INTERSECT | PTA_KL | PTA_WIDEKL; + constexpr wide_int_bitmask PTA_SAPPHIRERAPIDS = PTA_ICELAKE_SERVER | PTA_MOVDIRI +- | PTA_MOVDIR64B | PTA_AVX512VP2INTERSECT | PTA_ENQCMD | PTA_CLDEMOTE ++ | PTA_MOVDIR64B | PTA_ENQCMD | PTA_CLDEMOTE + | PTA_PTWRITE | PTA_WAITPKG | PTA_SERIALIZE | PTA_TSXLDTRK | PTA_AMX_TILE + | PTA_AMX_INT8 | PTA_AMX_BF16 | PTA_UINTR | PTA_AVXVNNI | PTA_AVX512BF16; + constexpr wide_int_bitmask PTA_KNL = PTA_BROADWELL | PTA_AVX512PF +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 3419483c532..6b3afb827a5 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -30236,9 +30236,9 @@ Intel sapphirerapids CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, + SSSE3, SSE4.1, SSE4.2, POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE, + RDRND, F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW, + AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW, AVX512DQ, +-AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2 ++AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2, + VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ, PCONFIG, WBNOINVD, CLWB, +-MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, ++MOVDIRI, MOVDIR64B, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, + SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI and + AVX512BF16 instruction set support. + diff --git a/gcc11-pr105331.patch b/gcc11-pr105331.patch deleted file mode 100644 index fa1a9d3..0000000 --- a/gcc11-pr105331.patch +++ /dev/null @@ -1,33 +0,0 @@ -2022-04-21 Jakub Jelinek - - PR target/105331 - * config/i386/i386.c (ix86_gimplify_va_arg): Mark va_arg_tmp - temporary TREE_ADDRESSABLE before trying to gimplify ADDR_EXPR - of it. - - * gcc.dg/pr105331.c: New test. - ---- gcc/config/i386/i386.c.jj 2022-04-12 09:20:07.566662842 +0200 -+++ gcc/config/i386/i386.c 2022-04-21 12:03:32.201951522 +0200 -@@ -4891,6 +4891,7 @@ ix86_gimplify_va_arg (tree valist, tree - { - int i, prev_size = 0; - tree temp = create_tmp_var (type, "va_arg_tmp"); -+ TREE_ADDRESSABLE (temp) = 1; - - /* addr = &temp; */ - t = build1 (ADDR_EXPR, build_pointer_type (type), temp); ---- gcc/testsuite/gcc.dg/pr105331.c.jj 2022-04-21 12:09:34.398906718 +0200 -+++ gcc/testsuite/gcc.dg/pr105331.c 2022-04-21 12:09:07.304283903 +0200 -@@ -0,0 +1,11 @@ -+/* PR target/105331 */ -+/* { dg-do compile } */ -+/* { dg-options "-O -Wuninitialized" } */ -+ -+#include -+ -+int -+foo (va_list *va) -+{ -+ return va_arg (*va, double _Complex); /* { dg-bogus "may be used uninitialized" } */ -+} diff --git a/gcc11-rh2106262.patch b/gcc11-rh2106262.patch deleted file mode 100644 index 34e9c5b..0000000 --- a/gcc11-rh2106262.patch +++ /dev/null @@ -1,388 +0,0 @@ -commit c725028a8bb9478ec84332641147ad12b9236922 -Author: Jonathan Wakely -Date: Tue Dec 14 14:32:35 2021 +0000 - - libstdc++: Fix handling of invalid ranges in std::regex [PR102447] - - std::regex currently allows invalid bracket ranges such as [\w-a] which - are only allowed by ECMAScript when in web browser compatibility mode. - It should be an error, because the start of the range is a character - class, not a single character. The current implementation of - _Compiler::_M_expression_term does not provide a way to reject this, - because we only remember a previous character, not whether we just - processed a character class (or collating symbol etc.) - - This patch replaces the pair used to emulate - optional with a custom class closer to pair. That - allows us to track three states, so that we can tell when we've just - seen a character class. - - With this additional state the code in _M_expression_term for processing - the _S_token_bracket_dash can be improved to correctly reject the [\w-a] - case, without regressing for valid cases such as [\w-] and [----]. - - libstdc++-v3/ChangeLog: - - PR libstdc++/102447 - * include/bits/regex_compiler.h (_Compiler::_BracketState): New - class. - (_Compiler::_BrackeyMatcher): New alias template. - (_Compiler::_M_expression_term): Change pair - parameter to _BracketState. Process first character for - ECMAScript syntax as well as POSIX. - * include/bits/regex_compiler.tcc - (_Compiler::_M_insert_bracket_matcher): Pass _BracketState. - (_Compiler::_M_expression_term): Use _BracketState to store - state between calls. Improve handling of dashes in ranges. - * testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc: - Add more tests for ranges containing dashes. Check invalid - ranges with character class at the beginning. - - (cherry picked from commit 7ce3c230edf6e498e125c805a6dd313bf87dc439) - -diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h -index f224fcb06e0..aa19df2bf9a 100644 ---- a/libstdc++-v3/include/bits/regex_compiler.h -+++ b/libstdc++-v3/include/bits/regex_compiler.h -@@ -122,13 +122,45 @@ namespace __detail - void - _M_insert_bracket_matcher(bool __neg); - -- // Returns true if successfully matched one term and should continue. -+ // Cache of the last atom seen in a bracketed range expression. -+ struct _BracketState -+ { -+ enum class _Type : char { _None, _Char, _Class } _M_type = _Type::_None; -+ _CharT _M_char; -+ -+ void -+ set(_CharT __c) noexcept { _M_type = _Type::_Char; _M_char = __c; } -+ -+ _GLIBCXX_NODISCARD _CharT -+ get() const noexcept { return _M_char; } -+ -+ void -+ reset(_Type __t = _Type::_None) noexcept { _M_type = __t; } -+ -+ explicit operator bool() const noexcept -+ { return _M_type != _Type::_None; } -+ -+ // Previous token was a single character. -+ _GLIBCXX_NODISCARD bool -+ _M_is_char() const noexcept { return _M_type == _Type::_Char; } -+ -+ // Previous token was a character class, equivalent class, -+ // collating symbol etc. -+ _GLIBCXX_NODISCARD bool -+ _M_is_class() const noexcept { return _M_type == _Type::_Class; } -+ }; -+ -+ template -+ using _BracketMatcher -+ = std::__detail::_BracketMatcher<_TraitsT, __icase, __collate>; -+ -+ // Returns true if successfully parsed one term and should continue -+ // compiling a bracket expression. - // Returns false if the compiler should move on. - template - bool -- _M_expression_term(pair& __last_char, -- _BracketMatcher<_TraitsT, __icase, __collate>& -- __matcher); -+ _M_expression_term(_BracketState& __last_char, -+ _BracketMatcher<__icase, __collate>& __matcher); - - int - _M_cur_int_value(int __radix); -diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc -index ea07bc2428e..7769a9e63a3 100644 ---- a/libstdc++-v3/include/bits/regex_compiler.tcc -+++ b/libstdc++-v3/include/bits/regex_compiler.tcc -@@ -403,7 +403,7 @@ namespace __detail - _M_insert_character_class_matcher() - { - __glibcxx_assert(_M_value.size() == 1); -- _BracketMatcher<_TraitsT, __icase, __collate> __matcher -+ _BracketMatcher<__icase, __collate> __matcher - (_M_ctype.is(_CtypeT::upper, _M_value[0]), _M_traits); - __matcher._M_add_character_class(_M_value, false); - __matcher._M_ready(); -@@ -424,25 +424,17 @@ namespace __detail - _Compiler<_TraitsT>:: - _M_insert_bracket_matcher(bool __neg) - { -- _BracketMatcher<_TraitsT, __icase, __collate> __matcher(__neg, _M_traits); -- pair __last_char; // Optional<_CharT> -- __last_char.first = false; -- if (!(_M_flags & regex_constants::ECMAScript)) -- { -- if (_M_try_char()) -- { -- __last_char.first = true; -- __last_char.second = _M_value[0]; -- } -- else if (_M_match_token(_ScannerT::_S_token_bracket_dash)) -- { -- __last_char.first = true; -- __last_char.second = '-'; -- } -- } -- while (_M_expression_term(__last_char, __matcher)); -- if (__last_char.first) -- __matcher._M_add_char(__last_char.second); -+ _BracketMatcher<__icase, __collate> __matcher(__neg, _M_traits); -+ _BracketState __last_char; -+ if (_M_try_char()) -+ __last_char.set(_M_value[0]); -+ else if (_M_match_token(_ScannerT::_S_token_bracket_dash)) -+ // Dash as first character is a normal character. -+ __last_char.set('-'); -+ while (_M_expression_term(__last_char, __matcher)) -+ ; -+ if (__last_char._M_is_char()) -+ __matcher._M_add_char(__last_char.get()); - __matcher._M_ready(); - _M_stack.push(_StateSeqT( - *_M_nfa, -@@ -447,27 +438,27 @@ namespace __detail - template - bool - _Compiler<_TraitsT>:: -- _M_expression_term(pair& __last_char, -- _BracketMatcher<_TraitsT, __icase, __collate>& __matcher) -+ _M_expression_term(_BracketState& __last_char, -+ _BracketMatcher<__icase, __collate>& __matcher) - { - if (_M_match_token(_ScannerT::_S_token_bracket_end)) - return false; - -+ // Add any previously cached char into the matcher and update cache. - const auto __push_char = [&](_CharT __ch) - { -- if (__last_char.first) -- __matcher._M_add_char(__last_char.second); -- else -- __last_char.first = true; -- __last_char.second = __ch; -+ if (__last_char._M_is_char()) -+ __matcher._M_add_char(__last_char.get()); -+ __last_char.set(__ch); - }; -- const auto __flush = [&] -+ // Add any previously cached char into the matcher and update cache. -+ const auto __push_class = [&] - { -- if (__last_char.first) -- { -- __matcher._M_add_char(__last_char.second); -- __last_char.first = false; -- } -+ if (__last_char._M_is_char()) -+ __matcher._M_add_char(__last_char.get()); -+ // We don't cache anything here, just record that the last thing -+ // processed was a character class (or similar). -+ __last_char.reset(_BracketState::_Type::_Class); - }; - - if (_M_match_token(_ScannerT::_S_token_collsymbol)) -@@ -476,16 +467,16 @@ namespace __detail - if (__symbol.size() == 1) - __push_char(__symbol[0]); - else -- __flush(); -+ __push_class(); - } - else if (_M_match_token(_ScannerT::_S_token_equiv_class_name)) - { -- __flush(); -+ __push_class(); - __matcher._M_add_equivalence_class(_M_value); - } - else if (_M_match_token(_ScannerT::_S_token_char_class_name)) - { -- __flush(); -+ __push_class(); - __matcher._M_add_character_class(_M_value, false); - } - else if (_M_try_char()) -@@ -502,49 +493,50 @@ namespace __detail - // It turns out that no one reads BNFs ;) - else if (_M_match_token(_ScannerT::_S_token_bracket_dash)) - { -- if (!__last_char.first) -+ if (_M_match_token(_ScannerT::_S_token_bracket_end)) - { -- if (!(_M_flags & regex_constants::ECMAScript)) -- { -- if (_M_match_token(_ScannerT::_S_token_bracket_end)) -- { -- __push_char('-'); -- return false; -- } -- __throw_regex_error( -- regex_constants::error_range, -- "Unexpected dash in bracket expression. For POSIX syntax, " -- "a dash is not treated literally only when it is at " -- "beginning or end."); -- } -+ // For "-]" the dash is a literal character. - __push_char('-'); -+ return false; - } -- else -+ else if (__last_char._M_is_class()) -+ { -+ // "\\w-" is invalid, start of range must be a single char. -+ __throw_regex_error(regex_constants::error_range, -+ "Invalid start of range in bracket expression."); -+ } -+ else if (__last_char._M_is_char()) - { - if (_M_try_char()) - { -- __matcher._M_make_range(__last_char.second, _M_value[0]); -- __last_char.first = false; -+ // "x-y" -+ __matcher._M_make_range(__last_char.get(), _M_value[0]); -+ __last_char.reset(); - } - else if (_M_match_token(_ScannerT::_S_token_bracket_dash)) - { -- __matcher._M_make_range(__last_char.second, '-'); -- __last_char.first = false; -+ // "x--" -+ __matcher._M_make_range(__last_char.get(), '-'); -+ __last_char.reset(); - } - else -- { -- if (_M_scanner._M_get_token() -- != _ScannerT::_S_token_bracket_end) -- __throw_regex_error( -- regex_constants::error_range, -- "Character is expected after a dash."); -- __push_char('-'); -- } -+ __throw_regex_error(regex_constants::error_range, -+ "Invalid end of range in bracket expression."); - } -+ else if (_M_flags & regex_constants::ECMAScript) -+ { -+ // A dash that is not part of an existing range. Might be the -+ // start of a new range, or might just be a literal '-' char. -+ // Only ECMAScript allows that in the middle of a bracket expr. -+ __push_char('-'); -+ } -+ else -+ __throw_regex_error(regex_constants::error_range, -+ "Invalid dash in bracket expression."); - } - else if (_M_match_token(_ScannerT::_S_token_quoted_class)) - { -- __flush(); -+ __push_class(); - __matcher._M_add_character_class(_M_value, - _M_ctype.is(_CtypeT::upper, - _M_value[0])); -diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc -index 7df70604ea6..0d76e63da7b 100644 ---- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc -+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc -@@ -69,6 +69,16 @@ test01() - void - test02() - { -+ VERIFY(regex_match("-", regex("[-]", regex_constants::ECMAScript))); -+ VERIFY(regex_match("-", regex("[--]", regex_constants::ECMAScript))); -+ VERIFY(regex_match("-", regex("[---]", regex_constants::ECMAScript))); -+ VERIFY(regex_match("-", regex("[----]", regex_constants::ECMAScript))); -+ VERIFY(regex_match("-", regex("[-----]", regex_constants::ECMAScript))); -+ -+ VERIFY(regex_match("-", regex("[-]", regex_constants::extended))); -+ VERIFY(regex_match("-", regex("[--]", regex_constants::extended))); -+ VERIFY(regex_match("-", regex("[---]", regex_constants::extended))); -+ VERIFY(regex_match("-", regex("[----]", regex_constants::extended))); - try - { - std::regex re("[-----]", std::regex::extended); -@@ -78,7 +88,6 @@ test02() - { - VERIFY(e.code() == std::regex_constants::error_range); - } -- std::regex re("[-----]", std::regex::ECMAScript); - - VERIFY(!regex_match("b", regex("[-ac]", regex_constants::extended))); - VERIFY(!regex_match("b", regex("[ac-]", regex_constants::extended))); -@@ -93,7 +102,27 @@ test02() - } - catch (const std::regex_error& e) - { -+ VERIFY(e.code() == std::regex_constants::error_range); -+ } -+ try -+ { -+ regex("[@--]", regex_constants::extended); -+ VERIFY(false); - } -+ catch (const std::regex_error& e) -+ { -+ VERIFY(e.code() == std::regex_constants::error_range); -+ } -+ try -+ { -+ regex("[--%]", regex_constants::extended); -+ VERIFY(false); -+ } -+ catch (const std::regex_error& e) -+ { -+ VERIFY(e.code() == std::regex_constants::error_range); -+ } -+ - VERIFY(regex_match("].", regex("[][.hyphen.]-0]*", regex_constants::extended))); - } - -@@ -158,6 +187,36 @@ test06() - VERIFY(regex_match("a-", debian_cron_namespace_ok)); - } - -+// libstdc++/102447 -+void -+test07() -+{ -+ VERIFY(regex_match("-", std::regex("[\\w-]", std::regex::ECMAScript))); -+ VERIFY(regex_match("a", std::regex("[\\w-]", std::regex::ECMAScript))); -+ VERIFY(regex_match("-", std::regex("[a-]", std::regex::ECMAScript))); -+ VERIFY(regex_match("a", std::regex("[a-]", std::regex::ECMAScript))); -+ -+ try -+ { -+ std::regex re("[\\w-a]", std::regex::ECMAScript); -+ VERIFY(false); -+ } -+ catch (const std::regex_error& e) -+ { -+ VERIFY(e.code() == std::regex_constants::error_range); -+ } -+ -+ try -+ { -+ std::regex re("[\\w--]", std::regex::ECMAScript); -+ VERIFY(false); -+ } -+ catch (const std::regex_error& e) -+ { -+ VERIFY(e.code() == std::regex_constants::error_range); -+ } -+} -+ - int - main() - { -@@ -167,6 +226,7 @@ main() - test04(); - test05(); - test06(); -+ test07(); - - return 0; - } diff --git a/gcc11-s390x-regarg-1.patch b/gcc11-s390x-regarg-1.patch new file mode 100644 index 0000000..b8de714 --- /dev/null +++ b/gcc11-s390x-regarg-1.patch @@ -0,0 +1,91 @@ +commit ef5f7b89bbc352255595069eb870d6f30f1f9134 +Author: Andreas Krebbel +Date: Wed Feb 1 08:59:41 2023 +0100 + + New reg note REG_CFA_NORESTORE + + This patch introduces a new reg note which can be used to tell the CFI + verification in dwarf2cfi that a register is stored without intending + to restore from it. + + This is useful when storing e.g. register contents to the stack and + generate CFI for it although the register is not really supposed to be + restored. + + gcc/ChangeLog: + + * dwarf2cfi.c (dwarf2out_frame_debug_cfa_restore): Add + EMIT_CFI parameter. + (dwarf2out_frame_debug): Add case for REG_CFA_NORESTORE. + * reg-notes.def (REG_CFA_NOTE): New reg note definition. + +--- a/gcc/dwarf2cfi.c ++++ b/gcc/dwarf2cfi.c +@@ -1496,10 +1496,12 @@ dwarf2out_frame_debug_cfa_val_expression (rtx set) + update_row_reg_save (cur_row, dwf_regno (dest), cfi); + } + +-/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE note. */ ++/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE ++ note. When called with EMIT_CFI set to false emitting a CFI ++ statement is suppressed. */ + + static void +-dwarf2out_frame_debug_cfa_restore (rtx reg) ++dwarf2out_frame_debug_cfa_restore (rtx reg, bool emit_cfi) + { + gcc_assert (REG_P (reg)); + +@@ -1507,7 +1509,8 @@ dwarf2out_frame_debug_cfa_restore (rtx reg) + if (!span) + { + unsigned int regno = dwf_regno (reg); +- add_cfi_restore (regno); ++ if (emit_cfi) ++ add_cfi_restore (regno); + update_row_reg_save (cur_row, regno, NULL); + } + else +@@ -1522,7 +1525,8 @@ dwarf2out_frame_debug_cfa_restore (rtx reg) + reg = XVECEXP (span, 0, par_index); + gcc_assert (REG_P (reg)); + unsigned int regno = dwf_regno (reg); +- add_cfi_restore (regno); ++ if (emit_cfi) ++ add_cfi_restore (regno); + update_row_reg_save (cur_row, regno, NULL); + } + } +@@ -2309,6 +2313,7 @@ dwarf2out_frame_debug (rtx_insn *insn) + break; + + case REG_CFA_RESTORE: ++ case REG_CFA_NO_RESTORE: + n = XEXP (note, 0); + if (n == NULL) + { +@@ -2317,7 +2322,7 @@ dwarf2out_frame_debug (rtx_insn *insn) + n = XVECEXP (n, 0, 0); + n = XEXP (n, 0); + } +- dwarf2out_frame_debug_cfa_restore (n); ++ dwarf2out_frame_debug_cfa_restore (n, REG_NOTE_KIND (note) == REG_CFA_RESTORE); + handled_one = true; + break; + +diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def +index 23de1f13ee9..1f74a605b3e 100644 +--- a/gcc/reg-notes.def ++++ b/gcc/reg-notes.def +@@ -157,6 +157,11 @@ REG_CFA_NOTE (CFA_VAL_EXPRESSION) + first pattern is the register to be restored. */ + REG_CFA_NOTE (CFA_RESTORE) + ++/* Like CFA_RESTORE but without actually emitting CFI. This can be ++ used to tell the verification infrastructure that a register is ++ saved without intending to restore it. */ ++REG_CFA_NOTE (CFA_NO_RESTORE) ++ + /* Attached to insns that are RTX_FRAME_RELATED_P, marks insn that sets + vDRAP from DRAP. If vDRAP is a register, vdrap_reg is initalized + to the argument, if it is a MEM, it is ignored. */ diff --git a/gcc11-s390x-regarg-2.patch b/gcc11-s390x-regarg-2.patch new file mode 100644 index 0000000..c4ae464 --- /dev/null +++ b/gcc11-s390x-regarg-2.patch @@ -0,0 +1,92 @@ +commit 36ffb2e0293d1bbef30e3553a431679de00549b9 +Author: Andreas Krebbel +Date: Wed Feb 1 08:59:42 2023 +0100 + + IBM zSystems: Make stack_tie to work with hard frame pointer + + With this patch a scheduling barrier is created to prevent the insn + setting up the frame-pointer and instructions which save GPRs to the + stack to be swapped. Otherwise broken CFI information would be + generated since the stack save insns would use a base register which + is not currently declared as holding the CFA. + + Without -mpreserve-args this did not happen because the store multiple + we used for saving the GPRs would also cover the frame-pointer + register and therefore creates a dependency on the frame-pointer + hardreg. However, with this patch the stack_tie is emitted regardless + of -mpreserve-args since this in general appears to be the safer + approach. + + * config/s390/s390.c (save_gprs): Use gen_frame_mem. + (restore_gprs): Likewise. + (s390_emit_stack_tie): Make the stack_tie to be dependent on the + frame pointer if a frame-pointer is used. + (s390_emit_prologue): Emit stack_tie when frame-pointer is needed. + * config/s390/s390.md (stack_tie): Add a register operand and + rename to ... + (@stack_tie): ... this. + +--- a/gcc/config/s390/s390.c ++++ b/gcc/config/s390/s390.c +@@ -10898,9 +10898,7 @@ save_gprs (rtx base, int offset, int first, int last) + int i; + + addr = plus_constant (Pmode, base, offset); +- addr = gen_rtx_MEM (Pmode, addr); +- +- set_mem_alias_set (addr, get_frame_alias_set ()); ++ addr = gen_frame_mem (Pmode, addr); + + /* Special-case single register. */ + if (first == last) +@@ -11012,8 +11010,7 @@ restore_gprs (rtx base, int offset, int first, int last) + rtx addr, insn; + + addr = plus_constant (Pmode, base, offset); +- addr = gen_rtx_MEM (Pmode, addr); +- set_mem_alias_set (addr, get_frame_alias_set ()); ++ addr = gen_frame_mem (Pmode, addr); + + /* Special-case single register. */ + if (first == last) +@@ -11062,10 +11059,11 @@ s390_load_got (void) + static void + s390_emit_stack_tie (void) + { +- rtx mem = gen_frame_mem (BLKmode, +- gen_rtx_REG (Pmode, STACK_POINTER_REGNUM)); +- +- emit_insn (gen_stack_tie (mem)); ++ rtx mem = gen_frame_mem (BLKmode, stack_pointer_rtx); ++ if (frame_pointer_needed) ++ emit_insn (gen_stack_tie (Pmode, mem, hard_frame_pointer_rtx)); ++ else ++ emit_insn (gen_stack_tie (Pmode, mem, stack_pointer_rtx)); + } + + /* Copy GPRS into FPR save slots. */ +@@ -11676,6 +11674,7 @@ s390_emit_prologue (void) + + if (frame_pointer_needed) + { ++ s390_emit_stack_tie (); + insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); + RTX_FRAME_RELATED_P (insn) = 1; + } +diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md +index 4828aa08be6..00d39608e1d 100644 +--- a/gcc/config/s390/s390.md ++++ b/gcc/config/s390/s390.md +@@ -11590,9 +11590,10 @@ (define_insn "stack_protect_test" + ; This is used in s390_emit_prologue in order to prevent insns + ; adjusting the stack pointer to be moved over insns writing stack + ; slots using a copy of the stack pointer in a different register. +-(define_insn "stack_tie" ++(define_insn "@stack_tie" + [(set (match_operand:BLK 0 "memory_operand" "+m") +- (unspec:BLK [(match_dup 0)] UNSPEC_TIE))] ++ (unspec:BLK [(match_dup 0) ++ (match_operand:P 1 "register_operand" "r")] UNSPEC_TIE))] + "" + "" + [(set_attr "length" "0")]) diff --git a/gcc11-s390x-regarg-3.patch b/gcc11-s390x-regarg-3.patch new file mode 100644 index 0000000..f24a9da --- /dev/null +++ b/gcc11-s390x-regarg-3.patch @@ -0,0 +1,545 @@ +commit 8091199cdf4d0aa9c28e4526548ddc25d02898ca +Author: Andreas Krebbel +Date: Wed Feb 1 08:59:42 2023 +0100 + + IBM zSystems: Save argument registers to the stack -mpreserve-args + + This adds support for preserving the content of parameter registers to + the stack and emit CFI for it. This useful for applications which want + to implement their own stack unwinding and need access to function + arguments. + + With the -mpreserve-args option GPRs and FPRs are save to the stack + slots which are reserved for stdargs in the register save area. + + gcc/ChangeLog: + + * config/s390/s390.c (s390_restore_gpr_p): New function. + (s390_preserve_gpr_arg_in_range_p): New function. + (s390_preserve_gpr_arg_p): New function. + (s390_preserve_fpr_arg_p): New function. + (s390_register_info_stdarg_fpr): Rename to ... + (s390_register_info_arg_fpr): ... this. Add -mpreserve-args handling. + (s390_register_info_stdarg_gpr): Rename to ... + (s390_register_info_arg_gpr): ... this. Add -mpreserve-args handling. + (s390_register_info): Use the renamed functions above. + (s390_optimize_register_info): Likewise. + (save_fpr): Generate CFI for -mpreserve-args. + (save_gprs): Generate CFI for -mpreserve-args. Drop return value. + (s390_emit_prologue): Adjust to changed calling convention of save_gprs. + (s390_optimize_prologue): Likewise. + * config/s390/s390.opt: New option -mpreserve-args + + gcc/testsuite/ChangeLog: + + * gcc.target/s390/preserve-args-1.c: New test. + * gcc.target/s390/preserve-args-2.c: New test. + +--- a/gcc/config/s390/s390.c ++++ b/gcc/config/s390/s390.c +@@ -411,6 +411,45 @@ struct s390_address + #define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2) + #define VEC_ARG_NUM_REG 8 + ++/* Return TRUE if GPR REGNO is supposed to be restored in the function ++ epilogue. */ ++static inline bool ++s390_restore_gpr_p (int regno) ++{ ++ return (cfun_frame_layout.first_restore_gpr != -1 ++ && regno >= cfun_frame_layout.first_restore_gpr ++ && regno <= cfun_frame_layout.last_restore_gpr); ++} ++ ++/* Return TRUE if any of the registers in range [FIRST, LAST] is saved ++ because of -mpreserve-args. */ ++static inline bool ++s390_preserve_gpr_arg_in_range_p (int first, int last) ++{ ++ int num_arg_regs = MIN (crtl->args.info.gprs + cfun->va_list_gpr_size, ++ GP_ARG_NUM_REG); ++ return (num_arg_regs ++ && s390_preserve_args_p ++ && first <= GPR2_REGNUM + num_arg_regs - 1 ++ && last >= GPR2_REGNUM); ++} ++ ++static inline bool ++s390_preserve_gpr_arg_p (int regno) ++{ ++ return s390_preserve_gpr_arg_in_range_p (regno, regno); ++} ++ ++static inline bool ++s390_preserve_fpr_arg_p (int regno) ++{ ++ int num_arg_regs = MIN (crtl->args.info.fprs + cfun->va_list_fpr_size, ++ FP_ARG_NUM_REG); ++ return (s390_preserve_args_p ++ && regno <= FPR0_REGNUM + num_arg_regs - 1 ++ && regno >= FPR0_REGNUM); ++} ++ + /* A couple of shortcuts. */ + #define CONST_OK_FOR_J(x) \ + CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J") +@@ -9893,61 +9932,89 @@ s390_register_info_gprtofpr () + } + + /* Set the bits in fpr_bitmap for FPRs which need to be saved due to +- stdarg. ++ stdarg or -mpreserve-args. + This is a helper routine for s390_register_info. */ +- + static void +-s390_register_info_stdarg_fpr () ++s390_register_info_arg_fpr () + { + int i; +- int min_fpr; +- int max_fpr; ++ int min_stdarg_fpr = INT_MAX, max_stdarg_fpr = -1; ++ int min_preserve_fpr = INT_MAX, max_preserve_fpr = -1; ++ int min_fpr, max_fpr; + + /* Save the FP argument regs for stdarg. f0, f2 for 31 bit and + f0-f4 for 64 bit. */ +- if (!cfun->stdarg +- || !TARGET_HARD_FLOAT +- || !cfun->va_list_fpr_size +- || crtl->args.info.fprs >= FP_ARG_NUM_REG) +- return; ++ if (cfun->stdarg ++ && TARGET_HARD_FLOAT ++ && cfun->va_list_fpr_size ++ && crtl->args.info.fprs < FP_ARG_NUM_REG) ++ { ++ min_stdarg_fpr = crtl->args.info.fprs; ++ max_stdarg_fpr = min_stdarg_fpr + cfun->va_list_fpr_size - 1; ++ if (max_stdarg_fpr >= FP_ARG_NUM_REG) ++ max_stdarg_fpr = FP_ARG_NUM_REG - 1; ++ ++ /* FPR argument regs start at f0. */ ++ min_stdarg_fpr += FPR0_REGNUM; ++ max_stdarg_fpr += FPR0_REGNUM; ++ } + +- min_fpr = crtl->args.info.fprs; +- max_fpr = min_fpr + cfun->va_list_fpr_size - 1; +- if (max_fpr >= FP_ARG_NUM_REG) +- max_fpr = FP_ARG_NUM_REG - 1; ++ if (s390_preserve_args_p && crtl->args.info.fprs) ++ { ++ min_preserve_fpr = FPR0_REGNUM; ++ max_preserve_fpr = MIN (FPR0_REGNUM + FP_ARG_NUM_REG - 1, ++ FPR0_REGNUM + crtl->args.info.fprs - 1); ++ } + +- /* FPR argument regs start at f0. */ +- min_fpr += FPR0_REGNUM; +- max_fpr += FPR0_REGNUM; ++ min_fpr = MIN (min_stdarg_fpr, min_preserve_fpr); ++ max_fpr = MAX (max_stdarg_fpr, max_preserve_fpr); ++ ++ if (max_fpr == -1) ++ return; + + for (i = min_fpr; i <= max_fpr; i++) + cfun_set_fpr_save (i); + } + ++ + /* Reserve the GPR save slots for GPRs which need to be saved due to +- stdarg. ++ stdarg or -mpreserve-args. + This is a helper routine for s390_register_info. */ + + static void +-s390_register_info_stdarg_gpr () ++s390_register_info_arg_gpr () + { + int i; +- int min_gpr; +- int max_gpr; ++ int min_stdarg_gpr = INT_MAX, max_stdarg_gpr = -1; ++ int min_preserve_gpr = INT_MAX, max_preserve_gpr = -1; ++ int min_gpr, max_gpr; + +- if (!cfun->stdarg +- || !cfun->va_list_gpr_size +- || crtl->args.info.gprs >= GP_ARG_NUM_REG) +- return; ++ if (cfun->stdarg ++ && cfun->va_list_gpr_size ++ && crtl->args.info.gprs < GP_ARG_NUM_REG) ++ { ++ min_stdarg_gpr = crtl->args.info.gprs; ++ max_stdarg_gpr = min_stdarg_gpr + cfun->va_list_gpr_size - 1; ++ if (max_stdarg_gpr >= GP_ARG_NUM_REG) ++ max_stdarg_gpr = GP_ARG_NUM_REG - 1; ++ ++ /* GPR argument regs start at r2. */ ++ min_stdarg_gpr += GPR2_REGNUM; ++ max_stdarg_gpr += GPR2_REGNUM; ++ } ++ ++ if (s390_preserve_args_p && crtl->args.info.gprs) ++ { ++ min_preserve_gpr = GPR2_REGNUM; ++ max_preserve_gpr = MIN (GPR6_REGNUM, ++ GPR2_REGNUM + crtl->args.info.gprs - 1); ++ } + +- min_gpr = crtl->args.info.gprs; +- max_gpr = min_gpr + cfun->va_list_gpr_size - 1; +- if (max_gpr >= GP_ARG_NUM_REG) +- max_gpr = GP_ARG_NUM_REG - 1; ++ min_gpr = MIN (min_stdarg_gpr, min_preserve_gpr); ++ max_gpr = MAX (max_stdarg_gpr, max_preserve_gpr); + +- /* GPR argument regs start at r2. */ +- min_gpr += GPR2_REGNUM; +- max_gpr += GPR2_REGNUM; ++ if (max_gpr == -1) ++ return; + + /* If r6 was supposed to be saved into an FPR and now needs to go to + the stack for vararg we have to adjust the restore range to make +@@ -10079,14 +10146,14 @@ s390_register_info () + if (clobbered_regs[i]) + cfun_gpr_save_slot (i) = SAVE_SLOT_STACK; + +- s390_register_info_stdarg_fpr (); ++ s390_register_info_arg_fpr (); + s390_register_info_gprtofpr (); + s390_register_info_set_ranges (); +- /* stdarg functions might need to save GPRs 2 to 6. This might +- override the GPR->FPR save decision made by +- s390_register_info_gprtofpr for r6 since vararg regs must go to +- the stack. */ +- s390_register_info_stdarg_gpr (); ++ ++ /* Forcing argument registers to be saved on the stack might ++ override the GPR->FPR save decision for r6 so this must come ++ last. */ ++ s390_register_info_arg_gpr (); + } + + /* Return true if REGNO is a global register, but not one +@@ -10141,7 +10208,7 @@ s390_optimize_register_info () + cfun_gpr_save_slot (i) = SAVE_SLOT_NONE; + + s390_register_info_set_ranges (); +- s390_register_info_stdarg_gpr (); ++ s390_register_info_arg_gpr (); + } + + /* Fill cfun->machine with info about frame of current function. */ +@@ -10864,14 +10931,28 @@ static rtx + save_fpr (rtx base, int offset, int regnum) + { + rtx addr; ++ rtx insn; ++ + addr = gen_rtx_MEM (DFmode, plus_constant (Pmode, base, offset)); + +- if (regnum >= 16 && regnum <= (16 + FP_ARG_NUM_REG)) ++ if (regnum >= FPR0_REGNUM && regnum <= (FPR0_REGNUM + FP_ARG_NUM_REG)) + set_mem_alias_set (addr, get_varargs_alias_set ()); + else + set_mem_alias_set (addr, get_frame_alias_set ()); + +- return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum)); ++ insn = emit_move_insn (addr, gen_rtx_REG (DFmode, regnum)); ++ ++ if (!call_used_regs[regnum] || s390_preserve_fpr_arg_p (regnum)) ++ RTX_FRAME_RELATED_P (insn) = 1; ++ ++ if (s390_preserve_fpr_arg_p (regnum) && !cfun_fpr_save_p (regnum)) ++ { ++ rtx reg = gen_rtx_REG (DFmode, regnum); ++ add_reg_note (insn, REG_CFA_NO_RESTORE, reg); ++ add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (addr, reg)); ++ } ++ ++ return insn; + } + + /* Emit insn to restore fpr REGNUM from offset OFFSET relative +@@ -10891,10 +10972,11 @@ restore_fpr (rtx base, int offset, int regnum) + the register save area located at offset OFFSET + relative to register BASE. */ + +-static rtx +-save_gprs (rtx base, int offset, int first, int last) ++static void ++save_gprs (rtx base, int offset, int first, int last, rtx_insn *before = NULL) + { + rtx addr, insn, note; ++ rtx_insn *out_insn; + int i; + + addr = plus_constant (Pmode, base, offset); +@@ -10910,7 +10992,15 @@ save_gprs (rtx base, int offset, int first, int last) + + if (!global_not_special_regno_p (first)) + RTX_FRAME_RELATED_P (insn) = 1; +- return insn; ++ ++ if (s390_preserve_gpr_arg_p (first) && !s390_restore_gpr_p (first)) ++ { ++ rtx reg = gen_rtx_REG (Pmode, first); ++ add_reg_note (insn, REG_CFA_NO_RESTORE, reg); ++ add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (addr, reg)); ++ } ++ ++ goto emit; + } + + +@@ -10939,7 +11029,12 @@ save_gprs (rtx base, int offset, int first, int last) + set, even if it does not. Therefore we emit a new pattern + without those registers as REG_FRAME_RELATED_EXPR note. */ + +- if (first >= 6 && !global_not_special_regno_p (first)) ++ /* In these cases all of the sets are marked as frame related: ++ 1. call-save GPR saved and restored ++ 2. argument GPR saved because of -mpreserve-args */ ++ if ((first >= GPR6_REGNUM && !global_not_special_regno_p (first)) ++ || s390_preserve_gpr_arg_in_range_p (first, last)) ++ + { + rtx pat = PATTERN (insn); + +@@ -10950,6 +11045,24 @@ save_gprs (rtx base, int offset, int first, int last) + RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1; + + RTX_FRAME_RELATED_P (insn) = 1; ++ ++ /* For the -mpreserve-args register saves no restore operations ++ will be emitted. CFI checking would complain about this. We ++ manually generate the REG_CFA notes here to be able to mark ++ those operations with REG_CFA_NO_RESTORE. */ ++ if (s390_preserve_gpr_arg_in_range_p (first, last)) ++ { ++ for (int regno = first; regno <= last; regno++) ++ { ++ rtx reg = gen_rtx_REG (Pmode, regno); ++ rtx reg_addr = plus_constant (Pmode, base, ++ offset + (regno - first) * UNITS_PER_LONG); ++ if (!s390_restore_gpr_p (regno)) ++ add_reg_note (insn, REG_CFA_NO_RESTORE, reg); ++ add_reg_note (insn, REG_CFA_OFFSET, ++ gen_rtx_SET (gen_frame_mem (Pmode, reg_addr), reg)); ++ } ++ } + } + else if (last >= 6) + { +@@ -10960,7 +11073,7 @@ save_gprs (rtx base, int offset, int first, int last) + break; + + if (start > last) +- return insn; ++ goto emit; + + addr = plus_constant (Pmode, base, + offset + (start - first) * UNITS_PER_LONG); +@@ -10978,7 +11091,7 @@ save_gprs (rtx base, int offset, int first, int last) + add_reg_note (insn, REG_FRAME_RELATED_EXPR, note); + RTX_FRAME_RELATED_P (insn) = 1; + +- return insn; ++ goto emit; + } + + note = gen_store_multiple (gen_rtx_MEM (Pmode, addr), +@@ -10997,9 +11110,15 @@ save_gprs (rtx base, int offset, int first, int last) + RTX_FRAME_RELATED_P (insn) = 1; + } + +- return insn; ++ emit: ++ if (before != NULL_RTX) ++ out_insn = emit_insn_before (insn, before); ++ else ++ out_insn = emit_insn (insn); ++ INSN_ADDRESSES_NEW (out_insn, -1); + } + ++ + /* Generate insn to restore registers FIRST to LAST from + the register save area located at offset OFFSET + relative to register BASE. */ +@@ -11423,12 +11542,12 @@ s390_emit_prologue (void) + /* Save call saved gprs. */ + if (cfun_frame_layout.first_save_gpr != -1) + { +- insn = save_gprs (stack_pointer_rtx, +- cfun_frame_layout.gprs_offset + +- UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr +- - cfun_frame_layout.first_save_gpr_slot), +- cfun_frame_layout.first_save_gpr, +- cfun_frame_layout.last_save_gpr); ++ save_gprs (stack_pointer_rtx, ++ cfun_frame_layout.gprs_offset + ++ UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr ++ - cfun_frame_layout.first_save_gpr_slot), ++ cfun_frame_layout.first_save_gpr, ++ cfun_frame_layout.last_save_gpr); + + /* This is not 100% correct. If we have more than one register saved, + then LAST_PROBE_OFFSET can move even closer to sp. */ +@@ -11436,8 +11555,6 @@ s390_emit_prologue (void) + = (cfun_frame_layout.gprs_offset + + UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr + - cfun_frame_layout.first_save_gpr_slot)); +- +- emit_insn (insn); + } + + /* Dummy insn to mark literal pool slot. */ +@@ -11467,15 +11584,10 @@ s390_emit_prologue (void) + { + if (cfun_fpr_save_p (i)) + { +- insn = save_fpr (stack_pointer_rtx, offset, i); ++ save_fpr (stack_pointer_rtx, offset, i); + if (offset < last_probe_offset) + last_probe_offset = offset; + offset += 8; +- +- /* If f4 and f6 are call clobbered they are saved due to +- stdargs and therefore are not frame related. */ +- if (!call_used_regs[i]) +- RTX_FRAME_RELATED_P (insn) = 1; + } + else if (!TARGET_PACKED_STACK || call_used_regs[i]) + offset += 8; +@@ -11491,11 +11603,10 @@ s390_emit_prologue (void) + for (i = FPR15_REGNUM; i >= FPR8_REGNUM && offset >= 0; i--) + if (cfun_fpr_save_p (i)) + { +- insn = save_fpr (stack_pointer_rtx, offset, i); ++ save_fpr (stack_pointer_rtx, offset, i); + if (offset < last_probe_offset) + last_probe_offset = offset; + +- RTX_FRAME_RELATED_P (insn) = 1; + offset -= 8; + } + if (offset >= cfun_frame_layout.f8_offset) +@@ -11663,7 +11774,6 @@ s390_emit_prologue (void) + + insn = save_fpr (temp_reg, offset, i); + offset += 8; +- RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_FRAME_RELATED_EXPR, + gen_rtx_SET (gen_rtx_MEM (DFmode, addr), + gen_rtx_REG (DFmode, i))); +@@ -14158,15 +14268,11 @@ s390_optimize_prologue (void) + continue; + + if (cfun_frame_layout.first_save_gpr != -1) +- { +- rtx s_pat = save_gprs (base, +- off + (cfun_frame_layout.first_save_gpr +- - first) * UNITS_PER_LONG, +- cfun_frame_layout.first_save_gpr, +- cfun_frame_layout.last_save_gpr); +- new_insn = emit_insn_before (s_pat, insn); +- INSN_ADDRESSES_NEW (new_insn, -1); +- } ++ save_gprs (base, ++ off + (cfun_frame_layout.first_save_gpr ++ - first) * UNITS_PER_LONG, ++ cfun_frame_layout.first_save_gpr, ++ cfun_frame_layout.last_save_gpr, insn); + + remove_insn (insn); + continue; +diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt +index 57d1b95bd65..344aa551f44 100644 +--- a/gcc/config/s390/s390.opt ++++ b/gcc/config/s390/s390.opt +@@ -321,3 +321,7 @@ and the default behavior is to emit separate multiplication and addition + instructions for long doubles in vector registers, because measurements show + that this improves performance. This option allows overriding it for testing + purposes. ++ ++mpreserve-args ++Target Var(s390_preserve_args_p) Init(0) ++Store all argument registers on the stack. +diff --git a/gcc/testsuite/gcc.target/s390/preserve-args-1.c b/gcc/testsuite/gcc.target/s390/preserve-args-1.c +new file mode 100644 +index 00000000000..24dcf547432 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/s390/preserve-args-1.c +@@ -0,0 +1,17 @@ ++/* Functional tests for the -mpreserve-args cmdline option. */ ++ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -march=z900 -mpreserve-args" } */ ++ ++ ++int ++foo (int a, int b, int c, double d, double e) ++{ ++ return a + c + (int)d + (int)e; ++} ++ ++/* { dg-final { scan-assembler "stmg\t%r2,%r4,\[0-9\]*\\(%r15\\)" { target lp64 } } } */ ++/* { dg-final { scan-assembler "stm\t%r2,%r4,\[0-9\]*\\(%r15\\)" { target { ! lp64 } } } } */ ++ ++/* { dg-final { scan-assembler "std\t%f0,\[0-9\]*\\(%r15\\)" } } */ ++/* { dg-final { scan-assembler "std\t%f2,\[0-9\]*\\(%r15\\)" } } */ +diff --git a/gcc/testsuite/gcc.target/s390/preserve-args-2.c b/gcc/testsuite/gcc.target/s390/preserve-args-2.c +new file mode 100644 +index 00000000000..006aad9c371 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/s390/preserve-args-2.c +@@ -0,0 +1,19 @@ ++/* This test requires special handling of a GPR which is saved because ++ of -mpreserve-args but not restored. dwarf2cfi used to ICE for ++ this in maybe_record_trace_start. The solution was to introduce a ++ REG_CFA_NORESTORE reg note. */ ++ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -march=z900 -mpreserve-args" } */ ++ ++void *foo (void *); ++void bar (); ++int x; ++void * ++baz (void *y) ++{ ++ if (__builtin_expect (x, 0)) ++ return foo (y); ++ bar (); ++ return foo (y); ++} +diff --git a/gcc/testsuite/gcc.target/s390/preserve-args-3.c b/gcc/testsuite/gcc.target/s390/preserve-args-3.c +new file mode 100644 +index 00000000000..f4b135ab8e6 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/s390/preserve-args-3.c +@@ -0,0 +1,19 @@ ++/* Functional tests for the -mpreserve-args cmdline option. */ ++ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -march=z900 -mpreserve-args" } */ ++ ++#include ++int ++foo (int a, int, int c, double d, ...) ++{ ++ va_list argp; ++ va_start(argp, d); ++ return a + c + va_arg(argp, int) + va_arg(argp, int) + (int)va_arg(argp, double); ++} ++ ++/* { dg-final { scan-assembler "stmg\t%r2,%r15,\[0-9\]*\\(%r15\\)" { target lp64 } } } */ ++/* { dg-final { scan-assembler "stm\t%r2,%r15,\[0-9\]*\\(%r15\\)" { target { ! lp64 } } } } */ ++ ++/* { dg-final { scan-assembler "std\t%f0,\[0-9\]*\\(%r15\\)" } } */ ++/* { dg-final { scan-assembler "std\t%f2,\[0-9\]*\\(%r15\\)" } } */ diff --git a/sources b/sources index 835d6d6..4f7c5cc 100644 --- a/sources +++ b/sources @@ -1,4 +1,4 @@ -SHA512 (gcc-11.3.1-20220421.tar.xz) = c631a8a990a6977b70a878c34a69c64dd49387edae0931ef64433cbf5f361ecec6a4118a9a5b1eab57b354eecea125297f721ddd25daebc2290749a7eae17af2 +SHA512 (gcc-11.3.1-20221121.tar.xz) = c4e484b7cd8b54925cd420aa9d4a22d27ad1557b481c882e952ed65e7709cfc9c044111f2d194f06349d6510672e23b9d8c8da9f1ec070f453bb4ce74f885095 SHA512 (isl-0.18.tar.bz2) = 85d0b40f4dbf14cb99d17aa07048cdcab2dc3eb527d2fbb1e84c41b2de5f351025370e57448b63b2b8a8cf8a0843a089c3263f9baee1542d5c2e1cb37ed39d94 SHA512 (newlib-cygwin-50e2a63b04bdd018484605fbb954fd1bd5147fa0.tar.xz) = 002a48a7b689a81abbf16161bcaec001a842e67dfbe372e9e109092703bfc666675f16198f60ca429370e8850d564547dc505df81bc3aaca4ce6defbc014ad6c SHA512 (nvptx-tools-5f6f343a302d620b0868edab376c00b15741e39e.tar.xz) = f6d10db94fa1570ae0f94df073fa3c73c8e5ee16d59070b53d94f7db0de8a031bc44d7f3f1852533da04b625ce758e022263855ed43cfc6867e0708d001e53c7