LGTM

On Wed, Sep 13, 2023 at 12:25 AM Lehua Ding <lehua.d...@rivai.ai> wrote:
>
> This patch add combine patterns to combine vnsra.w[vxi] + vcond_mask
> to a mask vnsra.w[vxi].
>
> gcc/ChangeLog:
>
>         * config/riscv/autovec-opt.md 
> (*cond_v<any_shiftrt:optab><any_extend:optab>trunc<mode>):
>         New combine pattern.
>         (*cond_<any_shiftrt:optab>trunc<mode>): Ditto.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-1.c: New test.
>         * gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-2.c: New test.
>         * gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-3.c: New test.
>         * gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-1.c: New 
> test.
>         * gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-2.c: New 
> test.
>         * gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-3.c: New 
> test.
>
> ---
>  gcc/config/riscv/autovec-opt.md               | 46 +++++++++++++++++++
>  .../rvv/autovec/cond/cond_narrow_shift-1.c    | 27 +++++++++++
>  .../rvv/autovec/cond/cond_narrow_shift-2.c    | 30 ++++++++++++
>  .../rvv/autovec/cond/cond_narrow_shift-3.c    | 30 ++++++++++++
>  .../autovec/cond/cond_narrow_shift_run-1.c    | 29 ++++++++++++
>  .../autovec/cond/cond_narrow_shift_run-2.c    | 30 ++++++++++++
>  .../autovec/cond/cond_narrow_shift_run-3.c    | 31 +++++++++++++
>  7 files changed, 223 insertions(+)
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-1.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-2.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-3.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-1.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-2.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-3.c
>
> diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
> index f759525f96b..0d2721f0b29 100644
> --- a/gcc/config/riscv/autovec-opt.md
> +++ b/gcc/config/riscv/autovec-opt.md
> @@ -924,6 +924,52 @@
>     DONE;
>  })
>
> +;; Combine vnsra + vcond_mask
> +(define_insn_and_split 
> "*cond_v<any_shiftrt:optab><any_extend:optab>trunc<mode>"
> +  [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand")
> +     (if_then_else:<V_DOUBLE_TRUNC>
> +       (match_operand:<VM> 1 "register_operand")
> +       (truncate:<V_DOUBLE_TRUNC>
> +         (any_shiftrt:VWEXTI
> +           (match_operand:VWEXTI 2 "register_operand")
> +          (any_extend:VWEXTI
> +             (match_operand:<V_DOUBLE_TRUNC> 3 "vector_shift_operand"))))
> +       (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand")))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code icode = code_for_pred_narrow (<any_shiftrt:CODE>, <MODE>mode);
> +  rtx ops[] = {operands[0], operands[1], operands[2], operands[3], 
> operands[4],
> +               gen_int_mode (GET_MODE_NUNITS (<MODE>mode), Pmode)};
> +  riscv_vector::expand_cond_len_binop (icode, ops);
> +  DONE;
> +}
> + [(set_attr "type" "vnshift")])
> +
> +(define_insn_and_split "*cond_<any_shiftrt:optab>trunc<mode>"
> +  [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand")
> +     (if_then_else:<V_DOUBLE_TRUNC>
> +       (match_operand:<VM> 1 "register_operand")
> +       (truncate:<V_DOUBLE_TRUNC>
> +         (any_shiftrt:VWEXTI
> +           (match_operand:VWEXTI 2 "register_operand")
> +          (match_operand:<VEL> 3 "csr_operand")))
> +       (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand")))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code icode = code_for_pred_narrow_scalar (<any_shiftrt:CODE>, 
> <MODE>mode);
> +  rtx ops[] = {operands[0], operands[1], operands[2], gen_lowpart (Pmode, 
> operands[3]),
> +               operands[4], gen_int_mode (GET_MODE_NUNITS (<MODE>mode), 
> Pmode)};
> +  riscv_vector::expand_cond_len_binop (icode, ops);
> +  DONE;
> +}
> + [(set_attr "type" "vnshift")])
> +
>  ;; 
> =============================================================================
>  ;; Combine extend + binop to widen_binop
>  ;; 
> =============================================================================
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-1.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-1.c
> new file mode 100644
> index 00000000000..d068110a8a8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-1.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d 
> --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
> +
> +#include <stdint-gcc.h>
> +
> +#define DEF_LOOP(TYPE1, TYPE2)                                               
>   \
> +  void __attribute__ ((noipa))                                               
>   \
> +  test_##TYPE1##_##TYPE2 (TYPE2 *__restrict r, TYPE2 *__restrict a,          
>     \
> +                       TYPE1 *__restrict b, int n)                           
>  \
> +  {                                                                          
>   \
> +    for (int i = 0; i < n; ++i)                                              
>   \
> +      r[i] = a[i] > 20 ? (TYPE2) (b[i] >> 3) : r[i];                         
>   \
> +  }
> +
> +#define TEST_ALL(T)                                                          
>   \
> +  T (int16_t, int8_t)                                                        
>   \
> +  T (int32_t, int16_t)                                                       
>   \
> +  T (int64_t, int32_t)                                                       
>   \
> +  T (uint16_t, uint8_t)                                                      
>   \
> +  T (uint32_t, uint16_t)                                                     
>   \
> +  T (uint64_t, uint32_t)
> +
> +TEST_ALL (DEF_LOOP)
> +
> +/* { dg-final { scan-assembler-times {\tvnsrl\.wi\t} 3 } } */
> +/* { dg-final { scan-assembler-times {\tvnsra\.wi\t} 3 } } */
> +/* { dg-final { scan-assembler-not {\tvmerge\.vvm\t} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-2.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-2.c
> new file mode 100644
> index 00000000000..263799175c9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-2.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d 
> --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
> +
> +#include <stdint-gcc.h>
> +
> +#define DEF_LOOP(TYPE1, TYPE2)                                               
>   \
> +  void __attribute__ ((noipa))                                               
>   \
> +  test_##TYPE1##_##TYPE2 (TYPE2 *__restrict r, TYPE2 *__restrict a,          
>   \
> +                         TYPE1 *__restrict b, TYPE2 shift, int n)            
>  \
> +  {                                                                          
>   \
> +    for (int i = 0; i < n; ++i)                                              
>   \
> +      r[i] = a[i] > 20 ? (TYPE2) (b[i] >> shift) : r[i];                     
>   \
> +  }
> +
> +#define TEST_ALL(T)                                                          
>   \
> +  T (int16_t, int8_t)                                                        
>   \
> +  T (int32_t, int16_t)                                                       
>   \
> +  T (int64_t, int32_t)                                                       
>   \
> +  T (uint16_t, uint8_t)                                                      
>   \
> +  T (uint32_t, uint16_t)                                                     
>   \
> +  T (uint64_t, uint32_t)
> +
> +TEST_ALL (DEF_LOOP)
> +
> +/* For int8_t and uint8_t, they are extended to int32_t and then shifted, so
> +   int8_t and uint8_t are use vnsra.wx and vnsra.wx's dest is used not by 
> vmerge
> +   but by vncvt, so vncvt + vmerge will combine to a mask operator. */
> +/* { dg-final { scan-assembler-times {vnsrl\.wx\t} 2 } } */
> +/* { dg-final { scan-assembler-times {vnsra\.wx\t} 4 } } */
> +/* { dg-final { scan-assembler-not {\tvmerge\.vvm\t} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-3.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-3.c
> new file mode 100644
> index 00000000000..17a640b97c7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift-3.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d 
> --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
> +
> +#include <stdint-gcc.h>
> +
> +#define DEF_LOOP(TYPE1, TYPE2)                                               
>   \
> +  void __attribute__ ((noipa))                                               
>   \
> +  test_##TYPE1##_##TYPE2 (TYPE2 *__restrict r, TYPE2 *__restrict a,          
>   \
> +                         TYPE1 *__restrict b, TYPE2 *__restrict shift, int 
> n) \
> +  {                                                                          
>   \
> +    for (int i = 0; i < n; ++i)                                              
>   \
> +      r[i] = a[i] > 20 ? (TYPE2) (b[i] >> shift[i]) : r[i];                  
>   \
> +  }
> +
> +#define TEST_ALL(T)                                                          
>   \
> +  T (int16_t, int8_t)                                                        
>   \
> +  T (int32_t, int16_t)                                                       
>   \
> +  T (int64_t, int32_t)                                                       
>   \
> +  T (uint16_t, uint8_t)                                                      
>   \
> +  T (uint32_t, uint16_t)                                                     
>   \
> +  T (uint64_t, uint32_t)
> +
> +TEST_ALL (DEF_LOOP)
> +
> +/* For int8_t and uint8_t, they are extended to int32_t and then shifted, so
> +   int8_t and uint8_t are use vsra.vv on e32 and cannot convert to vnsra.wv
> +   currently. */
> +/* { dg-final { scan-assembler-times {\tvnsrl\.wv\t} 2 } } */
> +/* { dg-final { scan-assembler-times {\tvnsra\.wv\t} 2 } } */
> +/* { dg-final { scan-assembler-not {\tvmerge\.vvm\t} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-1.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-1.c
> new file mode 100644
> index 00000000000..bf074688ede
> --- /dev/null
> +++ 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-1.c
> @@ -0,0 +1,29 @@
> +/* { dg-do run { target { riscv_vector } } } */
> +/* { dg-additional-options "--param=riscv-autovec-preference=scalable 
> -fno-vect-cost-model" } */
> +
> +#include "cond_narrow_shift-1.c"
> +
> +#define N 99
> +
> +#define TEST_LOOP(TYPE1, TYPE2)                                              
>   \
> +  {                                                                          
>   \
> +    TYPE2 r[N], a[N];                                                        
>   \
> +    TYPE1 b[N];                                                              
>   \
> +    for (int i = 0; i < N; ++i)                                              
>   \
> +      {                                                                      
>   \
> +       a[i] = (i & 1 ? i : 3 * i);                                           
>  \
> +       b[i] = (i >> 4) << (i & 15);                                          
>  \
> +       asm volatile ("" ::: "memory");                                       
>  \
> +      }                                                                      
>   \
> +    test_##TYPE1##_##TYPE2 (r, a, b, N);                                     
>   \
> +    for (int i = 0; i < N; ++i)                                              
>   \
> +      if (r[i] != (a[i] > 20 ? (TYPE2) (b[i] >> 3) : r[i]))                  
>   \
> +       __builtin_abort ();                                                   
>  \
> +  }
> +
> +int
> +main ()
> +{
> +  TEST_ALL (TEST_LOOP)
> +  return 0;
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-2.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-2.c
> new file mode 100644
> index 00000000000..b0454bd9cb9
> --- /dev/null
> +++ 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-2.c
> @@ -0,0 +1,30 @@
> +/* { dg-do run { target { riscv_vector } } } */
> +/* { dg-additional-options "--param=riscv-autovec-preference=scalable 
> -fno-vect-cost-model" } */
> +
> +#include "cond_narrow_shift-2.c"
> +
> +#define N 99
> +
> +#define TEST_LOOP(TYPE1, TYPE2)                                              
>   \
> +  {                                                                          
>   \
> +    TYPE2 r[N], a[N];                                                        
>   \
> +    TYPE2 shift = 5;                                                         
>   \
> +    TYPE1 b[N];                                                              
>   \
> +    for (int i = 0; i < N; ++i)                                              
>   \
> +      {                                                                      
>   \
> +       a[i] = (i & 1 ? i : 3 * i);                                           
>  \
> +       b[i] = (i >> 4) << (i & 15);                                          
>  \
> +       asm volatile ("" ::: "memory");                                       
>  \
> +      }                                                                      
>   \
> +    test_##TYPE1##_##TYPE2 (r, a, b, shift, N);                              
>   \
> +    for (int i = 0; i < N; ++i)                                              
>   \
> +      if (r[i] != (a[i] > 20 ? (TYPE2) (b[i] >> shift) : r[i]))              
>   \
> +       __builtin_abort ();                                                   
>  \
> +  }
> +
> +int
> +main ()
> +{
> +  TEST_ALL (TEST_LOOP)
> +  return 0;
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-3.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-3.c
> new file mode 100644
> index 00000000000..1c025a976ed
> --- /dev/null
> +++ 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_narrow_shift_run-3.c
> @@ -0,0 +1,31 @@
> +/* { dg-do run { target { riscv_vector } } } */
> +/* { dg-additional-options "--param=riscv-autovec-preference=scalable 
> -fno-vect-cost-model" } */
> +
> +#include "cond_narrow_shift-3.c"
> +
> +#define N 99
> +
> +#define TEST_LOOP(TYPE1, TYPE2)                                              
>   \
> +  {                                                                          
>   \
> +    TYPE2 r[N], a[N];                                                        
>   \
> +    TYPE2 shift[N];                                                          
>   \
> +    TYPE1 b[N];                                                              
>   \
> +    for (int i = 0; i < N; ++i)                                              
>   \
> +      {                                                                      
>   \
> +       a[i] = (i & 1 ? i : 3 * i);                                           
>  \
> +       b[i] = (i >> 4) << (i & 15);                                          
>  \
> +       shift[i] = i;                                                         
>  \
> +       asm volatile ("" ::: "memory");                                       
>  \
> +      }                                                                      
>   \
> +    test_##TYPE1##_##TYPE2 (r, a, b, shift, N);                              
>   \
> +    for (int i = 0; i < N; ++i)                                              
>   \
> +      if (r[i] != (a[i] > 20 ? (TYPE2) (b[i] >> shift[i]) : r[i]))           
>   \
> +       __builtin_abort ();                                                   
>  \
> +  }
> +
> +int
> +main ()
> +{
> +  TEST_ALL (TEST_LOOP)
> +  return 0;
> +}
> --
> 2.36.3
>

Reply via email to