Re: [PATCH] regcprop: Determine subreg offset depending on endianness [PR101260]
ping On Mon, Oct 11, 2021 at 02:14:53PM +0200, Stefan Schulze Frielinghaus wrote: > 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 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, _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 > 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, _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 000..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 = > +int f, g, h, i, r, s; > +static short j[8][1][6] = {0}; > +char k[7]; > +short l, m; > +int *n; > +int **o = > +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 = > + s = 0; > + for (; s < 3; s++) { > +r ^= x; > +m = j[i][g][h] == (k[g] = g); > +*w = v; > + } > + r = 2; > + for (; r; r--) > +*o = > +} > + } > + t(); > + return a; > +} > +int main() { > + *q = u(636); > + if (p.b != 4) > +__builtin_abort (); > + return 0; > +} > -- > 2.31.1 >
Re: [PATCH] regcprop: Determine subreg offset depending on endianness [PR101260]
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 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, _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 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, _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 000..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 = +int f, g, h, i, r, s; +static short j[8][1][6] = {0}; +char k[7]; +short l, m; +int *n; +int **o = +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 = + s = 0; + for (; s < 3; s++) { +r ^= x; +m = j[i][g][h] == (k[g] = g); +*w = v; + } + r = 2; + for (; r; r--) +*o = +} + } + t(); + return a; +} +int main() { + *q = u(636); + if (p.b != 4) +__builtin_abort (); + return 0; +} -- 2.31.1
Re: [PATCH] regcprop: Determine subreg offset depending on endianness [PR101260]
On Fri, Oct 8, 2021 at 1:31 PM Stefan Schulze Frielinghaus via Gcc-patches 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? > --- > 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, _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 >