From: Tamar Christina Date: Fri, 29 Nov 2024 13:01:11 +0000 (+0000) Subject: AArch64: Suppress default options when march or mcpu used is not affected by it. X-Git-Tag: basepoints/gcc-16~3762 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5b0e4ed3081e6648460661ff5013e9f03e318505;p=thirdparty%2Fgcc.git AArch64: Suppress default options when march or mcpu used is not affected by it. This patch makes it so that when you use any of the Cortex-A53 errata workarounds but have specified an -march or -mcpu we know is not affected by it that we suppress the errata workaround. This is a driver only patch as the linker invocation needs to be changed as well. The linker and cc SPECs are different because for the linker we didn't seem to add an inversion flag for the option. That said, it's also not possible to configure the linker with it on by default. So not passing the flag is sufficient to turn it off. For the compilers however we have an inversion flag using -mno-, which is needed to disable the workarounds when the compiler has been configured with it by default. In case it's unclear how the patch does what it does (it took me a while to figure out the syntax): * Early matching will replace any -march=native or -mcpu=native with their expanded forms and erases the native arguments from the buffer. * Due to the above if we ensure we handle the new code after this erasure then we only have to handle the expanded form. * The expanded form needs to handle -march=+extensions and -mcpu=+extensions and so we can't use normal string matching but instead use strstr with a custom driver function that's common between native and non-native builds. * For the compilers we output -mno- and for the linker we just erase the --fix- option. * The extra internal matching, e.g. the duplicate match of mcpu inside: mcpu=*:%{%:is_local_not_armv8_base(%{mcpu=*:%*}) is so we can extract the glob using %* because the outer match would otherwise reset at the %{. The reason for the outer glob at all is to skip the block early if no matches are found. The workaround has the effect of suppressing certain inlining and multiply-add formation which leads to about ~1% SPECCPU 2017 Intrate regression on modern cores. This patch is needed because most distros configure GCC with the workaround enabled by default. Expected output: > gcc -mcpu=neoverse-v1 -mfix-cortex-a53-835769 -xc - -O3 -o - < /dev/null -### 2>&1 | grep "\-mfix" | wc -l 0 > gcc -mfix-cortex-a53-835769 -xc - -O3 -o - < /dev/null -### 2>&1 | grep "\-mfix" | wc -l 5 > gcc -mfix-cortex-a53-835769 -march=armv8-a -xc - -O3 -o - < /dev/null -### 2>&1 | grep "\-mfix" | wc -l 5 > gcc -mfix-cortex-a53-835769 -march=armv8.1-a -xc - -O3 -o - < /dev/null -### 2>&1 | grep "\-mfix" | wc -l 0 > gcc -mfix-cortex-a53-835769 -march=armv8.1-a -xc - -O3 -o - < /dev/null -### 2>&1 | grep "\-\-fix" | wc -l 0 > gcc -mfix-cortex-a53-835769 -march=armv8-a -xc - -O3 -o - < /dev/null -### 2>&1 | grep "\-\-fix" | wc -l 1 > -gcc -mfix-cortex-a53-835769 -xc - -O3 -o - < /dev/null -### 2>&1 | grep "\-\-fix" | wc -l 1 gcc/ChangeLog: * config/aarch64/aarch64-errata.h (TARGET_SUPPRESS_OPT_SPEC, TARGET_TURN_OFF_OPT_SPEC, CA53_ERR_835769_COMPILE_SPEC, CA53_ERR_843419_COMPILE_SPEC): New. (CA53_ERR_835769_SPEC, CA53_ERR_843419_SPEC): Use them. * config/aarch64/aarch64-elf-raw.h (CC1_SPEC, CC1PLUS_SPEC): Add AARCH64_ERRATA_COMPILE_SPEC. * config/aarch64/aarch64-freebsd.h (CC1_SPEC, CC1PLUS_SPEC): Likewise. * config/aarch64/aarch64-gnu.h (CC1_SPEC, CC1PLUS_SPEC): Likewise. * config/aarch64/aarch64-linux.h (CC1_SPEC, CC1PLUS_SPEC): Likewise. * config/aarch64/aarch64-netbsd.h (CC1_SPEC, CC1PLUS_SPEC): Likewise. * common/config/aarch64/aarch64-common.cc (is_host_cpu_not_armv8_base): New. * config/aarch64/driver-aarch64.cc: Remove extra newline * config/aarch64/aarch64.h (is_host_cpu_not_armv8_base): New. (MCPU_TO_MARCH_SPEC_FUNCTIONS): Add is_local_not_armv8_base. (EXTRA_SPEC_FUNCTIONS): Add is_local_cpu_armv8_base. * doc/invoke.texi: Document it. gcc/testsuite/ChangeLog: * gcc.target/aarch64/cpunative/info_30: New test. * gcc.target/aarch64/cpunative/info_31: New test. * gcc.target/aarch64/cpunative/info_32: New test. * gcc.target/aarch64/cpunative/info_33: New test. * gcc.target/aarch64/cpunative/native_cpu_30.c: New test. * gcc.target/aarch64/cpunative/native_cpu_31.c: New test. * gcc.target/aarch64/cpunative/native_cpu_32.c: New test. * gcc.target/aarch64/cpunative/native_cpu_33.c: New test. * gcc.target/aarch64/erratas_opt_0.c: New test. * gcc.target/aarch64/erratas_opt_1.c: New test. * gcc.target/aarch64/erratas_opt_10.c: New test. * gcc.target/aarch64/erratas_opt_11.c: New test. * gcc.target/aarch64/erratas_opt_12.c: New test. * gcc.target/aarch64/erratas_opt_13.c: New test. * gcc.target/aarch64/erratas_opt_14.c: New test. * gcc.target/aarch64/erratas_opt_15.c: New test. * gcc.target/aarch64/erratas_opt_2.c: New test. * gcc.target/aarch64/erratas_opt_3.c: New test. * gcc.target/aarch64/erratas_opt_4.c: New test. * gcc.target/aarch64/erratas_opt_5.c: New test. * gcc.target/aarch64/erratas_opt_6.c: New test. * gcc.target/aarch64/erratas_opt_7.c: New test. * gcc.target/aarch64/erratas_opt_8.c: New test. * gcc.target/aarch64/erratas_opt_9.c: New test. --- diff --git a/gcc/common/config/aarch64/aarch64-common.cc b/gcc/common/config/aarch64/aarch64-common.cc index 64b65b7ff9e4..697432fbf544 100644 --- a/gcc/common/config/aarch64/aarch64-common.cc +++ b/gcc/common/config/aarch64/aarch64-common.cc @@ -446,6 +446,33 @@ aarch64_rewrite_mcpu (int argc, const char **argv) return aarch64_rewrite_selected_cpu (argv[argc - 1]); } +/* Checks to see if the host CPU may not be Cortex-A53 or an unknown Armv8-a + baseline CPU. */ + +const char * +is_host_cpu_not_armv8_base (int argc, const char **argv) +{ + gcc_assert (argc); + + /* Default to not knowing what we are if unspecified. The SPEC file should + have already mapped configure time options to here through + OPTION_DEFAULT_SPECS so we don't need to check the configure variants + manually. */ + if (!argv[0]) + return NULL; + + const char *res = argv[0]; + + /* No SVE system is baseline Armv8-A. */ + if (strstr (res, "+sve")) + return ""; + + if (strstr (res, "cortex-a53") || strstr (res, "armv8-a")) + return NULL; + + return ""; +} + struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; #undef AARCH64_CPU_NAME_LENGTH diff --git a/gcc/config/aarch64/aarch64-elf-raw.h b/gcc/config/aarch64/aarch64-elf-raw.h index 5396da9b2d62..8442a664c4fd 100644 --- a/gcc/config/aarch64/aarch64-elf-raw.h +++ b/gcc/config/aarch64/aarch64-elf-raw.h @@ -38,4 +38,12 @@ AARCH64_ERRATA_LINK_SPEC #endif +#ifndef CC1_SPEC +# define CC1_SPEC AARCH64_ERRATA_COMPILE_SPEC +#endif + +#ifndef CC1PLUS_SPEC +# define CC1PLUS_SPEC AARCH64_ERRATA_COMPILE_SPEC +#endif + #endif /* GCC_AARCH64_ELF_RAW_H */ diff --git a/gcc/config/aarch64/aarch64-errata.h b/gcc/config/aarch64/aarch64-errata.h index c323595ee495..dfc94488901c 100644 --- a/gcc/config/aarch64/aarch64-errata.h +++ b/gcc/config/aarch64/aarch64-errata.h @@ -21,24 +21,61 @@ #ifndef GCC_AARCH64_ERRATA_H #define GCC_AARCH64_ERRATA_H +/* Completely ignore the option if we've explicitly specify something other than + mcpu=cortex-a53 or march=armv8-a. */ +#define TARGET_SUPPRESS_OPT_SPEC(OPT) \ + "mcpu=*:%{%:is_local_not_armv8_base(%{mcpu=*:%*}):; " OPT \ + "}; march=*:%{%:is_local_not_armv8_base(%{march=*:%*}):;" OPT "}; " OPT + +/* Explicitly turn off the option if we've explicitly specify something other + than mcpu=cortex-a53 or march=armv8-a. This will also erase any other usage + of the flag making the order of the options not relevant. */ +# define TARGET_TURN_OFF_OPT_SPEC(FLAG) \ + "mcpu=*:%{%:is_local_not_armv8_base(%{mcpu=*:%*}):%