Can those intermediate patterns be used for intrinsic? I would prefer
to keep those stuff *IF* possible used for intrinsics.

On Mon, Sep 4, 2023 at 7:14 PM Lehua Ding <lehua.d...@rivai.ai> wrote:
>
> This patch keep vlmax vector pattern in simple before split1 pass which
> will allow more optimization (e.g. combine) before split1 pass.
> This patch changes the vlmax pattern in autovec.md to define_insn_and_split
> as much as possible and clean up some combine patterns that are no longer 
> needed.
> This patch also fixed PR111232 bug which was caused by a combined failed.
>
>         PR target/111232
>
> gcc/ChangeLog:
>
>         * config/riscv/autovec-opt.md 
> (@pred_single_widen_mul<any_extend:su><mode>):
>         Delete.
>         (*pred_widen_mulsu<mode>): Delete.
>         (*pred_single_widen_mul<mode>): Delete.
>         (*dual_widen_<any_widen_binop:optab><any_extend:su><mode>):
>         Add new combine patterns.
>         (*single_widen_sub<any_extend:su><mode>): Ditto.
>         (*single_widen_add<any_extend:su><mode>): Ditto.
>         (*single_widen_mult<any_extend:su><mode>): Ditto.
>         (*dual_widen_mulsu<mode>): Ditto.
>         (*dual_widen_mulus<mode>): Ditto.
>         (*dual_widen_<optab><mode>): Ditto.
>         (*single_widen_add<mode>): Ditto.
>         (*single_widen_sub<mode>): Ditto.
>         (*single_widen_mult<mode>): Ditto.
>         * config/riscv/autovec.md (<optab><mode>3):
>         Change define_expand to define_insn_and_split.
>         (<optab><mode>2): Ditto.
>         (abs<mode>2): Ditto.
>         (smul<mode>3_highpart): Ditto.
>         (umul<mode>3_highpart): Ditto.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/rvv/autovec/widen/widen-4.c: Add more testcases.
>         * gcc.target/riscv/rvv/autovec/widen/widen-complicate-4.c: Ditto.
>         * gcc.target/riscv/rvv/autovec/pr111232.c: New test.
>
> ---
>  gcc/config/riscv/autovec-opt.md               | 294 ++++++++++++------
>  gcc/config/riscv/autovec.md                   |  82 +++--
>  .../gcc.target/riscv/rvv/autovec/pr111232.c   |  18 ++
>  .../riscv/rvv/autovec/widen/widen-4.c         |   7 +-
>  .../rvv/autovec/widen/widen-complicate-4.c    |  11 +-
>  5 files changed, 276 insertions(+), 136 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111232.c
>
> diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
> index d9863c76654..3aaee54f02a 100644
> --- a/gcc/config/riscv/autovec-opt.md
> +++ b/gcc/config/riscv/autovec-opt.md
> @@ -18,67 +18,6 @@
>  ;; along with GCC; see the file COPYING3.  If not see
>  ;; <http://www.gnu.org/licenses/>.
>
> -;; We don't have vwmul.wv instruction like vwadd.wv in RVV.
> -;; This pattern is an intermediate RTL IR as a pseudo vwmul.wv to enhance
> -;; optimization of instructions combine.
> -(define_insn_and_split "@pred_single_widen_mul<any_extend:su><mode>"
> -  [(set (match_operand:VWEXTI 0 "register_operand"                  
> "=&vr,&vr")
> -       (if_then_else:VWEXTI
> -         (unspec:<VM>
> -           [(match_operand:<VM> 1 "vector_mask_operand"           
> "vmWc1,vmWc1")
> -            (match_operand 5 "vector_length_operand"              "   rK,   
> rK")
> -            (match_operand 6 "const_int_operand"                  "    i,    
> i")
> -            (match_operand 7 "const_int_operand"                  "    i,    
> i")
> -            (match_operand 8 "const_int_operand"                  "    i,    
> i")
> -            (reg:SI VL_REGNUM)
> -            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
> -         (mult:VWEXTI
> -           (any_extend:VWEXTI
> -             (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" "   vr,   
> vr"))
> -           (match_operand:VWEXTI 3 "register_operand"             "   vr,   
> vr"))
> -         (match_operand:VWEXTI 2 "vector_merge_operand"           "   vu,    
> 0")))]
> -  "TARGET_VECTOR && can_create_pseudo_p ()"
> -  "#"
> -  "&& 1"
> -  [(const_int 0)]
> -  {
> -    insn_code icode = code_for_pred_vf2 (<CODE>, <MODE>mode);
> -    rtx tmp = gen_reg_rtx (<MODE>mode);
> -    rtx ops[] = {tmp, operands[4]};
> -    riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, ops);
> -
> -    emit_insn (gen_pred (MULT, <MODE>mode, operands[0], operands[1], 
> operands[2],
> -                        operands[3], tmp, operands[5], operands[6],
> -                        operands[7], operands[8]));
> -    DONE;
> -  }
> -  [(set_attr "type" "viwmul")
> -   (set_attr "mode" "<MODE>")])
> -
> -;; This pattern it to enchance the instruction combine optimizations for 
> complicate
> -;; sign and unsigned widening multiplication operations.
> -(define_insn "*pred_widen_mulsu<mode>"
> -  [(set (match_operand:VWEXTI 0 "register_operand"                  
> "=&vr,&vr")
> -       (if_then_else:VWEXTI
> -         (unspec:<VM>
> -           [(match_operand:<VM> 1 "vector_mask_operand"           
> "vmWc1,vmWc1")
> -            (match_operand 5 "vector_length_operand"              "   rK,   
> rK")
> -            (match_operand 6 "const_int_operand"                  "    i,    
> i")
> -            (match_operand 7 "const_int_operand"                  "    i,    
> i")
> -            (match_operand 8 "const_int_operand"                  "    i,    
> i")
> -            (reg:SI VL_REGNUM)
> -            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
> -         (mult:VWEXTI
> -           (zero_extend:VWEXTI
> -             (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" "   vr,   
> vr"))
> -           (sign_extend:VWEXTI
> -             (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "   vr,   
> vr")))
> -         (match_operand:VWEXTI 2 "vector_merge_operand"           "   vu,    
> 0")))]
> -  "TARGET_VECTOR"
> -  "vwmulsu.vv\t%0,%3,%4%p1"
> -  [(set_attr "type" "viwmul")
> -   (set_attr "mode" "<V_DOUBLE_TRUNC>")])
> -
>  ;; 
> -----------------------------------------------------------------------------
>  ;; ---- Integer Compare Instructions Simplification
>  ;; 
> -----------------------------------------------------------------------------
> @@ -406,45 +345,6 @@
>    [(set_attr "type" "vimovvx")
>     (set_attr "mode" "<MODE>")])
>
> -;; We don't have vfwmul.wv instruction like vfwadd.wv in RVV.
> -;; This pattern is an intermediate RTL IR as a pseudo vfwmul.wv to enhance
> -;; optimization of instructions combine.
> -(define_insn_and_split "*pred_single_widen_mul<mode>"
> -  [(set (match_operand:VWEXTF 0 "register_operand"                  "=&vr,  
> &vr")
> -       (if_then_else:VWEXTF
> -         (unspec:<VM>
> -           [(match_operand:<VM> 1 "vector_mask_operand"           
> "vmWc1,vmWc1")
> -            (match_operand 5 "vector_length_operand"              "   rK,   
> rK")
> -            (match_operand 6 "const_int_operand"                  "    i,    
> i")
> -            (match_operand 7 "const_int_operand"                  "    i,    
> i")
> -            (match_operand 8 "const_int_operand"                  "    i,    
> i")
> -            (match_operand 9 "const_int_operand"                  "    i,    
> i")
> -            (reg:SI VL_REGNUM)
> -            (reg:SI VTYPE_REGNUM)
> -            (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
> -         (mult:VWEXTF
> -           (float_extend:VWEXTF
> -             (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" "   vr,   
> vr"))
> -           (match_operand:VWEXTF 3 "register_operand"             "   vr,   
> vr"))
> -         (match_operand:VWEXTF 2 "vector_merge_operand"           "   vu,    
> 0")))]
> -  "TARGET_VECTOR && can_create_pseudo_p ()"
> -  "#"
> -  "&& 1"
> -  [(const_int 0)]
> -  {
> -    insn_code icode = code_for_pred_extend (<MODE>mode);
> -    rtx tmp = gen_reg_rtx (<MODE>mode);
> -    rtx ops[] = {tmp, operands[4]};
> -    riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, ops);
> -
> -    emit_insn (gen_pred (MULT, <MODE>mode, operands[0], operands[1], 
> operands[2],
> -                        operands[3], tmp, operands[5], operands[6],
> -                        operands[7], operands[8], operands[9]));
> -    DONE;
> -  }
> -  [(set_attr "type" "vfwmul")
> -   (set_attr "mode" "<MODE>")])
> -
>  ;; -------------------------------------------------------------------------
>  ;; ---- [FP] VFWMACC
>  ;; -------------------------------------------------------------------------
> @@ -845,7 +745,7 @@
>    DONE;
>  })
>
> -;; Combine FP sign_extend/zero_extend(vf2) and vcond_mask
> +;; Combine FP extend(vf2) and vcond_mask
>  (define_insn_and_split "*cond_extend<v_double_trunc><mode>"
>    [(set (match_operand:VWEXTF_ZVFHMIN 0 "register_operand")
>          (if_then_else:VWEXTF_ZVFHMIN
> @@ -1003,3 +903,195 @@
>    riscv_vector::expand_cond_len_unop (icode, ops);
>    DONE;
>  })
> +
> +;; 
> =============================================================================
> +;; Combine extend + binop to widen_binop
> +;; 
> =============================================================================
> +
> +(define_insn_and_split 
> "*dual_widen_<any_widen_binop:optab><any_extend:su><mode>"
> +  [(set (match_operand:VWEXTI 0 "register_operand")
> +       (any_widen_binop:VWEXTI
> +         (any_extend:VWEXTI
> +           (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand"))
> +         (any_extend:VWEXTI
> +           (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code icode = code_for_pred_dual_widen (<any_widen_binop:CODE>,
> +                                              <any_extend:CODE>,
> +                                              <MODE>mode);
> +  riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands);
> +  DONE;
> +})
> +
> +(define_insn_and_split "*single_widen_sub<any_extend:su><mode>"
> +  [(set (match_operand:VWEXTI 0 "register_operand")
> +       (minus:VWEXTI
> +         (match_operand:VWEXTI 1 "register_operand")
> +         (any_extend:VWEXTI
> +           (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code icode = code_for_pred_single_widen_sub (<any_extend:CODE>,
> +                                                    <MODE>mode);
> +  riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands);
> +  DONE;
> +})
> +
> +(define_insn_and_split "*single_widen_add<any_extend:su><mode>"
> +  [(set (match_operand:VWEXTI 0 "register_operand")
> +       (plus:VWEXTI
> +         (any_extend:VWEXTI
> +           (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
> +         (match_operand:VWEXTI 1 "register_operand")))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code icode = code_for_pred_single_widen_add (<any_extend:CODE>,
> +                                                    <MODE>mode);
> +  riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands);
> +  DONE;
> +})
> +
> +;; This combine pattern does not correspond to an single instruction,
> +;; i.e. there is no vwmul.wv instruction. This is a temporary pattern
> +;; produced by a combine pass and if there is no further combine into
> +;; vwmul.vv pattern, then fall back to extend pattern and vmul.vv pattern.
> +(define_insn_and_split "*single_widen_mult<any_extend:su><mode>"
> +  [(set (match_operand:VWEXTI 0 "register_operand")
> +       (mult:VWEXTI
> +         (any_extend:VWEXTI
> +           (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
> +         (match_operand:VWEXTI 1 "register_operand")))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code extend_icode = code_for_pred_vf2 (<any_extend:CODE>, <MODE>mode);
> +  rtx tmp = gen_reg_rtx (<MODE>mode);
> +  rtx extend_ops[] = {tmp, operands[2]};
> +  riscv_vector::emit_vlmax_insn (extend_icode, riscv_vector::UNARY_OP, 
> extend_ops);
> +
> +  rtx ops[] = {operands[0], operands[1], tmp};
> +  insn_code icode = code_for_pred (MULT, <MODE>mode);
> +  riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops);
> +  DONE;
> +})
> +
> +(define_insn_and_split "*dual_widen_mulsu<mode>"
> +  [(set (match_operand:VWEXTI 0 "register_operand")
> +       (mult:VWEXTI
> +         (sign_extend:VWEXTI
> +           (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand"))
> +         (zero_extend:VWEXTI
> +           (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code icode = code_for_pred_widen_mulsu (<MODE>mode);
> +  riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands);
> +  DONE;
> +})
> +
> +(define_insn_and_split "*dual_widen_mulus<mode>"
> +  [(set (match_operand:VWEXTI 0 "register_operand")
> +       (mult:VWEXTI
> +          (zero_extend:VWEXTI
> +           (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
> +         (sign_extend:VWEXTI
> +           (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand"))))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code icode = code_for_pred_widen_mulsu (<MODE>mode);
> +  riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands);
> +  DONE;
> +})
> +
> +(define_insn_and_split "*dual_widen_<optab><mode>"
> +  [(set (match_operand:VWEXTF 0 "register_operand")
> +       (any_widen_binop:VWEXTF
> +         (float_extend:VWEXTF
> +           (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand"))
> +         (float_extend:VWEXTF
> +           (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code icode = code_for_pred_dual_widen (<CODE>, <MODE>mode);
> +  riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP_FRM_DYN, 
> operands);
> +  DONE;
> +})
> +
> +(define_insn_and_split "*single_widen_add<mode>"
> +  [(set (match_operand:VWEXTF 0 "register_operand")
> +       (plus:VWEXTF
> +         (float_extend:VWEXTF
> +           (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
> +         (match_operand:VWEXTF 1 "register_operand")))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code icode = code_for_pred_single_widen_add (<MODE>mode);
> +  riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP_FRM_DYN, 
> operands);
> +  DONE;
> +})
> +
> +(define_insn_and_split "*single_widen_sub<mode>"
> +  [(set (match_operand:VWEXTF 0 "register_operand")
> +       (minus:VWEXTF
> +          (match_operand:VWEXTF 1 "register_operand")
> +         (float_extend:VWEXTF
> +           (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code icode = code_for_pred_single_widen_sub (<MODE>mode);
> +  riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP_FRM_DYN, 
> operands);
> +  DONE;
> +})
> +
> +;; This combine pattern does not correspond to an single instruction,
> +;; i.e. there is no vfwmul.wv instruction. This is a temporary pattern
> +;; produced by a combine pass and if there is no further combine into
> +;; vfwmul.vv pattern, then fall back to extend pattern and vfmul.vv pattern.
> +(define_insn_and_split "*single_widen_mult<mode>"
> +  [(set (match_operand:VWEXTF 0 "register_operand")
> +       (mult:VWEXTF
> +         (float_extend:VWEXTF
> +           (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
> +         (match_operand:VWEXTF 1 "register_operand")))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
> +{
> +  insn_code extend_icode = code_for_pred_extend (<MODE>mode);
> +  rtx tmp = gen_reg_rtx (<MODE>mode);
> +  rtx extend_ops[] = {tmp, operands[2]};
> +  riscv_vector::emit_vlmax_insn (extend_icode, riscv_vector::UNARY_OP, 
> extend_ops);
> +
> +  rtx ops[] = {operands[0], operands[1], tmp};
> +  riscv_vector::emit_vlmax_insn (code_for_pred (MULT, <MODE>mode),
> +                                riscv_vector::BINARY_OP_FRM_DYN, ops);
> +  DONE;
> +})
> diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
> index c220fda312e..98cd0c07625 100644
> --- a/gcc/config/riscv/autovec.md
> +++ b/gcc/config/riscv/autovec.md
> @@ -419,12 +419,15 @@
>  ;; - vadd.vi/vsub.vi/...
>  ;; -------------------------------------------------------------------------
>
> -(define_expand "<optab><mode>3"
> +(define_insn_and_split "<optab><mode>3"
>    [(set (match_operand:VI 0 "register_operand")
>      (any_int_binop_no_shift:VI
>       (match_operand:VI 1 "<binop_rhs1_predicate>")
>       (match_operand:VI 2 "<binop_rhs2_predicate>")))]
> -  "TARGET_VECTOR"
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
>  {
>    riscv_vector::emit_vlmax_insn (code_for_pred (<CODE>, <MODE>mode),
>                                  riscv_vector::BINARY_OP, operands);
> @@ -937,11 +940,14 @@
>  ;; Includes:
>  ;; - vneg.v/vnot.v
>  ;; 
> -------------------------------------------------------------------------------
> -(define_expand "<optab><mode>2"
> +(define_insn_and_split "<optab><mode>2"
>    [(set (match_operand:VI 0 "register_operand")
>      (any_int_unop:VI
>       (match_operand:VI 1 "register_operand")))]
> -  "TARGET_VECTOR"
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
>  {
>    insn_code icode = code_for_pred (<CODE>, <MODE>mode);
>    riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP, operands);
> @@ -952,10 +958,14 @@
>  ;; - [INT] ABS expansion to vmslt and vneg.
>  ;; 
> -------------------------------------------------------------------------------
>
> -(define_expand "abs<mode>2"
> +(define_insn_and_split "abs<mode>2"
>    [(set (match_operand:VI 0 "register_operand")
> -    (match_operand:VI 1 "register_operand"))]
> -  "TARGET_VECTOR"
> +     (abs:VI
> +       (match_operand:VI 1 "register_operand")))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
>  {
>    rtx zero = gen_const_vec_duplicate (<MODE>mode, GEN_INT (0));
>    machine_mode mask_mode = riscv_vector::get_mask_mode (<MODE>mode);
> @@ -1457,12 +1467,15 @@
>  ;; - vfadd.vv/vfsub.vv/...
>  ;; - vfadd.vf/vfsub.vf/...
>  ;; -------------------------------------------------------------------------
> -(define_expand "<optab><mode>3"
> -  [(match_operand:VF 0 "register_operand")
> -   (any_float_binop:VF
> -    (match_operand:VF 1 "register_operand")
> -    (match_operand:VF 2 "register_operand"))]
> -  "TARGET_VECTOR"
> +(define_insn_and_split "<optab><mode>3"
> +  [(set (match_operand:VF 0 "register_operand")
> +        (any_float_binop:VF
> +          (match_operand:VF 1 "register_operand")
> +          (match_operand:VF 2 "register_operand")))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
>  {
>    riscv_vector::emit_vlmax_insn (code_for_pred (<CODE>, <MODE>mode),
>                                     riscv_vector::BINARY_OP_FRM_DYN, 
> operands);
> @@ -1474,12 +1487,15 @@
>  ;; - vfmin.vv/vfmax.vv
>  ;; - vfmin.vf/vfmax.vf
>  ;; -------------------------------------------------------------------------
> -(define_expand "<optab><mode>3"
> -  [(match_operand:VF 0 "register_operand")
> -   (any_float_binop_nofrm:VF
> -    (match_operand:VF 1 "register_operand")
> -    (match_operand:VF 2 "register_operand"))]
> -  "TARGET_VECTOR"
> +(define_insn_and_split "<optab><mode>3"
> +  [(set (match_operand:VF 0 "register_operand")
> +        (any_float_binop_nofrm:VF
> +          (match_operand:VF 1 "register_operand")
> +          (match_operand:VF 2 "register_operand")))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
>  {
>    riscv_vector::emit_vlmax_insn (code_for_pred (<CODE>, <MODE>mode),
>                                   riscv_vector::BINARY_OP, operands);
> @@ -1537,22 +1553,30 @@
>  ;; - vmulhu.vv
>  ;; -------------------------------------------------------------------------
>
> -(define_expand "smul<mode>3_highpart"
> -  [(match_operand:VFULLI 0 "register_operand")
> -   (match_operand:VFULLI 1 "register_operand")
> -   (match_operand:VFULLI 2 "register_operand")]
> -  "TARGET_VECTOR"
> +(define_insn_and_split "smul<mode>3_highpart"
> +  [(set (match_operand:VFULLI 0 "register_operand")
> +        (smul_highpart:VFULLI
> +          (match_operand:VFULLI 1 "register_operand")
> +          (match_operand:VFULLI 2 "register_operand")))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
>  {
>    insn_code icode = code_for_pred_mulh (UNSPEC_VMULHS, <MODE>mode);
>    riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands);
>    DONE;
>  })
>
> -(define_expand "umul<mode>3_highpart"
> -  [(match_operand:VFULLI 0 "register_operand")
> -   (match_operand:VFULLI 1 "register_operand")
> -   (match_operand:VFULLI 2 "register_operand")]
> -  "TARGET_VECTOR"
> +(define_insn_and_split "umul<mode>3_highpart"
> +  [(set (match_operand:VFULLI 0 "register_operand")
> +        (umul_highpart:VFULLI
> +          (match_operand:VFULLI 1 "register_operand")
> +          (match_operand:VFULLI 2 "register_operand")))]
> +  "TARGET_VECTOR && can_create_pseudo_p ()"
> +  "#"
> +  "&& 1"
> +  [(const_int 0)]
>  {
>    insn_code icode = code_for_pred_mulh (UNSPEC_VMULHU, <MODE>mode);
>    riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, operands);
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111232.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111232.c
> new file mode 100644
> index 00000000000..de815c5fac9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr111232.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64d 
> --param=riscv-autovec-preference=scalable -Ofast -fno-schedule-insns 
> -fno-schedule-insns2" } */
> +
> +#include <stdint.h>
> +
> +int16_t
> +foo (int8_t *restrict x, int8_t *restrict y, int n)
> +{
> +  int16_t result = 0;
> +
> +  for (int i = 0; i < n; i++)
> +    {
> +      result += (x[i] * y[i]);
> +    }
> +  return result;
> +}
> +
> +/* { dg-final { scan-assembler {\tvwmacc\.vv\tv[0-9]+,v[0-9]+,v[0-9]+} } }  
> */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-4.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-4.c
> index c29a74c4f8b..26f27ea6283 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-4.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-4.c
> @@ -16,8 +16,11 @@
>  #define TEST_ALL()                                                           
>   \
>    TEST_TYPE (int16_t, int8_t, uint8_t)                                       
>   \
>    TEST_TYPE (int32_t, int16_t, uint16_t)                                     
>   \
> -  TEST_TYPE (int64_t, int32_t, uint32_t)
> +  TEST_TYPE (int64_t, int32_t, uint32_t)                                     
>   \
> +  TEST_TYPE (int16_t, uint8_t, int8_t)                                       
>   \
> +  TEST_TYPE (int32_t, uint16_t, int16_t)                                     
>   \
> +  TEST_TYPE (int64_t, uint32_t, int32_t)
>
>  TEST_ALL ()
>
> -/* { dg-final { scan-assembler-times {\tvwmulsu\.vv} 3 } } */
> +/* { dg-final { scan-assembler-times {\tvwmulsu\.vv} 6 } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-4.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-4.c
> index 15fdefc550b..aeac4cb79c2 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-4.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-4.c
> @@ -21,11 +21,14 @@
>  #define TEST_ALL()                                                           
>   \
>    TEST_TYPE (int16_t, int8_t, uint8_t)                                       
>   \
>    TEST_TYPE (int32_t, int16_t, uint16_t)                                     
>   \
> -  TEST_TYPE (int64_t, int32_t, uint32_t)
> +  TEST_TYPE (int64_t, int32_t, uint32_t)                                     
>   \
> +  TEST_TYPE (int16_t, uint8_t, int8_t)                                       
>   \
> +  TEST_TYPE (int32_t, uint16_t, int16_t)                                     
>   \
> +  TEST_TYPE (int64_t, uint32_t, int32_t)
>
>  TEST_ALL ()
>
> -/* { dg-final { scan-assembler-times {\tvwmulsu\.vv} 6 } } */
> -/* { dg-final { scan-assembler-times {\tvwmul\.vv} 3 } } */
> -/* { dg-final { scan-assembler-times {\tvwmulu\.vv} 3 } } */
> +/* { dg-final { scan-assembler-times {\tvwmulsu\.vv} 12 } } */
> +/* { dg-final { scan-assembler-times {\tvwmul\.vv} 6 } } */
> +/* { dg-final { scan-assembler-times {\tvwmulu\.vv} 6 } } */
>  /* { dg-final { scan-assembler-not {\tvmul} } } */
> --
> 2.36.3
>

Reply via email to