- 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)
epel9
Robert Scheck 2 years ago
parent 28d73354d1
commit a182f14beb

@ -1,10 +1,10 @@
%global DATE 20220421 %global DATE 20221121
%global gitrev 1d3172725999deb0dca93ac70393ed9a0ad0da3f %global gitrev 643e61c61b308f9c572da4ccd5f730fb
%global gcc_version 11.3.1 %global gcc_version 11.3.1
%global gcc_major 11 %global gcc_major 11
# Note, gcc_release must be integer, if you want to add suffixes to # Note, gcc_release must be integer, if you want to add suffixes to
# %%{release}, append them after %%{gcc_release} on Release: line. # %%{release}, append them after %%{gcc_release} on Release: line.
%global gcc_release 4 %global gcc_release 5
%global nvptx_tools_gitrev 5f6f343a302d620b0868edab376c00b15741e39e %global nvptx_tools_gitrev 5f6f343a302d620b0868edab376c00b15741e39e
%global newlib_cygwin_gitrev 50e2a63b04bdd018484605fbb954fd1bd5147fa0 %global newlib_cygwin_gitrev 50e2a63b04bdd018484605fbb954fd1bd5147fa0
%global _unpackaged_files_terminate_build 0 %global _unpackaged_files_terminate_build 0
@ -44,7 +44,7 @@
%else %else
%global build_go 0 %global build_go 0
%endif %endif
%ifarch %{ix86} x86_64 %{arm} %{mips} s390 s390x riscv64 %ifarch %{ix86} x86_64 %{arm} aarch64 %{mips} s390 s390x riscv64
%global build_d 1 %global build_d 1
%else %else
%global build_d 0 %global build_d 0
@ -115,6 +115,18 @@
%ifarch x86_64 %ifarch x86_64
%global multilib_32_arch i686 %global multilib_32_arch i686
%endif %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 # Override RHEL/derivative build options for gcc-epel
%global epel_bootstrap 0 %global epel_bootstrap 0
%global epel_glibc32 0 %global epel_glibc32 0
@ -127,6 +139,7 @@
%if !0%{?epel_glibc32} %if !0%{?epel_glibc32}
%global multilib_64_archs noarch %global multilib_64_archs noarch
%endif %endif
%global build_cross 0
Summary: Various compilers (C, C++, Objective-C, ...) Summary: Various compilers (C, C++, Objective-C, ...)
Name: gcc-epel Name: gcc-epel
Version: %{gcc_version} Version: %{gcc_version}
@ -325,9 +338,11 @@ Patch20: gcc11-relocatable-pch.patch
Patch21: gcc11-dejagnu-multiline.patch Patch21: gcc11-dejagnu-multiline.patch
Patch23: gcc11-pie.patch Patch23: gcc11-pie.patch
Patch24: gcc11-bind-now.patch Patch24: gcc11-bind-now.patch
Patch25: gcc11-pr105331.patch Patch25: gcc11-detect-sapphirerapids.patch
# This can go once we rebase from GCC 11. Patch26: gcc11-Wmismatched-dealloc-doc.patch
Patch26: gcc11-rh2106262.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 Patch100: gcc11-fortran-fdec-duplicates.patch
Patch101: gcc11-fortran-flogical-as-integer.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 of the plugin is explicitly built by the same version of gcc that is installed
so that there cannot be any synchronization problems. 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 %prep
%setup -q -n gcc-%{version}-%{DATE} -a 1 -a 2 -a 3 %setup -q -n gcc-%{version}-%{DATE} -a 1 -a 2 -a 3
%patch0 -p0 -b .hack~ %patch0 -p0 -b .hack~
@ -902,8 +956,11 @@ so that there cannot be any synchronization problems.
%patch23 -p1 -b .pie~ %patch23 -p1 -b .pie~
%patch24 -p1 -b .now~ %patch24 -p1 -b .now~
%endif %endif
%patch25 -p0 -b .pr105331~ %patch25 -p1 -b .detect-spr~
%patch26 -p1 -b .rh2106262~ %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 %if 0%{?rhel} >= 9
%patch100 -p1 -b .fortran-fdec-duplicates~ %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 rm -f gcc/testsuite/go.test/test/fixedbugs/issue19182.go
%endif %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 cp -a libstdc++-v3/config/cpu/i{4,3}86/atomicity.h
@ -1120,10 +1179,36 @@ enablelgo=,go
%if %{build_d} %if %{build_d}
enableld=,d enableld=,d
%endif %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= + <arch-specific-opts>
# It it very important that the arch-specific configure options used in
# CONFIGURE_OPTS_NATIVE are in lockstep with the <arch-specific-opts>
# used in the cross builds.
CONFIGURE_OPTS_BASE="\
--prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir} \ --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir} \
--with-bugurl=http://bugzilla.redhat.com/bugzilla \ --with-bugurl=http://bugzilla.redhat.com/bugzilla \
--enable-shared --enable-threads=posix --enable-checking=release \ --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 %ifarch ppc64le
--enable-targets=powerpcle-linux \ --enable-targets=powerpcle-linux \
%endif %endif
@ -1144,16 +1229,8 @@ CONFIGURE_OPTS="\
--disable-multilib \ --disable-multilib \
%endif %endif
%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} %ifnarch %{mips}
--with-linker-hash-style=gnu \ --with-linker-hash-style=gnu \
%endif
--enable-plugin --enable-initfini-array \
%if %{build_isl}
--with-isl=`pwd`/isl-install \
%else
--without-isl \
%endif %endif
%if %{build_offload_nvptx} %if %{build_offload_nvptx}
--enable-offload-targets=nvptx-none \ --enable-offload-targets=nvptx-none \
@ -1268,6 +1345,16 @@ CONFIGURE_OPTS="\
%endif %endif
%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" \ CC="$CC" CXX="$CXX" CFLAGS="$OPT_FLAGS" \
CXXFLAGS="`echo " $OPT_FLAGS " | sed 's/ -Wall / /g;s/ -fexceptions / /g' \ 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 make jit.sphinx.install-html jit_htmldir=`pwd`/../../rpm.doc/libgccjit-devel/html
cd .. 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} %if %{build_isl}
cp -a isl-install/lib/libisl.so.15 gcc/ cp -a isl-install/lib/libisl.so.15 gcc/
%endif %endif
@ -1518,6 +1654,126 @@ make prefix=%{buildroot}%{_prefix} mandir=%{buildroot}%{_mandir} \
chmod 644 %{buildroot}%{_infodir}/gnat* chmod 644 %{buildroot}%{_infodir}/gnat*
%endif %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
# <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42980>. 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} FULLPATH=%{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
FULLEPATH=%{buildroot}%{_prefix}/libexec/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 %{ANNOBIN_GCC_PLUGIN_DIR}/gcc-annobin.so.0.0.0
%endif %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 %changelog
* Thu Jun 08 2023 Robert Scheck <robert@fedoraproject.org> 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 <robert@fedoraproject.org> 11.3.1-4 * Thu Nov 17 2022 Robert Scheck <robert@fedoraproject.org> 11.3.1-4
- disable bootstrap mode and rebuild using gcc-epel-11.3.1-3.el9 - disable bootstrap mode and rebuild using gcc-epel-11.3.1-3.el9

@ -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

@ -0,0 +1,69 @@
commit 63dd214dce603f4f99e2cb272255b6c2b4308c3d
Author: Cui,Lili <lili.cui@intel.com>
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.

@ -1,33 +0,0 @@
2022-04-21 Jakub Jelinek <jakub@redhat.com>
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 <stdarg.h>
+
+int
+foo (va_list *va)
+{
+ return va_arg (*va, double _Complex); /* { dg-bogus "may be used uninitialized" } */
+}

@ -1,388 +0,0 @@
commit c725028a8bb9478ec84332641147ad12b9236922
Author: Jonathan Wakely <jwakely@redhat.com>
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<bool, CharT> used to emulate
optional<CharT> with a custom class closer to pair<tribool,CharT>. 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<bool, CharT>
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<bool __icase, bool __collate>
+ 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 __icase, bool __collate>
bool
- _M_expression_term(pair<bool, _CharT>& __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<bool, _CharT> __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 __icase, bool __collate>
bool
_Compiler<_TraitsT>::
- _M_expression_term(pair<bool, _CharT>& __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;
}

@ -0,0 +1,91 @@
commit ef5f7b89bbc352255595069eb870d6f30f1f9134
Author: Andreas Krebbel <krebbel@linux.ibm.com>
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. */

@ -0,0 +1,92 @@
commit 36ffb2e0293d1bbef30e3553a431679de00549b9
Author: Andreas Krebbel <krebbel@linux.ibm.com>
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<mode>): ... 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<mode>"
; 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<mode>"
[(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")])

@ -0,0 +1,545 @@
commit 8091199cdf4d0aa9c28e4526548ddc25d02898ca
Author: Andreas Krebbel <krebbel@linux.ibm.com>
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 <stdarg.h>
+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\\)" } } */

@ -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 (isl-0.18.tar.bz2) = 85d0b40f4dbf14cb99d17aa07048cdcab2dc3eb527d2fbb1e84c41b2de5f351025370e57448b63b2b8a8cf8a0843a089c3263f9baee1542d5c2e1cb37ed39d94
SHA512 (newlib-cygwin-50e2a63b04bdd018484605fbb954fd1bd5147fa0.tar.xz) = 002a48a7b689a81abbf16161bcaec001a842e67dfbe372e9e109092703bfc666675f16198f60ca429370e8850d564547dc505df81bc3aaca4ce6defbc014ad6c SHA512 (newlib-cygwin-50e2a63b04bdd018484605fbb954fd1bd5147fa0.tar.xz) = 002a48a7b689a81abbf16161bcaec001a842e67dfbe372e9e109092703bfc666675f16198f60ca429370e8850d564547dc505df81bc3aaca4ce6defbc014ad6c
SHA512 (nvptx-tools-5f6f343a302d620b0868edab376c00b15741e39e.tar.xz) = f6d10db94fa1570ae0f94df073fa3c73c8e5ee16d59070b53d94f7db0de8a031bc44d7f3f1852533da04b625ce758e022263855ed43cfc6867e0708d001e53c7 SHA512 (nvptx-tools-5f6f343a302d620b0868edab376c00b15741e39e.tar.xz) = f6d10db94fa1570ae0f94df073fa3c73c8e5ee16d59070b53d94f7db0de8a031bc44d7f3f1852533da04b625ce758e022263855ed43cfc6867e0708d001e53c7

Loading…
Cancel
Save