> 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
> 

Reply via email to