diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2020-12-31 16:10:47 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2020-12-31 16:10:47 +0000 |
commit | 0411210fddbd3ec27c8dc1183f40f662712a2232 (patch) | |
tree | 8e8148d489ca4378607eb44f5cc7f1da15d9343f /gcc | |
parent | d2eb616a0f7bea78164912aa438c29fe1ef5774a (diff) | |
download | gcc-0411210fddbd3ec27c8dc1183f40f662712a2232.zip gcc-0411210fddbd3ec27c8dc1183f40f662712a2232.tar.gz gcc-0411210fddbd3ec27c8dc1183f40f662712a2232.tar.bz2 |
genmodes: Update GET_MODE_MASK when changing NUNITS [PR98214]
The static GET_MODE_MASKs for SVE vectors are based on the
static precisions, which in turn are based on 128-bit SVE.
The precisions are later updated based on -msve-vector-bits
(usually to become variable length), but the GET_MODE_MASK
stayed the same. This caused combine to fold:
(*_extract:DI (subreg:DI (reg:VNxMM R) 0) ...)
to zero because the extracted bits appeared to be insignificant.
gcc/
PR rtl-optimization/98214
* genmodes.c (emit_insn_modes_h): Emit a definition of CONST_MODE_MASK.
(emit_mode_mask): Treat mode_mask_array as non-constant if adj_nunits.
(emit_mode_adjustments): Update GET_MODE_MASK when updating
GET_MODE_NUNITS.
* machmode.h (mode_mask_array): Use CONST_MODE_MASK.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/genmodes.c | 22 | ||||
-rw-r--r-- | gcc/machmode.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/sve/pr98214.c | 21 |
3 files changed, 42 insertions, 4 deletions
diff --git a/gcc/genmodes.c b/gcc/genmodes.c index 34b52fe..d053eb3 100644 --- a/gcc/genmodes.c +++ b/gcc/genmodes.c @@ -1324,6 +1324,7 @@ enum machine_mode\n{"); #endif printf ("#define CONST_MODE_IBIT%s\n", adj_ibit ? "" : " const"); printf ("#define CONST_MODE_FBIT%s\n", adj_fbit ? "" : " const"); + printf ("#define CONST_MODE_MASK%s\n", adj_nunits ? "" : " const"); emit_max_int (); for_all_modes (c, m) @@ -1561,8 +1562,8 @@ emit_mode_mask (void) int c; struct mode_data *m; - print_decl ("unsigned HOST_WIDE_INT", "mode_mask_array", - "NUM_MACHINE_MODES"); + print_maybe_const_decl ("%sunsigned HOST_WIDE_INT", "mode_mask_array", + "NUM_MACHINE_MODES", adj_nunits); puts ("\ #define MODE_MASK(m) \\\n\ ((m) >= HOST_BITS_PER_WIDE_INT) \\\n\ @@ -1719,6 +1720,20 @@ emit_mode_adjustments (void) struct mode_adjust *a; struct mode_data *m; + if (adj_nunits) + printf ("\n" + "void\n" + "adjust_mode_mask (machine_mode mode)\n" + "{\n" + " unsigned int precision;\n" + " if (GET_MODE_PRECISION (mode).is_constant (&precision)\n" + " && precision < HOST_BITS_PER_WIDE_INT)\n" + " mode_mask_array[mode] = (HOST_WIDE_INT_1U << precision) - 1;" + "\n" + " else\n" + " mode_mask_array[mode] = HOST_WIDE_INT_M1U;\n" + "}\n"); + puts ("\ \nvoid\ \ninit_adjust_machine_modes (void)\ @@ -1736,10 +1751,11 @@ emit_mode_adjustments (void) printf (" int old_factor = vector_element_size" " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n", m->name, m->name); - printf (" mode_precision[E_%smode] = ps * old_factor;\n", m->name); + printf (" mode_precision[E_%smode] = ps * old_factor;\n", m->name); printf (" mode_size[E_%smode] = exact_div (mode_precision[E_%smode]," " BITS_PER_UNIT);\n", m->name, m->name); printf (" mode_nunits[E_%smode] = ps;\n", m->name); + printf (" adjust_mode_mask (E_%smode);\n", m->name); printf (" }\n"); } diff --git a/gcc/machmode.h b/gcc/machmode.h index bb3a5c6..11247fc 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -712,7 +712,8 @@ extern CONST_MODE_FBIT unsigned char mode_fbit[NUM_MACHINE_MODES]; /* Get a bitmask containing 1 for all bits in a word that fit within mode MODE. */ -extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES]; +extern CONST_MODE_MASK unsigned HOST_WIDE_INT + mode_mask_array[NUM_MACHINE_MODES]; #define GET_MODE_MASK(MODE) mode_mask_array[MODE] diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr98214.c b/gcc/testsuite/gcc.target/aarch64/sve/pr98214.c new file mode 100644 index 0000000..2de9625 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr98214.c @@ -0,0 +1,21 @@ +/* { dg-options "-O3 -msve-vector-bits=512" } */ + +long c; +int a; +int e[14]; +short b[14]; +void d(long *f, long h) { *f ^= h + *f; } +void this_test_has_completed_successfully (); +int main() { + e[2] = 1; + for (int g = 0; g < 13; g++) + a = b[g] = e[g]; + d(&c, a); + for (int g = 0; g < 4; g++) + d(&c, b[2]); + if (c != 15) + __builtin_abort(); + this_test_has_completed_successfully (); +} + +/* { dg-final { scan-assembler {this_test_has_completed_successfully} } } */ |