diff mbox series

Always use TYPE_MODE instead of DECL_MODE for vector field

Message ID 20221020165734.1113688-1-hjl.tools@gmail.com
State New
Headers show
Series Always use TYPE_MODE instead of DECL_MODE for vector field | expand

Commit Message

H.J. Lu Oct. 20, 2022, 4:57 p.m. UTC
commit e034c5c895722e0092d2239cd8c2991db77d6d39
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Dec 2 08:54:47 2017 +0100

	PR target/78643
	PR target/80583
	* expr.c (get_inner_reference): If DECL_MODE of a non-bitfield
	is BLKmode for vector field with vector raw mode, use TYPE_MODE
	instead of DECL_MODE.

fixed the case where DECL_MODE of a vector field is BLKmode and its
TYPE_MODE is a vector mode because of target attribute.  Remove the
BLKmode check for the case where DECL_MODE of a vector field is a vector
mode and its TYPE_MODE is BLKmode because of target attribute.

gcc/

	PR target/107304
	* expr.c (get_inner_reference): Always use TYPE_MODE for vector
	field with vector raw mode.

gcc/testsuite/

	PR target/107304
	* gcc.target/i386/pr107304.c: New test.
---
 gcc/expr.cc                              |  3 +-
 gcc/testsuite/gcc.target/i386/pr107304.c | 39 ++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr107304.c

Comments

