> 
> 
> > Am 22.09.2026 um 16:29 schrieb Juergen Christ <[email protected]>:
> > 
> > If vec_perm intrinsic is called with a constant permutation vector, try to
> > optimize this such that the permutation vector can be removed altogether.
> 
> Looks like folding the intrinsic to a VEC_PERM_EXPR would do this 
> automatically?

Thanks for the hint.  I was not aware we could do that.  s390 so far
does not implement that hook.  I am bootstrapping and regtesting a
patch...

> 
> > gcc/ChangeLog:
> > 
> >    * config/s390/s390.cc (s390_expand_builtin): Optimize vec_perm
> >          builtin.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> >    * gcc.target/s390/zvector/vec_perm-1.c: New test.
> > 
> > Bootstrapped and regtested on s390x.  Ok for trunk?
> > 
> > Signed-off-by: Juergen Christ <[email protected]>
> > ---
> > gcc/config/s390/s390.cc                       |  8 ++
> > .../gcc.target/s390/zvector/vec_perm-1.c      | 79 +++++++++++++++++++
> > 2 files changed, 87 insertions(+)
> > create mode 100644 gcc/testsuite/gcc.target/s390/zvector/vec_perm-1.c
> > 
> > diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
> > index 2e7997979918..94ffdaba53b8 100644
> > --- a/gcc/config/s390/s390.cc
> > +++ b/gcc/config/s390/s390.cc
> > @@ -972,6 +972,14 @@ s390_expand_builtin (tree exp, rtx target, rtx 
> > subtarget ATTRIBUTE_UNUSED,
> >       if (arity >= MAX_ARGS)
> >    return NULL_RTX;
> > 
> > +      vec_perm_builder sel;
> > +      if (arity == 2 && icode == CODE_FOR_vec_permv16qi
> > +      && TREE_CODE(arg) == VECTOR_CST
> > +      && tree_to_vec_perm_builder (&sel, arg))
> > +    return expand_vec_perm_const (mode, op[0], op[1], sel,
> > +                      TYPE_MODE (TREE_TYPE (arg)),
> > +                      target);
> > +
> >       if (O_IMM_P (op_flags)
> >      && TREE_CODE (arg) != INTEGER_CST)
> >    {
> > diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec_perm-1.c 
> > b/gcc/testsuite/gcc.target/s390/zvector/vec_perm-1.c
> > new file mode 100644
> > index 000000000000..9c6d17381f53
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/s390/zvector/vec_perm-1.c
> > @@ -0,0 +1,79 @@
> > +/* Test whether vec_perm with constant permutation mask gets optimized.  */
> > +
> > +/* { dg-do compile { target { s390*-*-* } } } */
> > +/* { dg-options "-march=z14 -mzarch -mzvector" } */
> > +
> > +#include <vecintrin.h>
> > +
> > +typedef signed char v16qi __attribute__((vector_size(16)));
> > +typedef unsigned char uv16qi __attribute__((vector_size(16)));
> > +typedef char bv16qi __attribute__((vector_size(16),s390_vector_bool));
> > +
> > +typedef signed short int v8hi __attribute__((vector_size(16)));
> > +typedef unsigned short int uv8hi __attribute__((vector_size(16)));
> > +typedef short int bv8hi __attribute__((vector_size(16),s390_vector_bool));
> > +
> > +typedef signed int v4si __attribute__((vector_size(16)));
> > +typedef unsigned int uv4si __attribute__((vector_size(16)));
> > +typedef int bv4si __attribute__((vector_size(16),s390_vector_bool));
> > +
> > +typedef signed long long v2di __attribute__((vector_size(16)));
> > +typedef unsigned long long uv2di __attribute__((vector_size(16)));
> > +typedef long long bv2di __attribute__((vector_size(16),s390_vector_bool));
> > +
> > +typedef float v4sf __attribute__((vector_size(16)));
> > +typedef double v2df __attribute__((vector_size(16)));
> > +
> > +#define T(t)                                \
> > +  t                                    \
> > +  mergehi_##t (t in)                            \
> > +  {                                    \
> > +    return vec_perm (in, in,                        \
> > +             (__vector unsigned char)                \
> > +             {0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23});    \
> > +  }                                    \
> > +  t                                    \
> > +  mergelow_##t (t in)                            \
> > +  {                                    \
> > +  return vec_perm (in, in,                        \
> > +           (__vector unsigned char)                \
> > +           {8,9,10,11,12,13,14,15,24,25,26,27,28,29,30,31});    \
> > +  }                                    \
> > +  t                                    \
> > +  pack_hi_##t (t in)                            \
> > +  {                                    \
> > +  return vec_perm (in, in,                        \
> > +           (__vector unsigned char)                \
> > +           {1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31});    \
> > +  }                                    \
> > +   t                                    \
> > +   pack_si_##t (t in)                            \
> > +   {                                    \
> > +     return vec_perm (in, in,                        \
> > +              (__vector unsigned char)                \
> > +              {2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31});    \
> > +   }                                    \
> > +   t                                    \
> > +   pack_di_##t (t in)                            \
> > +   {                                    \
> > +     return vec_perm (in, in,                        \
> > +              (__vector unsigned char)                \
> > +              {4,5,6,7,12,13,14,15,20,21,22,23,28,29,30,31});    \
> > +   }
> > +
> > +T(v16qi)
> > +T(uv16qi)
> > +T(bv16qi)
> > +T(v8hi)
> > +T(uv8hi)
> > +T(bv8hi)
> > +T(v4si)
> > +T(uv4si)
> > +T(bv4si)
> > +T(v2di)
> > +T(uv2di)
> > +T(bv2di)
> > +T(v4sf)
> > +T(v2df)
> > +
> > +/* { dg-final { scan-assembler-not {vperm} } } */
> > --
> > 2.43.7
> > 

Reply via email to