Thanks for the refactoring.
This patch is needed in VLS fma support and undefined value enabling
support.
LGTM.
------------------------------------------------------------------------
juzhe.zh...@rivai.ai
*From:* Lehua Ding <mailto:lehua.d...@rivai.ai>
*Date:* 2023-09-18 19:37
*To:* gcc-patches <mailto:gcc-patches@gcc.gnu.org>
*CC:* juzhe.zhong <mailto:juzhe.zh...@rivai.ai>; kito.cheng
<mailto:kito.ch...@gmail.com>; rdapp.gcc
<mailto:rdapp....@gmail.com>; palmer <mailto:pal...@rivosinc.com>;
jeffreyalaw <mailto:jeffreya...@gmail.com>; lehua.ding
<mailto:lehua.d...@rivai.ai>
*Subject:* [PATCH] RISC-V: Refactor and cleanup fma patterns
At present, FMA autovec's patterns do not fully use the
corresponding pattern
in vector.md. The previous reason is that the merge operand of
pattern in
vector.md cannot be VUNDEF. Now allowing it to be VUNDEF, reunify
insn used for
reload pass into vector.md, and the corresponding vlmax pattern in
autovec.md
is used for combine. This patch also refactors the corresponding combine
pattern inside autovec-opt.md and removes the unused ones.
gcc/ChangeLog:
* config/riscv/autovec-opt.md (*<optab>_fma<mode>):
Removed old combine patterns.
(*single_<optab>mult_plus<mode>): Ditto.
(*double_<optab>mult_plus<mode>): Ditto.
(*sign_zero_extend_fma): Ditto.
(*zero_sign_extend_fma): Ditto.
(*double_widen_fma<mode>): Ditto.
(*single_widen_fma<mode>): Ditto.
(*double_widen_fnma<mode>): Ditto.
(*single_widen_fnma<mode>): Ditto.
(*double_widen_fms<mode>): Ditto.
(*single_widen_fms<mode>): Ditto.
(*double_widen_fnms<mode>): Ditto.
(*single_widen_fnms<mode>): Ditto.
(*reduc_plus_scal_<mode>): Adjust name.
(*widen_reduc_plus_scal_<mode>): Adjust name.
(*dual_widen_fma<mode>): New combine pattern.
(*dual_widen_fmasu<mode>): Ditto.
(*dual_widen_fmaus<mode>): Ditto.
(*dual_fma<mode>): Ditto.
(*single_fma<mode>): Ditto.
(*dual_fnma<mode>): Ditto.
(*single_fnma<mode>): Ditto.
(*dual_fms<mode>): Ditto.
(*single_fms<mode>): Ditto.
(*dual_fnms<mode>): Ditto.
(*single_fnms<mode>): Ditto.
* config/riscv/autovec.md (fma<mode>4):
Reafctor fma pattern.
(*fma<VI:mode><P:mode>): Removed.
(fnma<mode>4): Reafctor.
(*fnma<VI:mode><P:mode>): Removed.
(*fma<VF:mode><P:mode>): Removed.
(*fnma<VF:mode><P:mode>): Removed.
(fms<mode>4): Reafctor.
(*fms<VF:mode><P:mode>): Removed.
(fnms<mode>4): Reafctor.
(*fnms<VF:mode><P:mode>): Removed.
* config/riscv/riscv-protos.h (prepare_ternary_operands):
Adjust prototype.
* config/riscv/riscv-v.cc (prepare_ternary_operands): Refactor.
* config/riscv/vector.md (*pred_mul_plus<mode>_undef): New pattern.
(*pred_mul_plus<mode>): Removed.
(*pred_mul_plus<mode>_scalar): Removed.
(*pred_mul_plus<mode>_extended_scalar): Removed.
(*pred_minus_mul<mode>_undef): New pattern.
(*pred_minus_mul<mode>): Removed.
(*pred_minus_mul<mode>_scalar): Removed.
(*pred_minus_mul<mode>_extended_scalar): Removed.
(*pred_mul_<optab><mode>_undef): New pattern.
(*pred_mul_<optab><mode>): Removed.
(*pred_mul_<optab><mode>_scalar): Removed.
(*pred_mul_neg_<optab><mode>_undef): New pattern.
(*pred_mul_neg_<optab><mode>): Removed.
(*pred_mul_neg_<optab><mode>_scalar): Removed.
---
gcc/config/riscv/autovec-opt.md | 736 ++++++++++++++------------------
gcc/config/riscv/autovec.md | 301 ++++---------
gcc/config/riscv/riscv-protos.h | 2 +-
gcc/config/riscv/riscv-v.cc | 14 +-
gcc/config/riscv/vector.md | 439 ++++++-------------
5 files changed, 528 insertions(+), 964 deletions(-)
diff --git a/gcc/config/riscv/autovec-opt.md
b/gcc/config/riscv/autovec-opt.md
index df516849527..c94cd0ae087 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -110,166 +110,6 @@
[(set_attr "type" "vmalu")
(set_attr "mode" "<MODE>")])
-;;
=========================================================================
-;; == Widening Ternary arithmetic
-;;
=========================================================================
-
-;;
-------------------------------------------------------------------------
-;; ---- [INT] VWMACC
-;;
-------------------------------------------------------------------------
-;; Includes:
-;; - vwmacc.vv
-;; - vwmaccu.vv
-;;
-------------------------------------------------------------------------
-
-;; Combine ext + ext + fma ===> widen fma.
-;; Most of circumstantces, LoopVectorizer will generate the
following IR:
-;; vect__8.64_40 = (vector([4,4]) int) vect__7.63_41;
-;; vect__11.68_35 = (vector([4,4]) int) vect__10.67_36;
-;; vect__13.70_33 = .FMA (vect__11.68_35, vect__8.64_40,
vect__4.60_45);
-(define_insn_and_split "*<optab>_fma<mode>"
- [(set (match_operand:VWEXTI 0 "register_operand")
- (plus:VWEXTI
- (mult:VWEXTI
- (any_extend:VWEXTI
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
- (any_extend:VWEXTI
- (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")))
- (match_operand:VWEXTI 1 "register_operand")))]
- "TARGET_VECTOR && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
- {
- riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plus
(<CODE>, <MODE>mode),
- riscv_vector::WIDEN_TERNARY_OP, operands);
- DONE;
- }
- [(set_attr "type" "viwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")])
-
-;; This helps to match ext + fma.
-(define_insn_and_split "*single_<optab>mult_plus<mode>"
- [(set (match_operand:VWEXTI 0 "register_operand")
- (plus:VWEXTI
- (mult:VWEXTI
- (any_extend:VWEXTI
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
- (match_operand:VWEXTI 3 "register_operand"))
- (match_operand:VWEXTI 1 "register_operand")))]
- "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 ext_ops[] = {tmp, operands[2]};
- riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP,
ext_ops);
-
- rtx dst = expand_ternary_op (<MODE>mode, fma_optab, tmp,
operands[3],
- operands[1], operands[0], 0);
- emit_move_insn (operands[0], dst);
- DONE;
- }
- [(set_attr "type" "viwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")])
-
-;; Combine ext + ext + mult + plus ===> widen fma.
-;; We have some special cases generated by LoopVectorizer:
-;; vect__8.18_46 = (vector([8,8]) signed short) vect__7.17_47;
-;; vect__11.22_41 = (vector([8,8]) signed short) vect__10.21_42;
-;; vect__12.23_40 = vect__11.22_41 * vect__8.18_46;
-;; vect__14.25_38 = vect__13.24_39 + vect__5.14_51;
-;; This situation doesn't generate FMA IR.
-(define_insn_and_split "*double_<optab>mult_plus<mode>"
- [(set (match_operand:VWEXTI 0 "register_operand")
- (if_then_else:VWEXTI
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand")
- (match_operand 6 "vector_length_operand")
- (match_operand 7 "const_int_operand")
- (match_operand 8 "const_int_operand")
- (match_operand 9 "const_int_operand")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (plus:VWEXTI
- (if_then_else:VWEXTI
- (unspec:<VM>
- [(match_dup 1)
- (match_dup 6)
- (match_dup 7)
- (match_dup 8)
- (match_dup 9)
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (mult:VWEXTI
- (any_extend:VWEXTI
- (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand"))
- (any_extend:VWEXTI
- (match_operand:<V_DOUBLE_TRUNC> 5 "register_operand")))
- (match_operand:VWEXTI 2 "vector_undef_operand"))
- (match_operand:VWEXTI 3 "register_operand"))
- (match_dup 2)))]
- "TARGET_VECTOR && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
- {
- emit_insn (gen_pred_widen_mul_plus (<CODE>, <MODE>mode,
operands[0],
- operands[1], operands[3], operands[4],
- operands[5], operands[6], operands[7],
- operands[8], operands[9]));
- DONE;
- }
- [(set_attr "type" "viwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")])
-
-;; Combine sign_extend + zero_extend + fma ===> widen fma (su).
-(define_insn_and_split "*sign_zero_extend_fma"
- [(set (match_operand:VWEXTI 0 "register_operand")
- (plus:VWEXTI
- (mult:VWEXTI
- (sign_extend:VWEXTI
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
- (zero_extend:VWEXTI
- (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")))
- (match_operand:VWEXTI 1 "register_operand")))]
- "TARGET_VECTOR && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
- {
- riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plussu
(<MODE>mode),
- riscv_vector::WIDEN_TERNARY_OP, operands);
- DONE;
- }
- [(set_attr "type" "viwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")])
-
-;; This helps to match zero_extend + sign_extend + fma.
-(define_insn_and_split "*zero_sign_extend_fma"
- [(set (match_operand:VWEXTI 0 "register_operand")
- (plus:VWEXTI
- (mult:VWEXTI
- (zero_extend:VWEXTI
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
- (sign_extend:VWEXTI
- (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")))
- (match_operand:VWEXTI 1 "register_operand")))]
- "TARGET_VECTOR && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
- {
- rtx ops[] = {operands[0], operands[1], operands[3], operands[2]};
- riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plussu
(<MODE>mode),
- riscv_vector::WIDEN_TERNARY_OP, ops);
- DONE;
- }
- [(set_attr "type" "viwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")])
-
;;
-------------------------------------------------------------------------
;; ---- [INT] Binary narrow shifts.
;;
-------------------------------------------------------------------------
@@ -345,269 +185,9 @@
[(set_attr "type" "vimovvx")
(set_attr "mode" "<MODE>")])
-;;
-------------------------------------------------------------------------
-;; ---- [FP] VFWMACC
-;;
-------------------------------------------------------------------------
-;; Includes:
-;; - vfwmacc.vv
-;;
-------------------------------------------------------------------------
-
-;; Combine ext + ext + fma ===> widen fma.
-;; Most of circumstantces, LoopVectorizer will generate the
following IR:
-;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41;
-;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36;
-;; vect__13.182_33 = .FMA (vect__11.180_35, vect__8.176_40,
vect__4.172_45);
-(define_insn_and_split "*double_widen_fma<mode>"
- [(set (match_operand:VWEXTF 0 "register_operand")
- (unspec:VWEXTF
- [(fma:VWEXTF
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))
- (match_operand:VWEXTF 1 "register_operand"))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))]
- "TARGET_VECTOR && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
- {
- riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul (PLUS,
<MODE>mode),
- riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, operands);
- DONE;
- }
- [(set_attr "type" "vfwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
-
-;; This helps to match ext + fma.
-(define_insn_and_split "*single_widen_fma<mode>"
- [(set (match_operand:VWEXTF 0 "register_operand")
- (unspec:VWEXTF
- [(fma:VWEXTF
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
- (match_operand:VWEXTF 3 "register_operand")
- (match_operand:VWEXTF 1 "register_operand"))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))]
- "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 ext_ops[] = {tmp, operands[2]};
- riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP,
ext_ops);
-
- rtx dst = expand_ternary_op (<MODE>mode, fma_optab, tmp,
operands[3],
- operands[1], operands[0], 0);
- emit_move_insn (operands[0], dst);
- DONE;
- }
- [(set_attr "type" "vfwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
-
-;;
-------------------------------------------------------------------------
-;; ---- [FP] VFWNMSAC
-;;
-------------------------------------------------------------------------
-;; Includes:
-;; - vfwnmsac.vv
-;;
-------------------------------------------------------------------------
-
-;; Combine ext + ext + fnma ===> widen fnma.
-;; Most of circumstantces, LoopVectorizer will generate the
following IR:
-;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41;
-;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36;
-;; vect__13.182_33 = .FNMA (vect__11.180_35, vect__8.176_40,
vect__4.172_45);
-(define_insn_and_split "*double_widen_fnma<mode>"
- [(set (match_operand:VWEXTF 0 "register_operand")
- (unspec:VWEXTF
- [(fma:VWEXTF
- (neg:VWEXTF
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")))
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))
- (match_operand:VWEXTF 1 "register_operand"))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))]
- "TARGET_VECTOR && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
- {
- riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_neg
(PLUS, <MODE>mode),
- riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, operands);
- DONE;
- }
- [(set_attr "type" "vfwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
-
-;; This helps to match ext + fnma.
-(define_insn_and_split "*single_widen_fnma<mode>"
- [(set (match_operand:VWEXTF 0 "register_operand")
- (unspec:VWEXTF
- [(fma:VWEXTF
- (neg:VWEXTF
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")))
- (match_operand:VWEXTF 3 "register_operand")
- (match_operand:VWEXTF 1 "register_operand"))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))]
- "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 ext_ops[] = {tmp, operands[2]};
- riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP,
ext_ops);
-
- rtx dst = expand_ternary_op (<MODE>mode, fnma_optab, tmp,
operands[3],
- operands[1], operands[0], 0);
- emit_move_insn (operands[0], dst);
- DONE;
- }
- [(set_attr "type" "vfwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
-
-;;
-------------------------------------------------------------------------
-;; ---- [FP] VFWMSAC
-;;
-------------------------------------------------------------------------
-;; Includes:
-;; - vfwmsac.vv
-;;
-------------------------------------------------------------------------
-
-;; Combine ext + ext + fms ===> widen fms.
-;; Most of circumstantces, LoopVectorizer will generate the
following IR:
-;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41;
-;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36;
-;; vect__13.182_33 = .FMS (vect__11.180_35, vect__8.176_40,
vect__4.172_45);
-(define_insn_and_split "*double_widen_fms<mode>"
- [(set (match_operand:VWEXTF 0 "register_operand")
- (unspec:VWEXTF
- [(fma:VWEXTF
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))
- (neg:VWEXTF
- (match_operand:VWEXTF 1 "register_operand")))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))]
- "TARGET_VECTOR && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
- {
- riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul (MINUS,
<MODE>mode),
- riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, operands);
- DONE;
- }
- [(set_attr "type" "vfwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
-
-;; This helps to match ext + fms.
-(define_insn_and_split "*single_widen_fms<mode>"
- [(set (match_operand:VWEXTF 0 "register_operand")
- (unspec:VWEXTF
- [(fma:VWEXTF
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
- (match_operand:VWEXTF 3 "register_operand")
- (neg:VWEXTF
- (match_operand:VWEXTF 1 "register_operand")))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))]
- "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 ext_ops[] = {tmp, operands[2]};
- riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP,
ext_ops);
-
- rtx dst = expand_ternary_op (<MODE>mode, fms_optab, tmp,
operands[3],
- operands[1], operands[0], 0);
- emit_move_insn (operands[0], dst);
- DONE;
- }
- [(set_attr "type" "vfwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
-
-;;
-------------------------------------------------------------------------
-;; ---- [FP] VFWNMACC
-;;
-------------------------------------------------------------------------
-;; Includes:
-;; - vfwnmacc.vv
-;;
-------------------------------------------------------------------------
-
-;; Combine ext + ext + fnms ===> widen fnms.
-;; Most of circumstantces, LoopVectorizer will generate the
following IR:
-;; vect__8.176_40 = (vector([2,2]) double) vect__7.175_41;
-;; vect__11.180_35 = (vector([2,2]) double) vect__10.179_36;
-;; vect__13.182_33 = .FNMS (vect__11.180_35, vect__8.176_40,
vect__4.172_45);
-(define_insn_and_split "*double_widen_fnms<mode>"
- [(set (match_operand:VWEXTF 0 "register_operand")
- (unspec:VWEXTF
- [(fma:VWEXTF
- (neg:VWEXTF
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")))
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))
- (neg:VWEXTF
- (match_operand:VWEXTF 1 "register_operand")))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))]
- "TARGET_VECTOR && can_create_pseudo_p ()"
- "#"
- "&& 1"
- [(const_int 0)]
- {
- riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_neg
(MINUS, <MODE>mode),
- riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, operands);
- DONE;
- }
- [(set_attr "type" "vfwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
-
-;; This helps to match ext + fnms.
-(define_insn_and_split "*single_widen_fnms<mode>"
- [(set (match_operand:VWEXTF 0 "register_operand")
- (unspec:VWEXTF
- [(fma:VWEXTF
- (neg:VWEXTF
- (float_extend:VWEXTF
- (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")))
- (match_operand:VWEXTF 3 "register_operand")
- (neg:VWEXTF
- (match_operand:VWEXTF 1 "register_operand")))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))]
- "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 ext_ops[] = {tmp, operands[2]};
- riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP,
ext_ops);
-
- rtx dst = expand_ternary_op (<MODE>mode, fnms_optab, tmp,
operands[3],
- operands[1], operands[0], 0);
- emit_move_insn (operands[0], dst);
- DONE;
- }
- [(set_attr "type" "vfwmuladd")
- (set_attr "mode" "<V_DOUBLE_TRUNC>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
+;;
=============================================================================
+;; All combine patterns for combine pass.
+;;
=============================================================================
;;
=============================================================================
;; Combine op + vmerge to cond_op
@@ -1197,7 +777,7 @@
[(set_attr "type" "vfwmul")])
;; Combine extend + vredsum to vwredsum[u]
-(define_insn_and_split "*reduc_plus_scal_<mode>"
+(define_insn_and_split "*widen_reduc_plus_scal_<mode>"
[(set (match_operand:<V_DOUBLE_EXTEND_VEL> 0 "register_operand")
(unspec:<V_DOUBLE_EXTEND_VEL> [
(any_extend:<V_DOUBLE_EXTEND>
@@ -1215,7 +795,7 @@
[(set_attr "type" "vector")])
;; Combine extend + vfredusum to vfwredusum
-(define_insn_and_split "*reduc_plus_scal_<mode>"
+(define_insn_and_split "*widen_reduc_plus_scal_<mode>"
[(set (match_operand:<V_DOUBLE_EXTEND_VEL> 0 "register_operand")
(unspec:<V_DOUBLE_EXTEND_VEL> [
(float_extend:<V_DOUBLE_EXTEND>
@@ -1278,6 +858,312 @@
}
[(set_attr "type" "vector")])
+;;
=============================================================================
+;; Combine extend + ternop to widen_ternop
+;;
=============================================================================
+
+;; Combine ext + fma(vmacc,vmadd) to widen_fma (vwmacc)
+(define_insn_and_split "*dual_widen_fma<mode>"
+ [(set (match_operand:VWEXTI 0 "register_operand")
+ (plus:VWEXTI
+ (mult:VWEXTI
+ (any_extend:VWEXTI
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (any_extend:VWEXTI
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")))
+ (match_operand:VWEXTI 1 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plus
(<CODE>, <MODE>mode),
+ riscv_vector::WIDEN_TERNARY_OP, ops);
+ DONE;
+ }
+ [(set_attr "type" "viwmuladd")])
+
+;; Combine sign_extend + zero_extend + fma to widen_fma (vwmaccsu)
+(define_insn_and_split "*dual_widen_fmasu<mode>"
+ [(set (match_operand:VWEXTI 0 "register_operand")
+ (plus:VWEXTI
+ (mult:VWEXTI
+ (sign_extend:VWEXTI
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (zero_extend:VWEXTI
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")))
+ (match_operand:VWEXTI 1 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plussu
(<MODE>mode),
+ riscv_vector::WIDEN_TERNARY_OP, ops);
+ DONE;
+ }
+ [(set_attr "type" "viwmuladd")])
+
+;; Combine zero_extend + sign_extend + fma to widen_fma (vwmaccsu)
+(define_insn_and_split "*dual_widen_fmaus<mode>"
+ [(set (match_operand:VWEXTI 0 "register_operand")
+ (plus:VWEXTI
+ (mult:VWEXTI
+ (zero_extend:VWEXTI
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand"))
+ (sign_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)]
+ {
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_plussu
(<MODE>mode),
+ riscv_vector::WIDEN_TERNARY_OP, ops);
+ DONE;
+ }
+ [(set_attr "type" "viwmuladd")])
+
+;; This combine pattern does not correspond to an single instruction.
+;; This is a temporary pattern produced by a combine pass and if there
+;; is no further combine into widen pattern, then fall back to extend
+;; pattern and non-widen fma pattern.
+(define_insn_and_split "*single_widen_fma<mode>"
+ [(set (match_operand:VWEXTI 0 "register_operand")
+ (plus:VWEXTI
+ (mult:VWEXTI
+ (any_extend:VWEXTI
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (match_operand:VWEXTI 3 "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 (<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], tmp, operands[3], operands[1]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_mul_plus (<MODE>mode),
+ riscv_vector::TERNARY_OP, ops);
+ DONE;
+ }
+ [(set_attr "type" "viwmuladd")])
+
+;; Combine extend + fma to widen_fma (vfwmacc)
+(define_insn_and_split "*dual_fma<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (plus:VWEXTF
+ (mult:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")))
+ (match_operand:VWEXTF 1 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul (PLUS,
<MODE>mode),
+ riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, ops);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")])
+
+;; This combine pattern does not correspond to an single instruction.
+;; This is a temporary pattern produced by a combine pass and if there
+;; is no further combine into widen pattern, then fall back to extend
+;; pattern and non-widen fma pattern.
+(define_insn_and_split "*single_fma<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (plus:VWEXTF
+ (mult:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (match_operand:VWEXTF 3 "register_operand"))
+ (match_operand:VWEXTF 1 "register_operand")))]
+ "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 ext_ops[] = {tmp, operands[2]};
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP,
ext_ops);
+
+ rtx ops[] = {operands[0], tmp, operands[3], operands[1]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_mul (PLUS,
<MODE>mode),
+ riscv_vector::TERNARY_OP_FRM_DYN, ops);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")])
+
+;; Combine extend + fnma to widen_fnma (vfwnmsac)
+(define_insn_and_split "*dual_fnma<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (minus:VWEXTF
+ (match_operand:VWEXTF 1 "register_operand")
+ (mult:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")))))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_neg
(PLUS, <MODE>mode),
+ riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, ops);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")])
+
+;; This combine pattern does not correspond to an single instruction.
+;; This is a temporary pattern produced by a combine pass and if there
+;; is no further combine into widen pattern, then fall back to extend
+;; pattern and non-widen fnma pattern.
+(define_insn_and_split "*single_fnma<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (minus:VWEXTF
+ (match_operand:VWEXTF 1 "register_operand")
+ (mult:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (match_operand:VWEXTF 3 "register_operand"))))]
+ "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 ext_ops[] = {tmp, operands[2]};
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP,
ext_ops);
+
+ rtx ops[] = {operands[0], tmp, operands[3], operands[1]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_mul_neg (PLUS,
<MODE>mode),
+ riscv_vector::TERNARY_OP_FRM_DYN, ops);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")])
+
+;; Combine extend + fms to widen_fms (vfwmsac)
+(define_insn_and_split "*dual_fms<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (minus:VWEXTF
+ (mult:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")))
+ (match_operand:VWEXTF 1 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul (MINUS,
<MODE>mode),
+ riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, ops);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")])
+
+;; This combine pattern does not correspond to an single instruction.
+;; This is a temporary pattern produced by a combine pass and if there
+;; is no further combine into widen pattern, then fall back to extend
+;; pattern and non-widen fms pattern.
+(define_insn_and_split "*single_fms<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (minus:VWEXTF
+ (mult:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))
+ (match_operand:VWEXTF 3 "register_operand"))
+ (match_operand:VWEXTF 1 "register_operand")))]
+ "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 ext_ops[] = {tmp, operands[2]};
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP,
ext_ops);
+
+ rtx ops[] = {operands[0], tmp, operands[3], operands[1]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_mul (MINUS,
<MODE>mode),
+ riscv_vector::TERNARY_OP_FRM_DYN, ops);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")])
+
+;; Combine extend + fnms to widen_fnms (vfwnmacc)
+(define_insn_and_split "*dual_fnms<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (minus:VWEXTF
+ (mult:VWEXTF
+ (neg:VWEXTF
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand")))
+ (float_extend:VWEXTF
+ (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand")))
+ (match_operand:VWEXTF 1 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_widen_mul_neg
(MINUS, <MODE>mode),
+ riscv_vector::WIDEN_TERNARY_OP_FRM_DYN, ops);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")])
+
+;; This combine pattern does not correspond to an single instruction.
+;; This is a temporary pattern produced by a combine pass and if there
+;; is no further combine into widen pattern, then fall back to extend
+;; pattern and non-widen fnms pattern.
+(define_insn_and_split "*single_fnms<mode>"
+ [(set (match_operand:VWEXTF 0 "register_operand")
+ (minus:VWEXTF
+ (mult:VWEXTF
+ (neg:VWEXTF
+ (match_operand:VWEXTF 3 "register_operand"))
+ (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_extend (<MODE>mode);
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ rtx ext_ops[] = {tmp, operands[2]};
+ riscv_vector::emit_vlmax_insn (icode, riscv_vector::UNARY_OP,
ext_ops);
+
+ rtx ops[] = {operands[0], tmp, operands[3], operands[1]};
+ riscv_vector::emit_vlmax_insn (code_for_pred_mul_neg (MINUS,
<MODE>mode),
+ riscv_vector::TERNARY_OP_FRM_DYN, ops);
+ DONE;
+ }
+ [(set_attr "type" "vfwmuladd")])
+
;;
=============================================================================
;; Misc combine patterns
;;
=============================================================================
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 8537b9d41f6..96aaf869f88 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -1078,57 +1078,25 @@
;; - vmadd
;;
-------------------------------------------------------------------------
-;; We can't expand FMA for the following reasons:
-;; 1. Before RA, we don't know which multiply-add instruction is
the ideal one.
-;; The vmacc is the ideal instruction when operands[3] overlaps
operands[0].
-;; The vmadd is the ideal instruction when operands[1|2]
overlaps operands[0].
-;; 2. According to vector.md, the multiply-add patterns has 'merge'
operand which
-;; is the operands[5]. Since operands[5] should overlap
operands[0], this operand
-;; should be allocated the same regno as operands[1|2|3].
-;; 3. The 'merge' operand is always a real merge operand and we
don't allow undefined
-;; operand.
-;; 4. The operation of FMA pattern needs VLMAX vsetlvi which needs
a VL operand.
-;;
-;; In this situation, we design the codegen of FMA as follows:
-;; 1. clobber a scratch in the expand pattern of FMA.
-;; 2. Let's RA decide which input operand (operands[1|2|3]) overlap
operands[0].
-;; 3. Generate instructions (vmacc or vmadd) according to the
register allocation
-;; result after reload_completed.
-(define_expand "fma<mode>4"
- [(parallel
- [(set (match_operand:VI 0 "register_operand")
- (plus:VI
- (mult:VI
- (match_operand:VI 1 "register_operand")
- (match_operand:VI 2 "register_operand"))
- (match_operand:VI 3 "register_operand")))
- (clobber (match_dup 4))])]
- "TARGET_VECTOR"
- {
- operands[4] = gen_reg_rtx (Pmode);
- })
-
-(define_insn_and_split "*fma<VI:mode><P:mode>"
- [(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr")
+(define_insn_and_split "fma<mode>4"
+ [(set (match_operand:VI 0 "register_operand")
(plus:VI
(mult:VI
- (match_operand:VI 1 "register_operand" " %0, vr, vr")
- (match_operand:VI 2 "register_operand" " vr, vr, vr"))
- (match_operand:VI 3 "register_operand" " vr, 0, vr")))
- (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
- "TARGET_VECTOR"
+ (match_operand:VI 1 "register_operand")
+ (match_operand:VI 2 "register_operand"))
+ (match_operand:VI 3 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
"#"
- "&& reload_completed"
+ "&& 1"
[(const_int 0)]
{
- riscv_vector::emit_vlmax_vsetvl (<VI:MODE>mode, operands[4]);
- rtx ops[] = {operands[0], operands[1], operands[2],
operands[3], operands[0]};
- riscv_vector::emit_vlmax_insn_lra (code_for_pred_mul_plus
(<VI:MODE>mode),
- riscv_vector::TERNARY_OP, ops, operands[4]);
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
+ RVV_VUNDEF(<MODE>mode)};
+ riscv_vector::emit_vlmax_insn (code_for_pred_mul_plus (<MODE>mode),
+ riscv_vector::TERNARY_OP, ops);
DONE;
}
- [(set_attr "type" "vimuladd")
- (set_attr "mode" "<VI:MODE>")])
+ [(set_attr "type" "vector")])
;;
-------------------------------------------------------------------------
;; ---- [INT] VNMSAC and VNMSUB
@@ -1138,41 +1106,25 @@
;; - vnmsub
;;
-------------------------------------------------------------------------
-(define_expand "fnma<mode>4"
- [(parallel
- [(set (match_operand:VI 0 "register_operand")
- (minus:VI
- (match_operand:VI 3 "register_operand")
- (mult:VI
- (match_operand:VI 1 "register_operand")
- (match_operand:VI 2 "register_operand"))))
- (clobber (match_dup 4))])]
- "TARGET_VECTOR"
- {
- operands[4] = gen_reg_rtx (Pmode);
- })
-
-(define_insn_and_split "*fnma<VI:mode><P:mode>"
- [(set (match_operand:VI 0 "register_operand" "=vr, vr, ?&vr")
- (minus:VI
- (match_operand:VI 3 "register_operand" " vr, 0, vr")
- (mult:VI
- (match_operand:VI 1 "register_operand" " %0, vr, vr")
- (match_operand:VI 2 "register_operand" " vr, vr, vr"))))
- (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
- "TARGET_VECTOR"
+(define_insn_and_split "fnma<mode>4"
+ [(set (match_operand:VI 0 "register_operand")
+ (minus:VI
+ (match_operand:VI 3 "register_operand")
+ (mult:VI
+ (match_operand:VI 1 "register_operand")
+ (match_operand:VI 2 "register_operand"))))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
"#"
- "&& reload_completed"
+ "&& 1"
[(const_int 0)]
{
- riscv_vector::emit_vlmax_vsetvl (<VI:MODE>mode, operands[4]);
- rtx ops[] = {operands[0], operands[1], operands[2],
operands[3], operands[0]};
- riscv_vector::emit_vlmax_insn_lra (code_for_pred_minus_mul
(<VI:MODE>mode),
- riscv_vector::TERNARY_OP,
ops, operands[4]);
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
+ RVV_VUNDEF(<MODE>mode)};
+ riscv_vector::emit_vlmax_insn (code_for_pred_minus_mul
(<MODE>mode),
+ riscv_vector::TERNARY_OP, ops);
DONE;
}
- [(set_attr "type" "vimuladd")
- (set_attr "mode" "<VI:MODE>")])
+ [(set_attr "type" "vector")])
;;
-------------------------------------------------------------------------
;; ---- [FP] VFMACC and VFMADD
@@ -1182,45 +1134,25 @@
;; - vfmadd
;;
-------------------------------------------------------------------------
-(define_expand "fma<mode>4"
- [(parallel
- [(set (match_operand:VF 0 "register_operand")
- (unspec:VF
- [(fma:VF
- (match_operand:VF 1 "register_operand")
- (match_operand:VF 2 "register_operand")
- (match_operand:VF 3 "register_operand"))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))
- (clobber (match_dup 4))])]
- "TARGET_VECTOR"
- {
- operands[4] = gen_reg_rtx (Pmode);
- }
- [(set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
-
-(define_insn_and_split "*fma<VF:mode><P:mode>"
- [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr")
- (unspec:VF
- [(fma:VF
- (match_operand:VF 1 "register_operand" " %0, vr, vr")
- (match_operand:VF 2 "register_operand" " vr, vr, vr")
- (match_operand:VF 3 "register_operand" " vr, 0, vr"))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))
- (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
- "TARGET_VECTOR"
+(define_insn_and_split "fma<mode>4"
+ [(set (match_operand:VF 0 "register_operand")
+ (plus:VF
+ (mult:VF
+ (match_operand:VF 1 "register_operand")
+ (match_operand:VF 2 "register_operand"))
+ (match_operand:VF 3 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
"#"
- "&& reload_completed"
+ "&& 1"
[(const_int 0)]
{
- riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]);
- rtx ops[] = {operands[0], operands[1], operands[2],
operands[3], operands[0]};
- riscv_vector::emit_vlmax_insn_lra (code_for_pred_mul (PLUS,
<VF:MODE>mode),
- riscv_vector::TERNARY_OP_FRM_DYN, ops, operands[4]);
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
+ RVV_VUNDEF(<MODE>mode)};
+ riscv_vector::emit_vlmax_insn (code_for_pred_mul (PLUS,
<MODE>mode),
+ riscv_vector::TERNARY_OP_FRM_DYN, ops);
DONE;
}
- [(set_attr "type" "vfmuladd")
- (set_attr "mode" "<VF:MODE>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
+ [(set_attr "type" "vector")])
;;
-------------------------------------------------------------------------
;; ---- [FP] VFNMSAC and VFNMSUB
@@ -1230,47 +1162,25 @@
;; - vfnmsub
;;
-------------------------------------------------------------------------
-(define_expand "fnma<mode>4"
- [(parallel
- [(set (match_operand:VF 0 "register_operand")
- (unspec:VF
- [(fma:VF
- (neg:VF
- (match_operand:VF 1 "register_operand"))
- (match_operand:VF 2 "register_operand")
- (match_operand:VF 3 "register_operand"))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))
- (clobber (match_dup 4))])]
- "TARGET_VECTOR"
- {
- operands[4] = gen_reg_rtx (Pmode);
- }
- [(set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
-
-(define_insn_and_split "*fnma<VF:mode><P:mode>"
- [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr")
- (unspec:VF
- [(fma:VF
- (neg:VF
- (match_operand:VF 1 "register_operand" " %0, vr, vr"))
- (match_operand:VF 2 "register_operand" " vr, vr, vr")
- (match_operand:VF 3 "register_operand" " vr, 0, vr"))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))
- (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
- "TARGET_VECTOR"
+(define_insn_and_split "fnma<mode>4"
+ [(set (match_operand:VF 0 "register_operand")
+ (minus:VF
+ (match_operand:VF 3 "register_operand")
+ (mult:VF
+ (match_operand:VF 1 "register_operand")
+ (match_operand:VF 2 "register_operand"))))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
"#"
- "&& reload_completed"
+ "&& 1"
[(const_int 0)]
{
- riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]);
- rtx ops[] = {operands[0], operands[1], operands[2],
operands[3], operands[0]};
- riscv_vector::emit_vlmax_insn_lra (code_for_pred_mul_neg (PLUS,
<VF:MODE>mode),
- riscv_vector::TERNARY_OP_FRM_DYN, ops, operands[4]);
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
+ RVV_VUNDEF(<MODE>mode)};
+ riscv_vector::emit_vlmax_insn (code_for_pred_mul_neg (PLUS,
<MODE>mode),
+ riscv_vector::TERNARY_OP_FRM_DYN, ops);
DONE;
}
- [(set_attr "type" "vfmuladd")
- (set_attr "mode" "<VF:MODE>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
+ [(set_attr "type" "vector")])
;;
-------------------------------------------------------------------------
;; ---- [FP] VFMSAC and VFMSUB
@@ -1280,47 +1190,25 @@
;; - vfmsub
;;
-------------------------------------------------------------------------
-(define_expand "fms<mode>4"
- [(parallel
- [(set (match_operand:VF 0 "register_operand")
- (unspec:VF
- [(fma:VF
- (match_operand:VF 1 "register_operand")
- (match_operand:VF 2 "register_operand")
- (neg:VF
- (match_operand:VF 3 "register_operand")))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))
- (clobber (match_dup 4))])]
- "TARGET_VECTOR"
- {
- operands[4] = gen_reg_rtx (Pmode);
- }
- [(set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
-
-(define_insn_and_split "*fms<VF:mode><P:mode>"
- [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr")
- (unspec:VF
- [(fma:VF
- (match_operand:VF 1 "register_operand" " %0, vr, vr")
- (match_operand:VF 2 "register_operand" " vr, vr, vr")
- (neg:VF
- (match_operand:VF 3 "register_operand" " vr, 0, vr")))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))
- (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
- "TARGET_VECTOR"
+(define_insn_and_split "fms<mode>4"
+ [(set (match_operand:VF 0 "register_operand")
+ (minus:VF
+ (mult:VF
+ (match_operand:VF 1 "register_operand")
+ (match_operand:VF 2 "register_operand"))
+ (match_operand:VF 3 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
"#"
- "&& reload_completed"
+ "&& 1"
[(const_int 0)]
{
- riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]);
- rtx ops[] = {operands[0], operands[1], operands[2],
operands[3], operands[0]};
- riscv_vector::emit_vlmax_insn_lra (code_for_pred_mul (MINUS,
<VF:MODE>mode),
- riscv_vector::TERNARY_OP_FRM_DYN, ops, operands[4]);
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
+ RVV_VUNDEF(<MODE>mode)};
+ riscv_vector::emit_vlmax_insn (code_for_pred_mul (MINUS,
<MODE>mode),
+ riscv_vector::TERNARY_OP_FRM_DYN, ops);
DONE;
}
- [(set_attr "type" "vfmuladd")
- (set_attr "mode" "<VF:MODE>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
+ [(set_attr "type" "vector")])
;;
-------------------------------------------------------------------------
;; ---- [FP] VFNMACC and VFNMADD
@@ -1330,49 +1218,26 @@
;; - vfnmadd
;;
-------------------------------------------------------------------------
-(define_expand "fnms<mode>4"
- [(parallel
- [(set (match_operand:VF 0 "register_operand")
- (unspec:VF
- [(fma:VF
- (neg:VF
- (match_operand:VF 1 "register_operand"))
- (match_operand:VF 2 "register_operand")
- (neg:VF
- (match_operand:VF 3 "register_operand")))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))
- (clobber (match_dup 4))])]
- "TARGET_VECTOR"
- {
- operands[4] = gen_reg_rtx (Pmode);
- }
- [(set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
-
-(define_insn_and_split "*fnms<VF:mode><P:mode>"
- [(set (match_operand:VF 0 "register_operand" "=vr, vr, ?&vr")
- (unspec:VF
- [(fma:VF
- (neg:VF
- (match_operand:VF 1 "register_operand" " %0, vr, vr"))
- (match_operand:VF 2 "register_operand" " vr, vr, vr")
- (neg:VF
- (match_operand:VF 3 "register_operand" " vr, 0, vr")))
- (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))
- (clobber (match_operand:P 4 "register_operand" "=r,r,r"))]
- "TARGET_VECTOR"
+(define_insn_and_split "fnms<mode>4"
+ [(set (match_operand:VF 0 "register_operand")
+ (minus:VF
+ (neg:VF
+ (mult:VF
+ (match_operand:VF 1 "register_operand")
+ (match_operand:VF 2 "register_operand")))
+ (match_operand:VF 3 "register_operand")))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
"#"
- "&& reload_completed"
+ "&& 1"
[(const_int 0)]
{
- riscv_vector::emit_vlmax_vsetvl (<VF:MODE>mode, operands[4]);
- rtx ops[] = {operands[0], operands[1], operands[2],
operands[3], operands[0]};
- riscv_vector::emit_vlmax_insn_lra (code_for_pred_mul_neg
(MINUS, <VF:MODE>mode),
- riscv_vector::TERNARY_OP_FRM_DYN, ops, operands[4]);
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
+ RVV_VUNDEF(<MODE>mode)};
+ riscv_vector::emit_vlmax_insn (code_for_pred_mul_neg (MINUS,
<MODE>mode),
+ riscv_vector::TERNARY_OP_FRM_DYN, ops);
DONE;
}
- [(set_attr "type" "vfmuladd")
- (set_attr "mode" "<VF:MODE>")
- (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))])
+ [(set_attr "type" "vector")])
;;
=========================================================================
;; == SELECT_VL
diff --git a/gcc/config/riscv/riscv-protos.h
b/gcc/config/riscv/riscv-protos.h
index 44fa36c32ab..46fc8f39974 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -462,7 +462,7 @@ void expand_select_vl (rtx *);
void expand_load_store (rtx *, bool);
void expand_gather_scatter (rtx *, bool);
void expand_cond_len_ternop (unsigned, rtx *);
-void prepare_ternary_operands (rtx *, bool = false);
+void prepare_ternary_operands (rtx *);
void expand_lanes_load_store (rtx *, bool);
void expand_fold_extract_last (rtx *);
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 668594b65ed..f51986aebde 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3253,15 +3253,15 @@ expand_reduction (unsigned unspec, rtx *ops,
rtx init, reduction_type type)
/* Prepare ops for ternary operations.
It can be called before or after RA. */
void
-prepare_ternary_operands (rtx *ops, bool split_p)
+prepare_ternary_operands (rtx *ops)
{
machine_mode mode = GET_MODE (ops[0]);
- if (split_p
- || (!rtx_equal_p (ops[2], ops[5])
- && !rtx_equal_p (ops[3], ops[5])
- && !rtx_equal_p (ops[4], ops[5])
- && riscv_get_v_regno_alignment (mode) == 8))
+ if (!rtx_equal_p (ops[5], RVV_VUNDEF (mode))
+ && (VECTOR_MODE_P (GET_MODE (ops[2]))
+ && !rtx_equal_p (ops[2], ops[5]))
+ && !rtx_equal_p (ops[3], ops[5])
+ && !rtx_equal_p (ops[4], ops[5]))
{
/* RA will fail to find vector REG and report ICE, so we
pre-merge
the ops for LMUL = 8. */
@@ -3286,6 +3286,8 @@ prepare_ternary_operands (rtx *ops, bool split_p)
/* TODO: ??? Maybe we could support splitting FMA (a, 4, b)
into PLUS (ASHIFT (a, 2), b) according to uarchs. */
}
+ gcc_assert (rtx_equal_p (ops[5], RVV_VUNDEF (mode))
+ || rtx_equal_p (ops[5], ops[2]) || rtx_equal_p (ops[5],
ops[4]));
}
/* Expand VEC_MASK_LEN_{LOAD_LANES,STORE_LANES}. */
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index fb0c8abd995..e174322a459 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -5002,12 +5002,40 @@
(match_operand:VI 2 "register_operand")
(match_operand:VI 3 "register_operand"))
(match_operand:VI 4 "register_operand"))
- (match_operand:VI 5 "register_operand")))]
+ (match_operand:VI 5 "vector_merge_operand")))]
"TARGET_VECTOR"
{
riscv_vector::prepare_ternary_operands (operands);
})
+(define_insn "*pred_mul_plus<mode>_undef"
+ [(set (match_operand:VI 0 "register_operand" "=vd,
vd,?&vd, vr, vr,?&vr")
+ (if_then_else:VI
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,
vm,Wc1,Wc1, Wc1")
+ (match_operand 6 "vector_length_operand" " rK, rK, rK,
rK, rK, rK")
+ (match_operand 7 "const_int_operand" " i, i, i,
i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i,
i, i, i")
+ (match_operand 9 "const_int_operand" " i, i, i,
i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (plus:VI
+ (mult:VI
+ (match_operand:VI 3 "register_operand" " 0, vr, vr,
0, vr, vr")
+ (match_operand:VI 4 "register_operand" " vr, vr, vr,
vr, vr, vr"))
+ (match_operand:VI 5 "register_operand" " vr, 0, vr,
vr, 0, vr"))
+ (match_operand:VI 2 "vector_undef_operand")))]
+ "TARGET_VECTOR"
+ "@
+ vmadd.vv\t%0,%4,%5%p1
+ vmacc.vv\t%0,%3,%4%p1
+ vmv.v.v\t%0,%4\;vmacc.vv\t%0,%3,%4%p1
+ vmadd.vv\t%0,%4,%5%p1
+ vmacc.vv\t%0,%3,%4%p1
+ vmv.v.v\t%0,%5\;vmacc.vv\t%0,%3,%4%p1"
+ [(set_attr "type" "vimuladd")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "*pred_madd<mode>"
[(set (match_operand:VI 0 "register_operand"
"=vd,?&vd, vr,?&vr")
(if_then_else:VI
@@ -5070,35 +5098,6 @@
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
(set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
-(define_insn_and_rewrite "*pred_mul_plus<mode>"
- [(set (match_operand:VI 0 "register_operand" "=&vr")
- (if_then_else:VI
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
- (match_operand 6 "vector_length_operand" " rK")
- (match_operand 7 "const_int_operand" " i")
- (match_operand 8 "const_int_operand" " i")
- (match_operand 9 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (plus:VI
- (mult:VI
- (match_operand:VI 2 "register_operand" " vr")
- (match_operand:VI 3 "register_operand" " vr"))
- (match_operand:VI 4 "register_operand" " vr"))
- (match_operand:VI 5 "register_operand" " vr")))]
- "TARGET_VECTOR
- && !rtx_equal_p (operands[2], operands[5])
- && !rtx_equal_p (operands[3], operands[5])
- && !rtx_equal_p (operands[4], operands[5])"
- "#"
- "&& reload_completed"
- {
- riscv_vector::prepare_ternary_operands (operands, true);
- }
- [(set_attr "type" "vimuladd")
- (set_attr "mode" "<MODE>")])
-
(define_expand "@pred_mul_plus<mode>_scalar"
[(set (match_operand:VI_QHS 0 "register_operand")
(if_then_else:VI_QHS
@@ -5184,35 +5183,6 @@
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
(set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
-(define_insn_and_rewrite "*pred_mul_plus<mode>_scalar"
- [(set (match_operand:VI 0 "register_operand" "=&vr")
- (if_then_else:VI
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
- (match_operand 6 "vector_length_operand" " rK")
- (match_operand 7 "const_int_operand" " i")
- (match_operand 8 "const_int_operand" " i")
- (match_operand 9 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (plus:VI
- (mult:VI
- (vec_duplicate:VI
- (match_operand:<VEL> 2 "register_operand" " r"))
- (match_operand:VI 3 "register_operand" " vr"))
- (match_operand:VI 4 "vector_arith_operand" " vr"))
- (match_operand:VI 5 "register_operand" " vr")))]
- "TARGET_VECTOR
- && !rtx_equal_p (operands[3], operands[5])
- && !rtx_equal_p (operands[4], operands[5])"
- "#"
- "&& reload_completed"
- {
- riscv_vector::prepare_ternary_operands (operands, true);
- }
- [(set_attr "type" "vimuladd")
- (set_attr "mode" "<MODE>")])
-
(define_expand "@pred_mul_plus<mode>_scalar"
[(set (match_operand:VI_D 0 "register_operand")
(if_then_else:VI_D
@@ -5313,36 +5283,6 @@
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
(set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
-(define_insn_and_rewrite "*pred_mul_plus<mode>_extended_scalar"
- [(set (match_operand:VI_D 0 "register_operand" "=&vr")
- (if_then_else:VI_D
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
- (match_operand 6 "vector_length_operand" " rK")
- (match_operand 7 "const_int_operand" " i")
- (match_operand 8 "const_int_operand" " i")
- (match_operand 9 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (plus:VI_D
- (mult:VI_D
- (vec_duplicate:VI_D
- (sign_extend:<VEL>
- (match_operand:<VSUBEL> 2 "register_operand" " r")))
- (match_operand:VI_D 3 "register_operand" " vr"))
- (match_operand:VI_D 4 "register_operand" " vr"))
- (match_operand:VI_D 5 "register_operand" " vr")))]
- "TARGET_VECTOR
- && !rtx_equal_p (operands[3], operands[5])
- && !rtx_equal_p (operands[4], operands[5])"
- "#"
- "&& reload_completed"
- {
- riscv_vector::prepare_ternary_operands (operands, true);
- }
- [(set_attr "type" "vimuladd")
- (set_attr "mode" "<MODE>")])
-
(define_expand "@pred_minus_mul<mode>"
[(set (match_operand:VI 0 "register_operand")
(if_then_else:VI
@@ -5359,12 +5299,40 @@
(mult:VI
(match_operand:VI 2 "register_operand")
(match_operand:VI 3 "register_operand")))
- (match_operand:VI 5 "register_operand")))]
+ (match_operand:VI 5 "vector_merge_operand")))]
"TARGET_VECTOR"
{
riscv_vector::prepare_ternary_operands (operands);
})
+(define_insn "*pred_minus_mul<mode>_undef"
+ [(set (match_operand:VI 0 "register_operand" "=vd,
vd,?&vd, vr, vr,?&vr")
+ (if_then_else:VI
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,
vm,Wc1,Wc1, Wc1")
+ (match_operand 6 "vector_length_operand" " rK, rK, rK,
rK, rK, rK")
+ (match_operand 7 "const_int_operand" " i, i, i,
i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i,
i, i, i")
+ (match_operand 9 "const_int_operand" " i, i, i,
i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (minus:VI
+ (match_operand:VI 5 "register_operand" " vr, 0,
vr, vr, 0, vr")
+ (mult:VI
+ (match_operand:VI 3 "register_operand" " 0, vr, vr,
0, vr, vr")
+ (match_operand:VI 4 "register_operand" " vr, vr, vr,
vr, vr, vr")))
+ (match_operand:VI 2 "vector_undef_operand")))]
+ "TARGET_VECTOR"
+ "@
+ vnmsub.vv\t%0,%4,%5%p1
+ vnmsac.vv\t%0,%3,%4%p1
+ vmv.v.v\t%0,%3\;vnmsub.vv\t%0,%4,%5%p1
+ vnmsub.vv\t%0,%4,%5%p1
+ vnmsac.vv\t%0,%3,%4%p1
+ vmv.v.v\t%0,%3\;vnmsub.vv\t%0,%4,%5%p1"
+ [(set_attr "type" "vimuladd")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "*pred_nmsub<mode>"
[(set (match_operand:VI 0 "register_operand"
"=vd,?&vd, vr,?&vr")
(if_then_else:VI
@@ -5427,35 +5395,6 @@
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
(set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
-(define_insn_and_rewrite "*pred_minus_mul<mode>"
- [(set (match_operand:VI 0 "register_operand" "=&vr")
- (if_then_else:VI
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
- (match_operand 6 "vector_length_operand" " rK")
- (match_operand 7 "const_int_operand" " i")
- (match_operand 8 "const_int_operand" " i")
- (match_operand 9 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (minus:VI
- (match_operand:VI 4 "vector_arith_operand" " vr")
- (mult:VI
- (match_operand:VI 2 "register_operand" " vr")
- (match_operand:VI 3 "register_operand" " vr")))
- (match_operand:VI 5 "register_operand" " vr")))]
- "TARGET_VECTOR
- && !rtx_equal_p (operands[2], operands[5])
- && !rtx_equal_p (operands[3], operands[5])
- && !rtx_equal_p (operands[4], operands[5])"
- "#"
- "&& reload_completed"
- {
- riscv_vector::prepare_ternary_operands (operands, true);
- }
- [(set_attr "type" "vimuladd")
- (set_attr "mode" "<MODE>")])
-
(define_expand "@pred_minus_mul<mode>_scalar"
[(set (match_operand:VI_QHS 0 "register_operand")
(if_then_else:VI_QHS
@@ -5541,35 +5480,6 @@
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
(set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
-(define_insn_and_rewrite "*pred_minus_mul<mode>_scalar"
- [(set (match_operand:VI 0 "register_operand" "=&vr")
- (if_then_else:VI
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
- (match_operand 6 "vector_length_operand" " rK")
- (match_operand 7 "const_int_operand" " i")
- (match_operand 8 "const_int_operand" " i")
- (match_operand 9 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (minus:VI
- (match_operand:VI 4 "vector_arith_operand" " vr")
- (mult:VI
- (vec_duplicate:VI
- (match_operand:<VEL> 2 "register_operand" " r"))
- (match_operand:VI 3 "register_operand" " vr")))
- (match_operand:VI 5 "register_operand" " vr")))]
- "TARGET_VECTOR
- && !rtx_equal_p (operands[3], operands[5])
- && !rtx_equal_p (operands[4], operands[5])"
- "#"
- "&& reload_completed"
- {
- riscv_vector::prepare_ternary_operands (operands, true);
- }
- [(set_attr "type" "vimuladd")
- (set_attr "mode" "<MODE>")])
-
(define_expand "@pred_minus_mul<mode>_scalar"
[(set (match_operand:VI_D 0 "register_operand")
(if_then_else:VI_D
@@ -5670,36 +5580,6 @@
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[7])"))
(set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
-(define_insn_and_rewrite "*pred_minus_mul<mode>_extended_scalar"
- [(set (match_operand:VI_D 0 "register_operand" "=&vr")
- (if_then_else:VI_D
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
- (match_operand 6 "vector_length_operand" " rK")
- (match_operand 7 "const_int_operand" " i")
- (match_operand 8 "const_int_operand" " i")
- (match_operand 9 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (minus:VI_D
- (match_operand:VI_D 4 "vector_arith_operand" " vr")
- (mult:VI_D
- (vec_duplicate:VI_D
- (sign_extend:<VEL>
- (match_operand:<VSUBEL> 2 "register_operand" " r")))
- (match_operand:VI_D 3 "register_operand" " vr")))
- (match_operand:VI_D 5 "register_operand" " vr")))]
- "TARGET_VECTOR
- && !rtx_equal_p (operands[3], operands[5])
- && !rtx_equal_p (operands[4], operands[5])"
- "#"
- "&& reload_completed"
- {
- riscv_vector::prepare_ternary_operands (operands, true);
- }
- [(set_attr "type" "vimuladd")
- (set_attr "mode" "<MODE>")])
-
;;
-------------------------------------------------------------------------------
;; ---- Predicated widen integer ternary operations
;;
-------------------------------------------------------------------------------
@@ -6276,12 +6156,44 @@
(match_operand:VF 2 "register_operand")
(match_operand:VF 3 "register_operand"))
(match_operand:VF 4 "register_operand"))
- (match_operand:VF 5 "register_operand")))]
+ (match_operand:VF 5 "vector_merge_operand")))]
"TARGET_VECTOR"
{
riscv_vector::prepare_ternary_operands (operands);
})
+(define_insn "*pred_mul_<optab><mode>_undef"
+ [(set (match_operand:VF 0 "register_operand"
"=vd,vd,?&vd, vr, vr,?&vr")
+ (if_then_else:VF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,vm,
vm,Wc1,Wc1, Wc1")
+ (match_operand 6 "vector_length_operand" " rK,rK, rK, rK,
rK, rK")
+ (match_operand 7 "const_int_operand" " i, i, i,
i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i,
i, i, i")
+ (match_operand 9 "const_int_operand" " i, i, i,
i, i, i")
+ (match_operand 10 "const_int_operand" " i, i, i,
i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)
+ (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
+ (plus_minus:VF
+ (mult:VF
+ (match_operand:VF 3 "register_operand" " 0,vr, vr, 0,
vr, vr")
+ (match_operand:VF 4 "register_operand" " vr,vr, vr, vr,
vr, vr"))
+ (match_operand:VF 5 "register_operand" " vr, 0, vr,
vr, 0, vr"))
+ (match_operand:VF 2 "vector_undef_operand")))]
+ "TARGET_VECTOR"
+ "@
+ vf<madd_msub>.vv\t%0,%4,%5%p1
+ vf<macc_msac>.vv\t%0,%3,%4%p1
+ vmv.v.v\t%0,%3\;vf<madd_msub>.vv\t%0,%4,%5%p1
+ vf<madd_msub>.vv\t%0,%4,%5%p1
+ vf<macc_msac>.vv\t%0,%3,%4%p1
+ vmv.v.v\t%0,%3\;vf<madd_msub>.vv\t%0,%4,%5%p1"
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<MODE>")
+ (set (attr "frm_mode")
+ (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))])
+
(define_insn "*pred_<madd_msub><mode>"
[(set (match_operand:VF 0 "register_operand" "=vd,
?&vd, vr, ?&vr")
(if_then_else:VF
@@ -6352,39 +6264,6 @@
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
-(define_insn_and_rewrite "*pred_mul_<optab><mode>"
- [(set (match_operand:VF 0 "register_operand" "=&vr")
- (if_then_else:VF
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
- (match_operand 6 "vector_length_operand" " rK")
- (match_operand 7 "const_int_operand" " i")
- (match_operand 8 "const_int_operand" " i")
- (match_operand 9 "const_int_operand" " i")
- (match_operand 10 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)
- (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
- (plus_minus:VF
- (mult:VF
- (match_operand:VF 2 "register_operand" " vr")
- (match_operand:VF 3 "register_operand" " vr"))
- (match_operand:VF 4 "register_operand" " vr"))
- (match_operand:VF 5 "register_operand" " vr")))]
- "TARGET_VECTOR
- && !rtx_equal_p (operands[2], operands[5])
- && !rtx_equal_p (operands[3], operands[5])
- && !rtx_equal_p (operands[4], operands[5])"
- "#"
- "&& reload_completed"
- {
- riscv_vector::prepare_ternary_operands (operands, true);
- }
- [(set_attr "type" "vfmuladd")
- (set_attr "mode" "<MODE>")
- (set (attr "frm_mode")
- (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))])
-
(define_expand "@pred_mul_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand")
(if_then_else:VF
@@ -6480,39 +6359,6 @@
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
-(define_insn_and_rewrite "*pred_mul_<optab><mode>_scalar"
- [(set (match_operand:VF 0 "register_operand" "=&vr")
- (if_then_else:VF
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
- (match_operand 6 "vector_length_operand" " rK")
- (match_operand 7 "const_int_operand" " i")
- (match_operand 8 "const_int_operand" " i")
- (match_operand 9 "const_int_operand" " i")
- (match_operand 10 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)
- (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
- (plus_minus:VF
- (mult:VF
- (vec_duplicate:VF
- (match_operand:<VEL> 2 "register_operand" " f"))
- (match_operand:VF 3 "register_operand" " vr"))
- (match_operand:VF 4 "vector_arith_operand" " vr"))
- (match_operand:VF 5 "register_operand" " vr")))]
- "TARGET_VECTOR
- && !rtx_equal_p (operands[3], operands[5])
- && !rtx_equal_p (operands[4], operands[5])"
- "#"
- "&& reload_completed"
- {
- riscv_vector::prepare_ternary_operands (operands, true);
- }
- [(set_attr "type" "vfmuladd")
- (set_attr "mode" "<MODE>")
- (set (attr "frm_mode")
- (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))])
-
(define_expand "@pred_mul_neg_<optab><mode>"
[(set (match_operand:VF 0 "register_operand")
(if_then_else:VF
@@ -6532,12 +6378,45 @@
(match_operand:VF 2 "register_operand")
(match_operand:VF 3 "register_operand")))
(match_operand:VF 4 "register_operand"))
- (match_operand:VF 5 "register_operand")))]
+ (match_operand:VF 5 "vector_merge_operand")))]
"TARGET_VECTOR"
{
riscv_vector::prepare_ternary_operands (operands);
})
+(define_insn "*pred_mul_neg_<optab><mode>_undef"
+ [(set (match_operand:VF 0 "register_operand"
"=vd,vd,?&vd, vr, vr,?&vr")
+ (if_then_else:VF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,vm,
vm,Wc1,Wc1, Wc1")
+ (match_operand 6 "vector_length_operand" " rK,rK, rK, rK,
rK, rK")
+ (match_operand 7 "const_int_operand" " i, i, i,
i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i,
i, i, i")
+ (match_operand 9 "const_int_operand" " i, i, i,
i, i, i")
+ (match_operand 10 "const_int_operand" " i, i, i,
i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)
+ (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
+ (plus_minus:VF
+ (neg:VF
+ (mult:VF
+ (match_operand:VF 3 "register_operand" " 0,vr, vr, 0,
vr, vr")
+ (match_operand:VF 4 "register_operand" " vr,vr, vr, vr,
vr, vr")))
+ (match_operand:VF 5 "register_operand" " vr, 0, vr,
vr, 0, vr"))
+ (match_operand:VF 2 "vector_undef_operand")))]
+ "TARGET_VECTOR"
+ "@
+ vf<nmsub_nmadd>.vv\t%0,%4,%5%p1
+ vf<nmsac_nmacc>.vv\t%0,%3,%4%p1
+ vmv.v.v\t%0,%3\;vf<nmsub_nmadd>.vv\t%0,%4,%5%p1
+ vf<nmsub_nmadd>.vv\t%0,%4,%5%p1
+ vf<nmsac_nmacc>.vv\t%0,%3,%4%p1
+ vmv.v.v\t%0,%3\;vf<nmsub_nmadd>.vv\t%0,%4,%5%p1"
+ [(set_attr "type" "vfmuladd")
+ (set_attr "mode" "<MODE>")
+ (set (attr "frm_mode")
+ (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))])
+
(define_insn "*pred_<nmsub_nmadd><mode>"
[(set (match_operand:VF 0 "register_operand" "=vd,
?&vd, vr, ?&vr")
(if_then_else:VF
@@ -6610,40 +6489,6 @@
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
-(define_insn_and_rewrite "*pred_mul_neg_<optab><mode>"
- [(set (match_operand:VF 0 "register_operand" "=&vr")
- (if_then_else:VF
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
- (match_operand 6 "vector_length_operand" " rK")
- (match_operand 7 "const_int_operand" " i")
- (match_operand 8 "const_int_operand" " i")
- (match_operand 9 "const_int_operand" " i")
- (match_operand 10 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)
- (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
- (plus_minus:VF
- (neg:VF
- (mult:VF
- (match_operand:VF 2 "register_operand" " vr")
- (match_operand:VF 3 "register_operand" " vr")))
- (match_operand:VF 4 "vector_arith_operand" " vr"))
- (match_operand:VF 5 "register_operand" " vr")))]
- "TARGET_VECTOR
- && !rtx_equal_p (operands[2], operands[5])
- && !rtx_equal_p (operands[3], operands[5])
- && !rtx_equal_p (operands[4], operands[5])"
- "#"
- "&& reload_completed"
- {
- riscv_vector::prepare_ternary_operands (operands, true);
- }
- [(set_attr "type" "vfmuladd")
- (set_attr "mode" "<MODE>")
- (set (attr "frm_mode")
- (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))])
-
(define_expand "@pred_mul_neg_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand")
(if_then_else:VF
@@ -6742,40 +6587,6 @@
(set (attr "frm_mode")
(symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
-(define_insn_and_rewrite "*pred_mul_neg_<optab><mode>_scalar"
- [(set (match_operand:VF 0 "register_operand" "=&vr")
- (if_then_else:VF
- (unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
- (match_operand 6 "vector_length_operand" " rK")
- (match_operand 7 "const_int_operand" " i")
- (match_operand 8 "const_int_operand" " i")
- (match_operand 9 "const_int_operand" " i")
- (match_operand 10 "const_int_operand" " i")
- (reg:SI VL_REGNUM)
- (reg:SI VTYPE_REGNUM)
- (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
- (plus_minus:VF
- (neg:VF
- (mult:VF
- (vec_duplicate:VF
- (match_operand:<VEL> 2 "register_operand" " f"))
- (match_operand:VF 3 "register_operand" " vr")))
- (match_operand:VF 4 "vector_arith_operand" " vr"))
- (match_operand:VF 5 "register_operand" " vr")))]
- "TARGET_VECTOR
- && !rtx_equal_p (operands[3], operands[5])
- && !rtx_equal_p (operands[4], operands[5])"
- "#"
- "&& reload_completed"
- {
- riscv_vector::prepare_ternary_operands (operands, true);
- }
- [(set_attr "type" "vfmuladd")
- (set_attr "mode" "<MODE>")
- (set (attr "frm_mode")
- (symbol_ref "riscv_vector::get_frm_mode (operands[10])"))])
-
;;
-------------------------------------------------------------------------------
;; ---- Predicated floating-point unary operations
;;
-------------------------------------------------------------------------------
--
2.36.3