https://gcc.gnu.org/g:e98592aa5924c0569df27db5bddbc277dea78f21
commit e98592aa5924c0569df27db5bddbc277dea78f21 Author: Michael Meissner <meiss...@linux.ibm.com> Date: Fri Nov 15 00:56:39 2024 -0500 Do not allow -mvsx to boost processor to power7. This patch restructures the code so that -mvsx for example will not silently convert the processor to power7. The user must now use -mcpu=power7 or higher. This means if the user does -mvsx and the default processor does not have VSX support, it will be an error. I have built both big endian and little endian bootstrap compilers and there were no regressions. In addition, I constructed a test case that used every archiecture define (like _ARCH_PWR4, etc.) and I also looked at the .machine directive generated. I ran this test for all supported combinations of -mcpu, big/little endian, and 32/64 bit support. Every single instance generated exactly the same code with the patches installed compared to the compiler before installing the patches. I updated the 2 tests that used -mvsx to raise the cpu to power7. Can I install this patch on the GCC 15 trunk? 2024-11-15 Michael Meissner <meiss...@linux.ibm.com> gcc/ * config/rs6000/rs6000.cc (report_architecture_mismatch): New function. Report an error if the user used an option such as -mvsx when the default processor would not allow the option. (rs6000_option_override_internal): Move some ISA checking code into report_architecture_mismatch. gcc/testsuite/ * gcc.target/powerpc/ppc-target-4.c: Rewrite the test to add cpu=power7 when we need to add VSX support. Add test for adding cpu=power7 no-vsx to generate only Altivec instructions. * gcc.target/powerpc/pr115688.c: Add -mdejagnu-cpu=power6 when requesting VSX instructions. * gcc.target/powerpc/pr87496-1.c: Update optins to use -mdejagnu-cpu=power6 to get the appropriate error message. Diff: --- gcc/config/rs6000/rs6000.cc | 129 +++++++++++++++--------- gcc/testsuite/gcc.target/powerpc/ppc-target-4.c | 38 +++++-- gcc/testsuite/gcc.target/powerpc/pr115688.c | 3 +- gcc/testsuite/gcc.target/powerpc/pr87496-1.c | 2 +- 4 files changed, 111 insertions(+), 61 deletions(-) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 000501ef01d0..96603ca61d84 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -1173,6 +1173,7 @@ const int INSN_NOT_AVAILABLE = -1; static void rs6000_print_isa_options (FILE *, int, const char *, HOST_WIDE_INT, HOST_WIDE_INT); static HOST_WIDE_INT rs6000_disable_incompatible_switches (void); +static void report_architecture_mismatch (void); static enum rs6000_reg_type register_to_reg_type (rtx, bool *); static bool rs6000_secondary_reload_move (enum rs6000_reg_type, @@ -3700,7 +3701,6 @@ rs6000_option_override_internal (bool global_init_p) bool ret = true; HOST_WIDE_INT set_masks; - HOST_WIDE_INT ignore_masks; int cpu_index = -1; int tune_index; struct cl_target_option *main_target_opt @@ -3969,59 +3969,13 @@ rs6000_option_override_internal (bool global_init_p) dwarf_offset_size = POINTER_SIZE_UNITS; #endif - /* Handle explicit -mno-{altivec,vsx} and turn off all of - the options that depend on those flags. */ - ignore_masks = rs6000_disable_incompatible_switches (); - - /* For the newer switches (vsx, dfp, etc.) set some of the older options, - unless the user explicitly used the -mno-<option> to disable the code. */ - if (TARGET_P9_VECTOR || TARGET_POWER9 || TARGET_P9_MISC) - rs6000_isa_flags |= (ISA_3_0_MASKS_SERVER & ~ignore_masks); - else if (TARGET_P9_MINMAX) - { - if (cpu_index >= 0) - { - if (cpu_index == PROCESSOR_POWER9) - { - /* legacy behavior: allow -mcpu=power9 with certain - capabilities explicitly disabled. */ - rs6000_isa_flags |= (ISA_3_0_MASKS_SERVER & ~ignore_masks); - } - else - error ("power9 target option is incompatible with %<%s=<xxx>%> " - "for <xxx> less than power9", "-mcpu"); - } - else if ((ISA_3_0_MASKS_SERVER & rs6000_isa_flags_explicit) - != (ISA_3_0_MASKS_SERVER & rs6000_isa_flags - & rs6000_isa_flags_explicit)) - /* Enforce that none of the ISA_3_0_MASKS_SERVER flags - were explicitly cleared. */ - error ("%qs incompatible with explicitly disabled options", - "-mpower9-minmax"); - else - rs6000_isa_flags |= ISA_3_0_MASKS_SERVER; - } - else if (TARGET_P8_VECTOR || TARGET_POWER8 || TARGET_CRYPTO) - rs6000_isa_flags |= (ISA_2_7_MASKS_SERVER & ~ignore_masks); - else if (TARGET_VSX) - rs6000_isa_flags |= (ISA_2_6_MASKS_SERVER & ~ignore_masks); - else if (TARGET_POWER7) - rs6000_isa_flags |= (ISA_2_6_MASKS_EMBEDDED & ~ignore_masks); - else if (TARGET_DFP) - rs6000_isa_flags |= (ISA_2_5_MASKS_SERVER & ~ignore_masks); - else if (TARGET_POWER6) - rs6000_isa_flags |= (ISA_2_5_MASKS_EMBEDDED & ~ignore_masks); - else if (TARGET_POWER5X) - rs6000_isa_flags |= (ISA_2_4_MASKS & ~ignore_masks); - else if (TARGET_POWER5) - rs6000_isa_flags |= (ISA_2_2_MASKS & ~ignore_masks); - else if (TARGET_ALTIVEC) - rs6000_isa_flags |= (OPTION_MASK_PPC_GFXOPT & ~ignore_masks); + /* Report trying to use things like -mmodulo to imply -mcpu=power9. */ + report_architecture_mismatch (); /* Disable VSX and Altivec silently if the user switched cpus to power7 in a target attribute or pragma which automatically enables both options, unless the altivec ABI was set. This is set by default for 64-bit, but - not for 32-bit. Don't move this before the above code using ignore_masks, + not for 32-bit. Don't move this before report_architecture_mismatch since it can reset the cleared VSX/ALTIVEC flag again. */ if (main_target_opt && !main_target_opt->x_rs6000_altivec_abi) { @@ -25425,6 +25379,81 @@ rs6000_disable_incompatible_switches (void) return ignore_masks; } +/* In the past, we would boost up the ISA if you selected an -m<foo> option but + did not specify the correct -mcpu=<bar> option. I.e. if you added -mvsx, + GCC implictly would assume that you were building for at least power7. Now, + don't allow the -m<foo> option to boost up the ISA level. But you can still + do -mcpu=power7 -mno-vsx or -mcpu=power5 -mno-vsx. */ + +static void +report_architecture_mismatch (void) +{ + HOST_WIDE_INT ignore_masks = rs6000_disable_incompatible_switches (); + + static const struct { + const HOST_WIDE_INT isa_flags; /* -m<foo> optiona. */ + const HOST_WIDE_INT arch_flags; /* -mcpu=<proc> level. */ + const char *const arch_name; /* architecture needed. */ + } mismatches[] = { + { + OPTION_MASK_P9_VECTOR | OPTION_MASK_P9_MISC | OPTION_MASK_P9_MINMAX + | OPTION_MASK_MODULO, + ARCH_MASK_POWER9, + "-mcpu=power9" + }, + + { + OPTION_MASK_P8_VECTOR | OPTION_MASK_CRYPTO, + ARCH_MASK_POWER8, + "-mcpu=power8" + }, + + { + OPTION_MASK_VSX | OPTION_MASK_POPCNTD, + ARCH_MASK_POWER7, + "-mcpu=power7" + }, + }; + + HOST_WIDE_INT isa_flags = rs6000_isa_flags; + HOST_WIDE_INT arch_flags = rs6000_arch_flags; + + for (size_t i = 0; i < ARRAY_SIZE (mismatches); i++) + { + HOST_WIDE_INT mismatch_isa_flags = mismatches[i].isa_flags & isa_flags; + HOST_WIDE_INT mismatch_arch_flags = mismatches[i].arch_flags & arch_flags; + + if (mismatch_isa_flags != 0 && mismatch_arch_flags == 0) + { + for (size_t j = 0; j < ARRAY_SIZE (rs6000_opt_masks); j++) + { + HOST_WIDE_INT mask = rs6000_opt_masks[j].mask; + + if ((mask & mismatch_isa_flags) != 0 + && (mask & rs6000_isa_flags_explicit) != 0) + error ("%qs needs at least %qs", + rs6000_opt_masks[j].name, + mismatches[i].arch_name); + } + + rs6000_isa_flags &= ~mismatch_isa_flags; + } + } + + /* The following old options are used in multiple processors, so silently + enable the appropriate ISA options as previous GCC revisions did. */ + if (TARGET_DFP) + rs6000_isa_flags |= (ISA_2_5_MASKS_SERVER & ~ignore_masks); + else if (TARGET_CMPB) + rs6000_isa_flags |= (ISA_2_5_MASKS_EMBEDDED & ~ignore_masks); + else if (TARGET_POWER5X) + rs6000_isa_flags |= (ISA_2_4_MASKS & ~ignore_masks); + else if (TARGET_POPCNTB) + rs6000_isa_flags |= (ISA_2_2_MASKS & ~ignore_masks); + else if (TARGET_ALTIVEC) + rs6000_isa_flags |= (OPTION_MASK_PPC_GFXOPT & ~ignore_masks); +} + /* Helper function for printing the function name when debugging. */ diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-target-4.c b/gcc/testsuite/gcc.target/powerpc/ppc-target-4.c index feef76db4618..5e2ecf34f249 100644 --- a/gcc/testsuite/gcc.target/powerpc/ppc-target-4.c +++ b/gcc/testsuite/gcc.target/powerpc/ppc-target-4.c @@ -2,7 +2,7 @@ /* { dg-skip-if "" { powerpc*-*-darwin* } } */ /* { dg-require-effective-target powerpc_fprs } */ /* { dg-options "-O2 -ffast-math -mdejagnu-cpu=power5 -mno-altivec -mabi=altivec -fno-unroll-loops" } */ -/* { dg-final { scan-assembler-times "vaddfp" 1 } } */ +/* { dg-final { scan-assembler-times "vaddfp" 2 } } */ /* { dg-final { scan-assembler-times "xvaddsp" 1 } } */ /* { dg-final { scan-assembler-times "fadds" 1 } } */ @@ -18,10 +18,6 @@ #error "__VSX__ should not be defined." #endif -#pragma GCC target("altivec,vsx") -#include <altivec.h> -#pragma GCC reset_options - #pragma GCC push_options #pragma GCC target("altivec,no-vsx") @@ -33,6 +29,7 @@ #error "__VSX__ should not be defined." #endif +/* Altivec build, generate vaddfp. */ void av_add (vector float *a, vector float *b, vector float *c) { @@ -40,10 +37,11 @@ av_add (vector float *a, vector float *b, vector float *c) unsigned long n = SIZE / 4; for (i = 0; i < n; i++) - a[i] = vec_add (b[i], c[i]); + a[i] = b[i] + c[i]; } -#pragma GCC target("vsx") +/* cpu=power7 must be used to enable VSX. */ +#pragma GCC target("cpu=power7,vsx") #ifndef __ALTIVEC__ #error "__ALTIVEC__ should be defined." @@ -53,6 +51,7 @@ av_add (vector float *a, vector float *b, vector float *c) #error "__VSX__ should be defined." #endif +/* VSX build on power7, generate xsaddsp. */ void vsx_add (vector float *a, vector float *b, vector float *c) { @@ -60,11 +59,31 @@ vsx_add (vector float *a, vector float *b, vector float *c) unsigned long n = SIZE / 4; for (i = 0; i < n; i++) - a[i] = vec_add (b[i], c[i]); + a[i] = b[i] + c[i]; +} + +#pragma GCC target("cpu=power7,no-vsx") + +#ifndef __ALTIVEC__ +#error "__ALTIVEC__ should be defined." +#endif + +#ifdef __VSX__ +#error "__VSX__ should not be defined." +#endif + +/* Altivec build on power7 with no VSX, generate vaddfp. */ +void +av2_add (vector float *a, vector float *b, vector float *c) +{ + unsigned long i; + unsigned long n = SIZE / 4; + + for (i = 0; i < n; i++) + a[i] = b[i] + c[i]; } #pragma GCC pop_options -#pragma GCC target("no-vsx,no-altivec") #ifdef __ALTIVEC__ #error "__ALTIVEC__ should not be defined." @@ -74,6 +93,7 @@ vsx_add (vector float *a, vector float *b, vector float *c) #error "__VSX__ should not be defined." #endif +/* Default power5 build, generate scalar fadds. */ void norm_add (float *a, float *b, float *c) { diff --git a/gcc/testsuite/gcc.target/powerpc/pr115688.c b/gcc/testsuite/gcc.target/powerpc/pr115688.c index 5222e66ef170..00c7c301436a 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr115688.c +++ b/gcc/testsuite/gcc.target/powerpc/pr115688.c @@ -7,7 +7,8 @@ /* Verify there is no ICE under 32 bit env. */ -__attribute__((target("vsx"))) +/* cpu=power7 must be used to enable VSX. */ +__attribute__((target("cpu=power7,vsx"))) int test (void) { return 0; diff --git a/gcc/testsuite/gcc.target/powerpc/pr87496-1.c b/gcc/testsuite/gcc.target/powerpc/pr87496-1.c index b8d00286256a..2029ecacaf9b 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr87496-1.c +++ b/gcc/testsuite/gcc.target/powerpc/pr87496-1.c @@ -2,7 +2,7 @@ /* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ /* { dg-skip-if "" { powerpc*-*-darwin* } } */ /* { dg-require-effective-target longdouble128 } */ -/* { dg-options "-O2 -mdejagnu-cpu=power7 -mabi=ieeelongdouble -mno-popcntd -Wno-psabi" } */ +/* { dg-options "-O2 -mdejagnu-cpu=power6 -mabi=ieeelongdouble -Wno-psabi" } */ int i;