On Mon, Oct 11, 2021 at 09:38:36AM +0200, Richard Biener wrote: > On Fri, Oct 8, 2021 at 1:31 PM Stefan Schulze Frielinghaus via > Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > > gcc/ChangeLog: > > > > * regcprop.c (maybe_mode_change): Determine offset relative to > > high or low part depending on endianness. > > > > Bootstrapped and regtested on IBM Z. Ok for mainline and gcc-{11,10,9}? > > Is there a testcase to add?
I've updated the patch and added the testcase from the PR. > > > --- > > gcc/regcprop.c | 11 ++++++++--- > > 1 file changed, 8 insertions(+), 3 deletions(-) > > > > diff --git a/gcc/regcprop.c b/gcc/regcprop.c > > index d2a01130fe1..0e1ac12458a 100644 > > --- a/gcc/regcprop.c > > +++ b/gcc/regcprop.c > > @@ -414,9 +414,14 @@ maybe_mode_change (machine_mode orig_mode, > > machine_mode copy_mode, > > copy_nregs, &bytes_per_reg)) > > return NULL_RTX; > > poly_uint64 copy_offset = bytes_per_reg * (copy_nregs - use_nregs); > > - poly_uint64 offset > > - = subreg_size_lowpart_offset (GET_MODE_SIZE (new_mode) + > > copy_offset, > > - GET_MODE_SIZE (orig_mode)); > > + poly_uint64 offset = > > +#if WORDS_BIG_ENDIAN > > + subreg_size_highpart_offset > > +#else > > + subreg_size_lowpart_offset > > +#endif > > + (GET_MODE_SIZE (new_mode) + copy_offset, > > + GET_MODE_SIZE (orig_mode)); > > regno += subreg_regno_offset (regno, orig_mode, offset, new_mode); > > if (targetm.hard_regno_mode_ok (regno, new_mode)) > > return gen_raw_REG (new_mode, regno); > > -- > > 2.31.1 > >
>From 299959788321e21c27f0d4a6d437a586c5f6c92e Mon Sep 17 00:00:00 2001 From: Stefan Schulze Frielinghaus <stefa...@linux.ibm.com> Date: Mon, 4 Oct 2021 09:36:21 +0200 Subject: [PATCH] regcprop: Determine subreg offset depending on endianness [PR101260] gcc/ChangeLog: * regcprop.c (maybe_mode_change): Determine offset relative to high or low part depending on endianness. gcc/testsuite/ChangeLog: * gcc.dg/pr101260.c: New test. --- gcc/regcprop.c | 11 ++++++-- gcc/testsuite/gcc.dg/pr101260.c | 49 +++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr101260.c diff --git a/gcc/regcprop.c b/gcc/regcprop.c index d2a01130fe1..0e1ac12458a 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -414,9 +414,14 @@ maybe_mode_change (machine_mode orig_mode, machine_mode copy_mode, copy_nregs, &bytes_per_reg)) return NULL_RTX; poly_uint64 copy_offset = bytes_per_reg * (copy_nregs - use_nregs); - poly_uint64 offset - = subreg_size_lowpart_offset (GET_MODE_SIZE (new_mode) + copy_offset, - GET_MODE_SIZE (orig_mode)); + poly_uint64 offset = +#if WORDS_BIG_ENDIAN + subreg_size_highpart_offset +#else + subreg_size_lowpart_offset +#endif + (GET_MODE_SIZE (new_mode) + copy_offset, + GET_MODE_SIZE (orig_mode)); regno += subreg_regno_offset (regno, orig_mode, offset, new_mode); if (targetm.hard_regno_mode_ok (regno, new_mode)) return gen_raw_REG (new_mode, regno); diff --git a/gcc/testsuite/gcc.dg/pr101260.c b/gcc/testsuite/gcc.dg/pr101260.c new file mode 100644 index 00000000000..0e9ec4e203a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101260.c @@ -0,0 +1,49 @@ +/* PR rtl-optimization/101260 */ +/* { dg-do run } */ +/* { dg-options -O1 } */ +struct a { + unsigned b : 7; + int c; + int d; + short e; +} p, *q = &p; +int f, g, h, i, r, s; +static short j[8][1][6] = {0}; +char k[7]; +short l, m; +int *n; +int **o = &n; +void t() { + for (; f;) + ; +} +static struct a u(int x) { + struct a a = {4, 8, 5, 4}; + for (; i <= 6; i++) { + struct a v = {0}; + for (; l; l++) + h = 0; + for (; h >= 0; h--) { + struct a *w; + j[i]; + w = &p; + s = 0; + for (; s < 3; s++) { + r ^= x; + m = j[i][g][h] == (k[g] = g); + *w = v; + } + r = 2; + for (; r; r--) + *o = &r; + } + } + t(); + return a; +} +int main() { + *q = u(636); + if (p.b != 4) + __builtin_abort (); + return 0; +} -- 2.31.1