> Fold the vec_perm intrinsic into a VEC_PERM_EXPR such that gcc can > optimize this. > > gcc/ChangeLog: > > * config/s390/s390.cc (s390_gimple_fold_builtin): New > function. > > gcc/testsuite/ChangeLog: > > * gcc.target/s390/zvector/vec_perm-1.c: New test. >
Sorry, forgot: Bootstrapped and regtested on s390x. Okay for trunk? > Signed-off-by: Juergen Christ <[email protected]> > --- > gcc/config/s390/s390.cc | 26 ++++++ > .../gcc.target/s390/zvector/vec_perm-1.c | 87 +++++++++++++++++++ > 2 files changed, 113 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..03d2a694d09b 100644 > --- a/gcc/config/s390/s390.cc > +++ b/gcc/config/s390/s390.cc > @@ -845,6 +845,30 @@ s390_const_operand_ok (tree arg, int argnum, int > op_flags, tree decl) > return true; > } > > +static bool > +s390_gimple_fold_builtin (gimple_stmt_iterator *gsi) > +{ > + gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi)); > + tree fndecl = gimple_call_fndecl (stmt); > + unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); > + gimple *new_stmt; > + tree arg0, arg1, arg2; > + > + if (fcode == S390_BUILTIN_s390_vperm) > + { > + arg0 = gimple_call_arg (stmt, 0); > + arg1 = gimple_call_arg (stmt, 1); > + arg2 = gimple_call_arg (stmt, 2); > + new_stmt = gimple_build_assign (gimple_call_lhs (stmt), > + VEC_PERM_EXPR, > + arg0, arg1, arg2); > + gimple_set_location (new_stmt, gimple_location (stmt)); > + gsi_replace (gsi, new_stmt, false); > + return true; > + } > + return false; > +} > + > /* Expand an expression EXP that calls a built-in function, > with result going to TARGET if that's convenient > (and in mode MODE if that's convenient). > @@ -18439,6 +18463,8 @@ s390_bitint_type_info (int n, struct bitint_info > *info) > > #undef TARGET_INIT_BUILTINS > #define TARGET_INIT_BUILTINS s390_init_builtins > +#undef TARGET_GIMPLE_FOLD_BUILTIN > +#define TARGET_GIMPLE_FOLD_BUILTIN s390_gimple_fold_builtin > #undef TARGET_EXPAND_BUILTIN > #define TARGET_EXPAND_BUILTIN s390_expand_builtin > #undef TARGET_BUILTIN_DECL > 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..9afa400b0c7d > --- /dev/null > +++ b/gcc/testsuite/gcc.target/s390/zvector/vec_perm-1.c > @@ -0,0 +1,87 @@ > +/* Test whether vec_perm with constant permutation mask gets optimized. */ > + > +/* { dg-do compile { target { s390x-*-* } } } */ > +/* { dg-options "-march=z14 -O2" } */ > + > +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 __builtin_s390_vec_perm (in, in, \ > + (uv16qi) \ > + {0,1,2,3,4,5,6,7,16, \ > + 17,18,19,20,21,22,23}); \ > + } \ > + t \ > + mergelow_##t (t in) > \ > + { \ > + return __builtin_s390_vec_perm (in, in, \ > + (uv16qi) \ > + {8,9,10,11,12,13,14,15, \ > + 24,25,26,27,28,29,30,31}); \ > + } \ > + t \ > + pack_hi_##t (t in) \ > + { \ > + return __builtin_s390_vec_perm (in, in, \ > + (uv16qi) \ > + {1,3,5,7,9,11,13,15, \ > + 17,19,21,23,25,27,29,31}); \ > + } \ > + t \ > + pack_si_##t (t in) > \ > + { \ > + return __builtin_s390_vec_perm (in, in, \ > + (uv16qi) \ > + {2,3,6,7,10,11,14,15, \ > + 18,19,22,23,26,27,30,31}); \ > + } \ > + t \ > + pack_di_##t (t in) > \ > + { \ > + return __builtin_s390_vec_perm (in, in, \ > + (uv16qi) \ > + {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} } } */ > +/* { dg-final { scan-assembler-times {vmrh} 14 } } */ > +/* { dg-final { scan-assembler-times {vmrl} 14 } } */ > +/* { dg-final { scan-assembler-times {vpkh} 14 } } */ > +/* { dg-final { scan-assembler-times {vpkf} 14 } } */ > +/* { dg-final { scan-assembler-times {vpkg} 14 } } */ > -- > 2.43.7 >