Richard Biener Oct. 21, 2022, 9:33 a.m. UTC | #1
On Thu, Oct 20, 2022 at 6:58 PM H.J. Lu via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> commit e034c5c895722e0092d2239cd8c2991db77d6d39
> Author: Jakub Jelinek <jakub@redhat.com>
> Date:   Sat Dec 2 08:54:47 2017 +0100
>
>         PR target/78643
>         PR target/80583
>         * expr.c (get_inner_reference): If DECL_MODE of a non-bitfield
>         is BLKmode for vector field with vector raw mode, use TYPE_MODE
>         instead of DECL_MODE.
>
> fixed the case where DECL_MODE of a vector field is BLKmode and its
> TYPE_MODE is a vector mode because of target attribute.  Remove the
> BLKmode check for the case where DECL_MODE of a vector field is a vector
> mode and its TYPE_MODE is BLKmode because of target attribute.
>
> gcc/
>
>         PR target/107304
>         * expr.c (get_inner_reference): Always use TYPE_MODE for vector
>         field with vector raw mode.
>
> gcc/testsuite/
>
>         PR target/107304
>         * gcc.target/i386/pr107304.c: New test.
> ---
>  gcc/expr.cc                              |  3 +-
>  gcc/testsuite/gcc.target/i386/pr107304.c | 39 ++++++++++++++++++++++++
>  2 files changed, 40 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr107304.c
>
> diff --git a/gcc/expr.cc b/gcc/expr.cc
> index efe387e6173..9145193c2c1 100644
> --- a/gcc/expr.cc
> +++ b/gcc/expr.cc
> @@ -7905,8 +7905,7 @@ get_inner_reference (tree exp, poly_int64_pod *pbitsize,
>           /* For vector fields re-check the target flags, as DECL_MODE
>              could have been set with different target flags than
>              the current function has.  */
> -         if (mode == BLKmode
> -             && VECTOR_TYPE_P (TREE_TYPE (field))
> +         if (VECTOR_TYPE_P (TREE_TYPE (field))
>               && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))

Isn't the check on TYPE_MODE_RAW also wrong then?  Btw, the mode could
also be an integer mode.

>             mode = TYPE_MODE (TREE_TYPE (field));
>         }
> diff --git a/gcc/testsuite/gcc.target/i386/pr107304.c b/gcc/testsuite/gcc.target/i386/pr107304.c
> new file mode 100644
> index 00000000000..24d68795e7f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr107304.c
> @@ -0,0 +1,39 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O0 -march=tigerlake" } */
> +
> +#include <stdint.h>
> +
> +typedef union {
> +  uint8_t v __attribute__((aligned(256))) __attribute__ ((vector_size(64 * sizeof(uint8_t))));
> +  uint8_t i[64] __attribute__((aligned(256)));
> +} stress_vec_u8_64_t;
> +
> +typedef struct {
> + struct {
> +  stress_vec_u8_64_t s;
> +  stress_vec_u8_64_t o;
> +  stress_vec_u8_64_t mask1;
> +  stress_vec_u8_64_t mask2;
> + } u8_64;
> +} stress_vec_data_t;
> +
> +__attribute__((target_clones("arch=alderlake", "default")))
> +void
> +stress_vecshuf_u8_64(stress_vec_data_t *data)
> +{
> +  stress_vec_u8_64_t *__restrict s;
> +  stress_vec_u8_64_t *__restrict mask1;
> +  stress_vec_u8_64_t *__restrict mask2;
> +  register int i;
> +
> +  s = &data->u8_64.s;
> +  mask1 = &data->u8_64.mask1;
> +  mask2 = &data->u8_64.mask2;
> +
> +  for (i = 0; i < 256; i++) {  /* was i < 65536 */
> +      stress_vec_u8_64_t tmp;
> +
> +      tmp.v = __builtin_shuffle(s->v, mask1->v);
> +      s->v = __builtin_shuffle(tmp.v, mask2->v);
> +  }
> +}
> --
> 2.37.3
>
H.J. Lu Oct. 21, 2022, 4:18 p.m. UTC | #2
On Fri, Oct 21, 2022 at 2:33 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Thu, Oct 20, 2022 at 6:58 PM H.J. Lu via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > commit e034c5c895722e0092d2239cd8c2991db77d6d39
> > Author: Jakub Jelinek <jakub@redhat.com>
> > Date:   Sat Dec 2 08:54:47 2017 +0100
> >
> >         PR target/78643
> >         PR target/80583
> >         * expr.c (get_inner_reference): If DECL_MODE of a non-bitfield
> >         is BLKmode for vector field with vector raw mode, use TYPE_MODE
> >         instead of DECL_MODE.
> >
> > fixed the case where DECL_MODE of a vector field is BLKmode and its
> > TYPE_MODE is a vector mode because of target attribute.  Remove the
> > BLKmode check for the case where DECL_MODE of a vector field is a vector
> > mode and its TYPE_MODE is BLKmode because of target attribute.
> >
> > gcc/
> >
> >         PR target/107304
> >         * expr.c (get_inner_reference): Always use TYPE_MODE for vector
> >         field with vector raw mode.
> >
> > gcc/testsuite/
> >
> >         PR target/107304
> >         * gcc.target/i386/pr107304.c: New test.
> > ---
> >  gcc/expr.cc                              |  3 +-
> >  gcc/testsuite/gcc.target/i386/pr107304.c | 39 ++++++++++++++++++++++++
> >  2 files changed, 40 insertions(+), 2 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr107304.c
> >
> > diff --git a/gcc/expr.cc b/gcc/expr.cc
> > index efe387e6173..9145193c2c1 100644
> > --- a/gcc/expr.cc
> > +++ b/gcc/expr.cc
> > @@ -7905,8 +7905,7 @@ get_inner_reference (tree exp, poly_int64_pod *pbitsize,
> >           /* For vector fields re-check the target flags, as DECL_MODE
> >              could have been set with different target flags than
> >              the current function has.  */
> > -         if (mode == BLKmode
> > -             && VECTOR_TYPE_P (TREE_TYPE (field))
> > +         if (VECTOR_TYPE_P (TREE_TYPE (field))
> >               && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
>
> Isn't the check on TYPE_MODE_RAW also wrong then?  Btw, the mode could

TYPE_MODE_RAW is always set to a vector mode for a vector type:

       /* Find an appropriate mode for the vector type.  */
        if (TYPE_MODE (type) == VOIDmode)
          SET_TYPE_MODE (type,
                         mode_for_vector (SCALAR_TYPE_MODE (innertype),
                                          nunits).else_blk ());

But TYPE_MODE returns BLKmode if the vector mode is unsupported.

> also be an integer mode.

For a vector field, mode is either BLK mode or the vector mode.  Jakub,
can you comment on it?

>
> >             mode = TYPE_MODE (TREE_TYPE (field));
> >         }
> > diff --git a/gcc/testsuite/gcc.target/i386/pr107304.c b/gcc/testsuite/gcc.target/i386/pr107304.c
> > new file mode 100644
> > index 00000000000..24d68795e7f
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/i386/pr107304.c
> > @@ -0,0 +1,39 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O0 -march=tigerlake" } */
> > +
> > +#include <stdint.h>
> > +
> > +typedef union {
> > +  uint8_t v __attribute__((aligned(256))) __attribute__ ((vector_size(64 * sizeof(uint8_t))));
> > +  uint8_t i[64] __attribute__((aligned(256)));
> > +} stress_vec_u8_64_t;
> > +
> > +typedef struct {
> > + struct {
> > +  stress_vec_u8_64_t s;
> > +  stress_vec_u8_64_t o;
> > +  stress_vec_u8_64_t mask1;
> > +  stress_vec_u8_64_t mask2;
> > + } u8_64;
> > +} stress_vec_data_t;
> > +
> > +__attribute__((target_clones("arch=alderlake", "default")))
> > +void
> > +stress_vecshuf_u8_64(stress_vec_data_t *data)
> > +{
> > +  stress_vec_u8_64_t *__restrict s;
> > +  stress_vec_u8_64_t *__restrict mask1;
> > +  stress_vec_u8_64_t *__restrict mask2;
> > +  register int i;
> > +
> > +  s = &data->u8_64.s;
> > +  mask1 = &data->u8_64.mask1;
> > +  mask2 = &data->u8_64.mask2;
> > +
> > +  for (i = 0; i < 256; i++) {  /* was i < 65536 */
> > +      stress_vec_u8_64_t tmp;
> > +
> > +      tmp.v = __builtin_shuffle(s->v, mask1->v);
> > +      s->v = __builtin_shuffle(tmp.v, mask2->v);
> > +  }
> > +}
> > --
> > 2.37.3
> >
Richard Biener Oct. 24, 2022, 7:12 a.m. UTC | #3
On Fri, Oct 21, 2022 at 6:18 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Fri, Oct 21, 2022 at 2:33 AM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > On Thu, Oct 20, 2022 at 6:58 PM H.J. Lu via Gcc-patches
> > <gcc-patches@gcc.gnu.org> wrote:
> > >
> > > commit e034c5c895722e0092d2239cd8c2991db77d6d39
> > > Author: Jakub Jelinek <jakub@redhat.com>
> > > Date:   Sat Dec 2 08:54:47 2017 +0100
> > >
> > >         PR target/78643
> > >         PR target/80583
> > >         * expr.c (get_inner_reference): If DECL_MODE of a non-bitfield
> > >         is BLKmode for vector field with vector raw mode, use TYPE_MODE
> > >         instead of DECL_MODE.
> > >
> > > fixed the case where DECL_MODE of a vector field is BLKmode and its
> > > TYPE_MODE is a vector mode because of target attribute.  Remove the
> > > BLKmode check for the case where DECL_MODE of a vector field is a vector
> > > mode and its TYPE_MODE is BLKmode because of target attribute.
> > >
> > > gcc/
> > >
> > >         PR target/107304
> > >         * expr.c (get_inner_reference): Always use TYPE_MODE for vector
> > >         field with vector raw mode.
> > >
> > > gcc/testsuite/
> > >
> > >         PR target/107304
> > >         * gcc.target/i386/pr107304.c: New test.
> > > ---
> > >  gcc/expr.cc                              |  3 +-
> > >  gcc/testsuite/gcc.target/i386/pr107304.c | 39 ++++++++++++++++++++++++
> > >  2 files changed, 40 insertions(+), 2 deletions(-)
> > >  create mode 100644 gcc/testsuite/gcc.target/i386/pr107304.c
> > >
> > > diff --git a/gcc/expr.cc b/gcc/expr.cc
> > > index efe387e6173..9145193c2c1 100644
> > > --- a/gcc/expr.cc
> > > +++ b/gcc/expr.cc
> > > @@ -7905,8 +7905,7 @@ get_inner_reference (tree exp, poly_int64_pod *pbitsize,
> > >           /* For vector fields re-check the target flags, as DECL_MODE
> > >              could have been set with different target flags than
> > >              the current function has.  */
> > > -         if (mode == BLKmode
> > > -             && VECTOR_TYPE_P (TREE_TYPE (field))
> > > +         if (VECTOR_TYPE_P (TREE_TYPE (field))
> > >               && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
> >
> > Isn't the check on TYPE_MODE_RAW also wrong then?  Btw, the mode could
>
> TYPE_MODE_RAW is always set to a vector mode for a vector type:
>
>        /* Find an appropriate mode for the vector type.  */
>         if (TYPE_MODE (type) == VOIDmode)
>           SET_TYPE_MODE (type,
>                          mode_for_vector (SCALAR_TYPE_MODE (innertype),
>                                           nunits).else_blk ());

But mode_for_vector can return a MODE_INT!

  /* For integers, try mapping it to a same-sized scalar mode.  */
  if (GET_MODE_CLASS (innermode) == MODE_INT)
    {
      poly_uint64 nbits = nunits * GET_MODE_BITSIZE (innermode);
      if (int_mode_for_size (nbits, 0).exists (&mode)
          && have_regs_of_mode[mode])
        return mode;

> But TYPE_MODE returns BLKmode if the vector mode is unsupported.
>
> > also be an integer mode.
>
> For a vector field, mode is either BLK mode or the vector mode.  Jakub,
> can you comment on it?

I think that for

typedef int v2si __attribute__((vector_size(8)));

struct X { int i; v2si j; };

v2si should get DImode with -mno-sse?

> >
> > >             mode = TYPE_MODE (TREE_TYPE (field));
> > >         }
> > > diff --git a/gcc/testsuite/gcc.target/i386/pr107304.c b/gcc/testsuite/gcc.target/i386/pr107304.c
> > > new file mode 100644
> > > index 00000000000..24d68795e7f
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.target/i386/pr107304.c
> > > @@ -0,0 +1,39 @@
> > > +/* { dg-do compile } */
> > > +/* { dg-options "-O0 -march=tigerlake" } */
> > > +
> > > +#include <stdint.h>
> > > +
> > > +typedef union {
> > > +  uint8_t v __attribute__((aligned(256))) __attribute__ ((vector_size(64 * sizeof(uint8_t))));
> > > +  uint8_t i[64] __attribute__((aligned(256)));
> > > +} stress_vec_u8_64_t;
> > > +
> > > +typedef struct {
> > > + struct {
> > > +  stress_vec_u8_64_t s;
> > > +  stress_vec_u8_64_t o;
> > > +  stress_vec_u8_64_t mask1;
> > > +  stress_vec_u8_64_t mask2;
> > > + } u8_64;
> > > +} stress_vec_data_t;
> > > +
> > > +__attribute__((target_clones("arch=alderlake", "default")))
> > > +void
> > > +stress_vecshuf_u8_64(stress_vec_data_t *data)
> > > +{
> > > +  stress_vec_u8_64_t *__restrict s;
> > > +  stress_vec_u8_64_t *__restrict mask1;
> > > +  stress_vec_u8_64_t *__restrict mask2;
> > > +  register int i;
> > > +
> > > +  s = &data->u8_64.s;
> > > +  mask1 = &data->u8_64.mask1;
> > > +  mask2 = &data->u8_64.mask2;
> > > +
> > > +  for (i = 0; i < 256; i++) {  /* was i < 65536 */
> > > +      stress_vec_u8_64_t tmp;
> > > +
> > > +      tmp.v = __builtin_shuffle(s->v, mask1->v);
> > > +      s->v = __builtin_shuffle(tmp.v, mask2->v);
> > > +  }
> > > +}
> > > --
> > > 2.37.3
> > >
>
>
>
> --
> H.J.
H.J. Lu Oct. 24, 2022, 8:01 p.m. UTC | #4
On Mon, Oct 24, 2022 at 12:12 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Fri, Oct 21, 2022 at 6:18 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > On Fri, Oct 21, 2022 at 2:33 AM Richard Biener
> > <richard.guenther@gmail.com> wrote:
> > >
> > > On Thu, Oct 20, 2022 at 6:58 PM H.J. Lu via Gcc-patches
> > > <gcc-patches@gcc.gnu.org> wrote:
> > > >
> > > > commit e034c5c895722e0092d2239cd8c2991db77d6d39
> > > > Author: Jakub Jelinek <jakub@redhat.com>
> > > > Date:   Sat Dec 2 08:54:47 2017 +0100
> > > >
> > > >         PR target/78643
> > > >         PR target/80583
> > > >         * expr.c (get_inner_reference): If DECL_MODE of a non-bitfield
> > > >         is BLKmode for vector field with vector raw mode, use TYPE_MODE
> > > >         instead of DECL_MODE.
> > > >
> > > > fixed the case where DECL_MODE of a vector field is BLKmode and its
> > > > TYPE_MODE is a vector mode because of target attribute.  Remove the
> > > > BLKmode check for the case where DECL_MODE of a vector field is a vector
> > > > mode and its TYPE_MODE is BLKmode because of target attribute.
> > > >
> > > > gcc/
> > > >
> > > >         PR target/107304
> > > >         * expr.c (get_inner_reference): Always use TYPE_MODE for vector
> > > >         field with vector raw mode.
> > > >
> > > > gcc/testsuite/
> > > >
> > > >         PR target/107304
> > > >         * gcc.target/i386/pr107304.c: New test.
> > > > ---
> > > >  gcc/expr.cc                              |  3 +-
> > > >  gcc/testsuite/gcc.target/i386/pr107304.c | 39 ++++++++++++++++++++++++
> > > >  2 files changed, 40 insertions(+), 2 deletions(-)
> > > >  create mode 100644 gcc/testsuite/gcc.target/i386/pr107304.c
> > > >
> > > > diff --git a/gcc/expr.cc b/gcc/expr.cc
> > > > index efe387e6173..9145193c2c1 100644
> > > > --- a/gcc/expr.cc
> > > > +++ b/gcc/expr.cc
> > > > @@ -7905,8 +7905,7 @@ get_inner_reference (tree exp, poly_int64_pod *pbitsize,
> > > >           /* For vector fields re-check the target flags, as DECL_MODE
> > > >              could have been set with different target flags than
> > > >              the current function has.  */
> > > > -         if (mode == BLKmode
> > > > -             && VECTOR_TYPE_P (TREE_TYPE (field))
> > > > +         if (VECTOR_TYPE_P (TREE_TYPE (field))
> > > >               && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
> > >
> > > Isn't the check on TYPE_MODE_RAW also wrong then?  Btw, the mode could
> >
> > TYPE_MODE_RAW is always set to a vector mode for a vector type:
> >
> >        /* Find an appropriate mode for the vector type.  */
> >         if (TYPE_MODE (type) == VOIDmode)
> >           SET_TYPE_MODE (type,
> >                          mode_for_vector (SCALAR_TYPE_MODE (innertype),
> >                                           nunits).else_blk ());
>
> But mode_for_vector can return a MODE_INT!

You are right.

>   /* For integers, try mapping it to a same-sized scalar mode.  */
>   if (GET_MODE_CLASS (innermode) == MODE_INT)
>     {
>       poly_uint64 nbits = nunits * GET_MODE_BITSIZE (innermode);
>       if (int_mode_for_size (nbits, 0).exists (&mode)
>           && have_regs_of_mode[mode])
>         return mode;
>
> > But TYPE_MODE returns BLKmode if the vector mode is unsupported.
> >
> > > also be an integer mode.
> >
> > For a vector field, mode is either BLK mode or the vector mode.  Jakub,
> > can you comment on it?
>
> I think that for
>
> typedef int v2si __attribute__((vector_size(8)));
>
> struct X { int i; v2si j; };
>
> v2si should get DImode with -mno-sse?
>

Currently GCC generates

(insn 31 32 33 (set (subreg:DI (reg:V2SI 105) 0)
        (reg:DI 84 [ _3 ])) "y2.c":12:11 -1
     (nil))

With my patch, v2si gets DImode directly without SUBREG.

Here is the v2 patch with the update commit message:

Remove the BLKmode check for the case where DECL_MODE
of a vector field is a vector mode and its TYPE_MODE isn't a
vector mode because of target attribute.

OK for master?

Thanks.
Richard Biener Oct. 25, 2022, 6:27 a.m. UTC | #5
On Mon, Oct 24, 2022 at 10:02 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Mon, Oct 24, 2022 at 12:12 AM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > On Fri, Oct 21, 2022 at 6:18 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > >
> > > On Fri, Oct 21, 2022 at 2:33 AM Richard Biener
> > > <richard.guenther@gmail.com> wrote:
> > > >
> > > > On Thu, Oct 20, 2022 at 6:58 PM H.J. Lu via Gcc-patches
> > > > <gcc-patches@gcc.gnu.org> wrote:
> > > > >
> > > > > commit e034c5c895722e0092d2239cd8c2991db77d6d39
> > > > > Author: Jakub Jelinek <jakub@redhat.com>
> > > > > Date:   Sat Dec 2 08:54:47 2017 +0100
> > > > >
> > > > >         PR target/78643
> > > > >         PR target/80583
> > > > >         * expr.c (get_inner_reference): If DECL_MODE of a non-bitfield
> > > > >         is BLKmode for vector field with vector raw mode, use TYPE_MODE
> > > > >         instead of DECL_MODE.
> > > > >
> > > > > fixed the case where DECL_MODE of a vector field is BLKmode and its
> > > > > TYPE_MODE is a vector mode because of target attribute.  Remove the
> > > > > BLKmode check for the case where DECL_MODE of a vector field is a vector
> > > > > mode and its TYPE_MODE is BLKmode because of target attribute.
> > > > >
> > > > > gcc/
> > > > >
> > > > >         PR target/107304
> > > > >         * expr.c (get_inner_reference): Always use TYPE_MODE for vector
> > > > >         field with vector raw mode.
> > > > >
> > > > > gcc/testsuite/
> > > > >
> > > > >         PR target/107304
> > > > >         * gcc.target/i386/pr107304.c: New test.
> > > > > ---
> > > > >  gcc/expr.cc                              |  3 +-
> > > > >  gcc/testsuite/gcc.target/i386/pr107304.c | 39 ++++++++++++++++++++++++
> > > > >  2 files changed, 40 insertions(+), 2 deletions(-)
> > > > >  create mode 100644 gcc/testsuite/gcc.target/i386/pr107304.c
> > > > >
> > > > > diff --git a/gcc/expr.cc b/gcc/expr.cc
> > > > > index efe387e6173..9145193c2c1 100644
> > > > > --- a/gcc/expr.cc
> > > > > +++ b/gcc/expr.cc
> > > > > @@ -7905,8 +7905,7 @@ get_inner_reference (tree exp, poly_int64_pod *pbitsize,
> > > > >           /* For vector fields re-check the target flags, as DECL_MODE
> > > > >              could have been set with different target flags than
> > > > >              the current function has.  */
> > > > > -         if (mode == BLKmode
> > > > > -             && VECTOR_TYPE_P (TREE_TYPE (field))
> > > > > +         if (VECTOR_TYPE_P (TREE_TYPE (field))
> > > > >               && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
> > > >
> > > > Isn't the check on TYPE_MODE_RAW also wrong then?  Btw, the mode could
> > >
> > > TYPE_MODE_RAW is always set to a vector mode for a vector type:
> > >
> > >        /* Find an appropriate mode for the vector type.  */
> > >         if (TYPE_MODE (type) == VOIDmode)
> > >           SET_TYPE_MODE (type,
> > >                          mode_for_vector (SCALAR_TYPE_MODE (innertype),
> > >                                           nunits).else_blk ());
> >
> > But mode_for_vector can return a MODE_INT!
>
> You are right.
>
> >   /* For integers, try mapping it to a same-sized scalar mode.  */
> >   if (GET_MODE_CLASS (innermode) == MODE_INT)
> >     {
> >       poly_uint64 nbits = nunits * GET_MODE_BITSIZE (innermode);
> >       if (int_mode_for_size (nbits, 0).exists (&mode)
> >           && have_regs_of_mode[mode])
> >         return mode;
> >
> > > But TYPE_MODE returns BLKmode if the vector mode is unsupported.
> > >
> > > > also be an integer mode.
> > >
> > > For a vector field, mode is either BLK mode or the vector mode.  Jakub,
> > > can you comment on it?
> >
> > I think that for
> >
> > typedef int v2si __attribute__((vector_size(8)));
> >
> > struct X { int i; v2si j; };
> >
> > v2si should get DImode with -mno-sse?
> >
>
> Currently GCC generates
>
> (insn 31 32 33 (set (subreg:DI (reg:V2SI 105) 0)
>         (reg:DI 84 [ _3 ])) "y2.c":12:11 -1
>      (nil))
>
> With my patch, v2si gets DImode directly without SUBREG.
>
> Here is the v2 patch with the update commit message:
>
> Remove the BLKmode check for the case where DECL_MODE
> of a vector field is a vector mode and its TYPE_MODE isn't a
> vector mode because of target attribute.
>
> OK for master?

OK.

Thanks,
Richard.

> Thanks.
>
> --
> H.J.
H.J. Lu Nov. 7, 2022, 8:07 p.m. UTC | #6
On Mon, Oct 24, 2022 at 11:28 PM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Mon, Oct 24, 2022 at 10:02 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > On Mon, Oct 24, 2022 at 12:12 AM Richard Biener
> > <richard.guenther@gmail.com> wrote:
> > >
> > > On Fri, Oct 21, 2022 at 6:18 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > >
> > > > On Fri, Oct 21, 2022 at 2:33 AM Richard Biener
> > > > <richard.guenther@gmail.com> wrote:
> > > > >
> > > > > On Thu, Oct 20, 2022 at 6:58 PM H.J. Lu via Gcc-patches
> > > > > <gcc-patches@gcc.gnu.org> wrote:
> > > > > >
> > > > > > commit e034c5c895722e0092d2239cd8c2991db77d6d39
> > > > > > Author: Jakub Jelinek <jakub@redhat.com>
> > > > > > Date:   Sat Dec 2 08:54:47 2017 +0100
> > > > > >
> > > > > >         PR target/78643
> > > > > >         PR target/80583
> > > > > >         * expr.c (get_inner_reference): If DECL_MODE of a non-bitfield
> > > > > >         is BLKmode for vector field with vector raw mode, use TYPE_MODE
> > > > > >         instead of DECL_MODE.
> > > > > >
> > > > > > fixed the case where DECL_MODE of a vector field is BLKmode and its
> > > > > > TYPE_MODE is a vector mode because of target attribute.  Remove the
> > > > > > BLKmode check for the case where DECL_MODE of a vector field is a vector
> > > > > > mode and its TYPE_MODE is BLKmode because of target attribute.
> > > > > >
> > > > > > gcc/
> > > > > >
> > > > > >         PR target/107304
> > > > > >         * expr.c (get_inner_reference): Always use TYPE_MODE for vector
> > > > > >         field with vector raw mode.
> > > > > >
> > > > > > gcc/testsuite/
> > > > > >
> > > > > >         PR target/107304
> > > > > >         * gcc.target/i386/pr107304.c: New test.
> > > > > > ---
> > > > > >  gcc/expr.cc                              |  3 +-
> > > > > >  gcc/testsuite/gcc.target/i386/pr107304.c | 39 ++++++++++++++++++++++++
> > > > > >  2 files changed, 40 insertions(+), 2 deletions(-)
> > > > > >  create mode 100644 gcc/testsuite/gcc.target/i386/pr107304.c
> > > > > >
> > > > > > diff --git a/gcc/expr.cc b/gcc/expr.cc
> > > > > > index efe387e6173..9145193c2c1 100644
> > > > > > --- a/gcc/expr.cc
> > > > > > +++ b/gcc/expr.cc
> > > > > > @@ -7905,8 +7905,7 @@ get_inner_reference (tree exp, poly_int64_pod *pbitsize,
> > > > > >           /* For vector fields re-check the target flags, as DECL_MODE
> > > > > >              could have been set with different target flags than
> > > > > >              the current function has.  */
> > > > > > -         if (mode == BLKmode
> > > > > > -             && VECTOR_TYPE_P (TREE_TYPE (field))
> > > > > > +         if (VECTOR_TYPE_P (TREE_TYPE (field))
> > > > > >               && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
> > > > >
> > > > > Isn't the check on TYPE_MODE_RAW also wrong then?  Btw, the mode could
> > > >
> > > > TYPE_MODE_RAW is always set to a vector mode for a vector type:
> > > >
> > > >        /* Find an appropriate mode for the vector type.  */
> > > >         if (TYPE_MODE (type) == VOIDmode)
> > > >           SET_TYPE_MODE (type,
> > > >                          mode_for_vector (SCALAR_TYPE_MODE (innertype),
> > > >                                           nunits).else_blk ());
> > >
> > > But mode_for_vector can return a MODE_INT!
> >
> > You are right.
> >
> > >   /* For integers, try mapping it to a same-sized scalar mode.  */
> > >   if (GET_MODE_CLASS (innermode) == MODE_INT)
> > >     {
> > >       poly_uint64 nbits = nunits * GET_MODE_BITSIZE (innermode);
> > >       if (int_mode_for_size (nbits, 0).exists (&mode)
> > >           && have_regs_of_mode[mode])
> > >         return mode;
> > >
> > > > But TYPE_MODE returns BLKmode if the vector mode is unsupported.
> > > >
> > > > > also be an integer mode.
> > > >
> > > > For a vector field, mode is either BLK mode or the vector mode.  Jakub,
> > > > can you comment on it?
> > >
> > > I think that for
> > >
> > > typedef int v2si __attribute__((vector_size(8)));
> > >
> > > struct X { int i; v2si j; };
> > >
> > > v2si should get DImode with -mno-sse?
> > >
> >
> > Currently GCC generates
> >
> > (insn 31 32 33 (set (subreg:DI (reg:V2SI 105) 0)
> >         (reg:DI 84 [ _3 ])) "y2.c":12:11 -1
> >      (nil))
> >
> > With my patch, v2si gets DImode directly without SUBREG.
> >
> > Here is the v2 patch with the update commit message:
> >
> > Remove the BLKmode check for the case where DECL_MODE
> > of a vector field is a vector mode and its TYPE_MODE isn't a
> > vector mode because of target attribute.
> >
> > OK for master?
>
> OK.

OK to backport to release branches?

Thanks.
Richard Biener Nov. 8, 2022, 9:42 a.m. UTC | #7
On Mon, Nov 7, 2022 at 9:07 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Mon, Oct 24, 2022 at 11:28 PM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > On Mon, Oct 24, 2022 at 10:02 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > >
> > > On Mon, Oct 24, 2022 at 12:12 AM Richard Biener
> > > <richard.guenther@gmail.com> wrote:
> > > >
> > > > On Fri, Oct 21, 2022 at 6:18 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > > >
> > > > > On Fri, Oct 21, 2022 at 2:33 AM Richard Biener
> > > > > <richard.guenther@gmail.com> wrote:
> > > > > >
> > > > > > On Thu, Oct 20, 2022 at 6:58 PM H.J. Lu via Gcc-patches
> > > > > > <gcc-patches@gcc.gnu.org> wrote:
> > > > > > >
> > > > > > > commit e034c5c895722e0092d2239cd8c2991db77d6d39
> > > > > > > Author: Jakub Jelinek <jakub@redhat.com>
> > > > > > > Date:   Sat Dec 2 08:54:47 2017 +0100
> > > > > > >
> > > > > > >         PR target/78643
> > > > > > >         PR target/80583
> > > > > > >         * expr.c (get_inner_reference): If DECL_MODE of a non-bitfield
> > > > > > >         is BLKmode for vector field with vector raw mode, use TYPE_MODE
> > > > > > >         instead of DECL_MODE.
> > > > > > >
> > > > > > > fixed the case where DECL_MODE of a vector field is BLKmode and its
> > > > > > > TYPE_MODE is a vector mode because of target attribute.  Remove the
> > > > > > > BLKmode check for the case where DECL_MODE of a vector field is a vector
> > > > > > > mode and its TYPE_MODE is BLKmode because of target attribute.
> > > > > > >
> > > > > > > gcc/
> > > > > > >
> > > > > > >         PR target/107304
> > > > > > >         * expr.c (get_inner_reference): Always use TYPE_MODE for vector
> > > > > > >         field with vector raw mode.
> > > > > > >
> > > > > > > gcc/testsuite/
> > > > > > >
> > > > > > >         PR target/107304
> > > > > > >         * gcc.target/i386/pr107304.c: New test.
> > > > > > > ---
> > > > > > >  gcc/expr.cc                              |  3 +-
> > > > > > >  gcc/testsuite/gcc.target/i386/pr107304.c | 39 ++++++++++++++++++++++++
> > > > > > >  2 files changed, 40 insertions(+), 2 deletions(-)
> > > > > > >  create mode 100644 gcc/testsuite/gcc.target/i386/pr107304.c
> > > > > > >
> > > > > > > diff --git a/gcc/expr.cc b/gcc/expr.cc
> > > > > > > index efe387e6173..9145193c2c1 100644
> > > > > > > --- a/gcc/expr.cc
> > > > > > > +++ b/gcc/expr.cc
> > > > > > > @@ -7905,8 +7905,7 @@ get_inner_reference (tree exp, poly_int64_pod *pbitsize,
> > > > > > >           /* For vector fields re-check the target flags, as DECL_MODE
> > > > > > >              could have been set with different target flags than
> > > > > > >              the current function has.  */
> > > > > > > -         if (mode == BLKmode
> > > > > > > -             && VECTOR_TYPE_P (TREE_TYPE (field))
> > > > > > > +         if (VECTOR_TYPE_P (TREE_TYPE (field))
> > > > > > >               && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
> > > > > >
> > > > > > Isn't the check on TYPE_MODE_RAW also wrong then?  Btw, the mode could
> > > > >
> > > > > TYPE_MODE_RAW is always set to a vector mode for a vector type:
> > > > >
> > > > >        /* Find an appropriate mode for the vector type.  */
> > > > >         if (TYPE_MODE (type) == VOIDmode)
> > > > >           SET_TYPE_MODE (type,
> > > > >                          mode_for_vector (SCALAR_TYPE_MODE (innertype),
> > > > >                                           nunits).else_blk ());
> > > >
> > > > But mode_for_vector can return a MODE_INT!
> > >
> > > You are right.
> > >
> > > >   /* For integers, try mapping it to a same-sized scalar mode.  */
> > > >   if (GET_MODE_CLASS (innermode) == MODE_INT)
> > > >     {
> > > >       poly_uint64 nbits = nunits * GET_MODE_BITSIZE (innermode);
> > > >       if (int_mode_for_size (nbits, 0).exists (&mode)
> > > >           && have_regs_of_mode[mode])
> > > >         return mode;
> > > >
> > > > > But TYPE_MODE returns BLKmode if the vector mode is unsupported.
> > > > >
> > > > > > also be an integer mode.
> > > > >
> > > > > For a vector field, mode is either BLK mode or the vector mode.  Jakub,
> > > > > can you comment on it?
> > > >
> > > > I think that for
> > > >
> > > > typedef int v2si __attribute__((vector_size(8)));
> > > >
> > > > struct X { int i; v2si j; };
> > > >
> > > > v2si should get DImode with -mno-sse?
> > > >
> > >
> > > Currently GCC generates
> > >
> > > (insn 31 32 33 (set (subreg:DI (reg:V2SI 105) 0)
> > >         (reg:DI 84 [ _3 ])) "y2.c":12:11 -1
> > >      (nil))
> > >
> > > With my patch, v2si gets DImode directly without SUBREG.
> > >
> > > Here is the v2 patch with the update commit message:
> > >
> > > Remove the BLKmode check for the case where DECL_MODE
> > > of a vector field is a vector mode and its TYPE_MODE isn't a
> > > vector mode because of target attribute.
> > >
> > > OK for master?
> >
> > OK.
>
> OK to backport to release branches?

Yes

> Thanks.
>
> --
> H.J.
diff mbox series

Patch

diff --git a/gcc/expr.cc b/gcc/expr.cc
index efe387e6173..9145193c2c1 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -7905,8 +7905,7 @@  get_inner_reference (tree exp, poly_int64_pod *pbitsize,
 	  /* For vector fields re-check the target flags, as DECL_MODE
 	     could have been set with different target flags than
 	     the current function has.  */
-	  if (mode == BLKmode
-	      && VECTOR_TYPE_P (TREE_TYPE (field))
+	  if (VECTOR_TYPE_P (TREE_TYPE (field))
 	      && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
 	    mode = TYPE_MODE (TREE_TYPE (field));
 	}
diff --git a/gcc/testsuite/gcc.target/i386/pr107304.c b/gcc/testsuite/gcc.target/i386/pr107304.c
new file mode 100644
index 00000000000..24d68795e7f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107304.c
@@ -0,0 +1,39 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O0 -march=tigerlake" } */
+
+#include <stdint.h>
+
+typedef union {
+  uint8_t v __attribute__((aligned(256))) __attribute__ ((vector_size(64 * sizeof(uint8_t))));
+  uint8_t i[64] __attribute__((aligned(256)));
+} stress_vec_u8_64_t;
+
+typedef struct {
+ struct {
+  stress_vec_u8_64_t s;
+  stress_vec_u8_64_t o;
+  stress_vec_u8_64_t mask1;
+  stress_vec_u8_64_t mask2;
+ } u8_64;
+} stress_vec_data_t;
+
+__attribute__((target_clones("arch=alderlake", "default"))) 
+void
+stress_vecshuf_u8_64(stress_vec_data_t *data)
+{
+  stress_vec_u8_64_t *__restrict s;
+  stress_vec_u8_64_t *__restrict mask1;
+  stress_vec_u8_64_t *__restrict mask2;
+  register int i;
+
+  s = &data->u8_64.s;
+  mask1 = &data->u8_64.mask1;
+  mask2 = &data->u8_64.mask2;
+
+  for (i = 0; i < 256; i++) {	/* was i < 65536 */
+      stress_vec_u8_64_t tmp;
+
+      tmp.v = __builtin_shuffle(s->v, mask1->v);
+      s->v = __builtin_shuffle(tmp.v, mask2->v);
+  }
+}