From: Pan Li <[email protected]>
This patch would like to combine the vec_duplicate + vmadd.vv to the
vmadd.vx. From example as below code. The related pattern will depend
on the cost of vec_duplicate from GR2VR. Then the late-combine will
take action if the cost of GR2VR is zero, and reject the combination
if the GR2VR cost is greater than zero.
Assume we have example code like below, GR2VR cost is 0.
Before this patch:
11 │ beq a3,zero,.L8
12 │ vsetvli a5,zero,e32,m1,ta,ma
13 │ vmv.v.x v2,a2
...
16 │ .L3:
17 │ vsetvli a5,a3,e32,m1,ta,ma
...
22 │ vmadd.vv v1,v2,v3
...
25 │ bne a3,zero,.L3
After this patch:
11 │ beq a3,zero,.L8
...
14 │ .L3:
15 │ vsetvli a5,a3,e32,m1,ta,ma
...
20 │ vmadd.vx v1,a2,v3
...
23 │ bne a3,zero,.L3
gcc/ChangeLog:
* config/riscv/autovec-opt.md (*vmacc_vx_<mode>): Rename to
handle both the macc and madd.
(*mul_then_plus_vx_<mode>): Add madd pattern.
* config/riscv/vector.md (@pred_mul_plus_vx_<mode>): Rename to
handle both the macc and madd.
(*pred_macc_<mode>_scalar_undef): Remove.
(*pred_nmsac_<mode>_scalar_undef): Remove.
(*pred_mul_then_plus_vx<mode>_undef): Add new pattern to handle
both the vmacc and vmadd.
(@pred_mul_then_plus_vx<mode>): Ditto.
Signed-off-by: Pan Li <[email protected]>
---
gcc/config/riscv/autovec-opt.md | 8 +-
gcc/config/riscv/vector.md | 172 ++++++++++++++++----------------
2 files changed, 92 insertions(+), 88 deletions(-)
diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index 9695fdcb5c9..3caabf0ff4d 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -1824,7 +1824,7 @@ (define_insn_and_split "*merge_vx_<mode>"
}
[(set_attr "type" "vimerge")])
-(define_insn_and_split "*vmacc_vx_<mode>"
+(define_insn_and_split "*mul_then_plus_vx_<mode>"
[(set (match_operand:V_VLSI 0 "register_operand")
(plus:V_VLSI
(mult:V_VLSI
@@ -1837,9 +1837,9 @@ (define_insn_and_split "*vmacc_vx_<mode>"
"&& 1"
[(const_int 0)]
{
- insn_code icode = code_for_pred_mul_plus_vx (<MODE>mode);
- rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
- RVV_VUNDEF(<MODE>mode)};
+ insn_code icode = code_for_pred_mul_then_plus_vx (<MODE>mode);
+ rtx v_undef = RVV_VUNDEF(<MODE>mode);
+ rtx ops[] = {operands[0], operands[1], operands[2], operands[3], v_undef};
riscv_vector::emit_vlmax_insn (icode, riscv_vector::TERNARY_OP, ops);
DONE;
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 2b35d66b611..d0de08d07c0 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -5493,52 +5493,6 @@ (define_expand "@pred_mul_plus<mode>_scalar"
"TARGET_VECTOR"
{})
-(define_expand "@pred_mul_plus_vx_<mode>"
- [(set (match_operand:V_VLSI_QHS 0 "register_operand")
- (if_then_else:V_VLSI_QHS
- (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:V_VLSI_QHS
- (mult:V_VLSI_QHS
- (vec_duplicate:V_VLSI_QHS
- (match_operand:<VEL> 2 "register_operand"))
- (match_operand:V_VLSI_QHS 3 "register_operand"))
- (match_operand:V_VLSI_QHS 4 "register_operand"))
- (match_operand:V_VLSI_QHS 5 "vector_merge_operand")))]
- "TARGET_VECTOR"
-{
- riscv_vector::prepare_ternary_operands (operands);
-})
-
-(define_expand "@pred_mul_plus_vx_<mode>"
- [(set (match_operand:V_VLSI_D 0 "register_operand")
- (if_then_else:V_VLSI_D
- (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:V_VLSI_D
- (mult:V_VLSI_D
- (vec_duplicate:V_VLSI_D
- (match_operand:<VEL> 2 "register_operand"))
- (match_operand:V_VLSI_D 3 "register_operand"))
- (match_operand:V_VLSI_D 4 "register_operand"))
- (match_operand:V_VLSI_D 5 "vector_merge_operand")))]
- "TARGET_VECTOR && TARGET_64BIT"
-{
- riscv_vector::prepare_ternary_operands (operands);
-})
-
(define_expand "@pred_vnmsac_vx_<mode>"
[(set (match_operand:V_VLSI_QHS 0 "register_operand")
(if_then_else:V_VLSI_QHS
@@ -8934,7 +8888,7 @@ (define_insn
"@pred_indexed_<order>store<V32T:mode><RATIO2I:mode>"
[(set_attr "type" "vssegt<order>x")
(set_attr "mode" "<V32T:MODE>")])
-(define_insn "*pred_macc_<mode>_scalar_undef"
+(define_insn "*pred_nmsac_<mode>_scalar_undef"
[(set (match_operand:V_VLSI_QHS 0 "register_operand" "=vd, vr")
(if_then_else:V_VLSI_QHS
(unspec:<VM>
@@ -8945,21 +8899,21 @@ (define_insn "*pred_macc_<mode>_scalar_undef"
(match_operand 9 "const_int_operand" " i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (plus:V_VLSI_QHS
+ (minus:V_VLSI_QHS
+ (match_operand:V_VLSI_QHS 5 "register_operand" " 0, 0")
(mult:V_VLSI_QHS
(vec_duplicate:V_VLSI_QHS
(match_operand:<VEL> 3 "reg_or_0_operand" " rJ, rJ"))
- (match_operand:V_VLSI_QHS 4 "register_operand" " vr, vr"))
- (match_operand:V_VLSI_QHS 5 "register_operand" " 0, 0"))
+ (match_operand:V_VLSI_QHS 4 "register_operand" " vr, vr")))
(match_operand:V_VLSI_QHS 2 "vector_undef_operand")))]
"TARGET_VECTOR"
"@
- vmacc.vx\t%0,%z3,%4%p1
- vmacc.vx\t%0,%z3,%4%p1"
+ vnmsac.vx\t%0,%z3,%4%p1
+ vnmsac.vx\t%0,%z3,%4%p1"
[(set_attr "type" "vimuladd")
(set_attr "mode" "<MODE>")])
-(define_insn "*pred_macc_<mode>_scalar_undef"
+(define_insn "*pred_nmsac_<mode>_scalar_undef"
[(set (match_operand:V_VLSI_D 0 "register_operand" "=vd, vr")
(if_then_else:V_VLSI_D
(unspec:<VM>
@@ -8970,70 +8924,120 @@ (define_insn "*pred_macc_<mode>_scalar_undef"
(match_operand 9 "const_int_operand" " i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (plus:V_VLSI_D
+ (minus:V_VLSI_D
+ (match_operand:V_VLSI_D 5 "register_operand" " 0, 0")
(mult:V_VLSI_D
(vec_duplicate:V_VLSI_D
(match_operand:<VEL> 3 "reg_or_0_operand" " rJ, rJ"))
- (match_operand:V_VLSI_D 4 "register_operand" " vr, vr"))
- (match_operand:V_VLSI_D 5 "register_operand" " 0, 0"))
+ (match_operand:V_VLSI_D 4 "register_operand" " vr, vr")))
(match_operand:V_VLSI_D 2 "vector_undef_operand")))]
"TARGET_VECTOR && TARGET_64BIT"
"@
- vmacc.vx\t%0,%z3,%4%p1
- vmacc.vx\t%0,%z3,%4%p1"
+ vnmsac.vx\t%0,%z3,%4%p1
+ vnmsac.vx\t%0,%z3,%4%p1"
[(set_attr "type" "vimuladd")
(set_attr "mode" "<MODE>")])
-(define_insn "*pred_nmsac_<mode>_scalar_undef"
- [(set (match_operand:V_VLSI_QHS 0 "register_operand" "=vd, vr")
+(define_insn "*pred_mul_then_plus_vx<mode>_undef"
+ [(set (match_operand:V_VLSI_QHS 0 "register_operand" "=vd, vd,
vr, vr")
(if_then_else:V_VLSI_QHS
(unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" " vm, Wc1")
- (match_operand 6 "vector_length_operand" "rvl, rvl")
- (match_operand 7 "const_int_operand" " i, i")
- (match_operand 8 "const_int_operand" " i, i")
- (match_operand 9 "const_int_operand" " i, i")
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,
Wc1, Wc1")
+ (match_operand 6 "vector_length_operand" "rvl, rvl,
rvl, rvl")
+ (match_operand 7 "const_int_operand" " i, i,
i, i")
+ (match_operand 8 "const_int_operand" " i, i,
i, i")
+ (match_operand 9 "const_int_operand" " i, i,
i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (minus:V_VLSI_QHS
- (match_operand:V_VLSI_QHS 5 "register_operand" " 0, 0")
+ (plus:V_VLSI_QHS
(mult:V_VLSI_QHS
(vec_duplicate:V_VLSI_QHS
- (match_operand:<VEL> 3 "reg_or_0_operand" " rJ, rJ"))
- (match_operand:V_VLSI_QHS 4 "register_operand" " vr, vr")))
+ (match_operand:<VEL> 3 "reg_or_0_operand" " rJ, rJ,
rJ, rJ"))
+ (match_operand:V_VLSI_QHS 4 "register_operand" " 0, vr,
0, vr"))
+ (match_operand:V_VLSI_QHS 5 "register_operand" " vr, 0,
vr, 0"))
(match_operand:V_VLSI_QHS 2 "vector_undef_operand")))]
"TARGET_VECTOR"
"@
- vnmsac.vx\t%0,%z3,%4%p1
- vnmsac.vx\t%0,%z3,%4%p1"
+ vmadd.vx\t%0,%z3,%5%p1
+ vmacc.vx\t%0,%z3,%4%p1
+ vmadd.vx\t%0,%z3,%5%p1
+ vmacc.vx\t%0,%z3,%4%p1"
[(set_attr "type" "vimuladd")
(set_attr "mode" "<MODE>")])
-(define_insn "*pred_nmsac_<mode>_scalar_undef"
- [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd, vr")
+(define_insn "*pred_mul_then_plus_vx<mode>_undef"
+ [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd, vd, vr,
vr")
(if_then_else:V_VLSI_D
(unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" " vm, Wc1")
- (match_operand 6 "vector_length_operand" "rvl, rvl")
- (match_operand 7 "const_int_operand" " i, i")
- (match_operand 8 "const_int_operand" " i, i")
- (match_operand 9 "const_int_operand" " i, i")
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm, Wc1,
Wc1")
+ (match_operand 6 "vector_length_operand" "rvl, rvl, rvl,
rvl")
+ (match_operand 7 "const_int_operand" " i, i, i,
i")
+ (match_operand 8 "const_int_operand" " i, i, i,
i")
+ (match_operand 9 "const_int_operand" " i, i, i,
i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (minus:V_VLSI_D
- (match_operand:V_VLSI_D 5 "register_operand" " 0, 0")
+ (plus:V_VLSI_D
(mult:V_VLSI_D
(vec_duplicate:V_VLSI_D
- (match_operand:<VEL> 3 "reg_or_0_operand" " rJ, rJ"))
- (match_operand:V_VLSI_D 4 "register_operand" " vr, vr")))
+ (match_operand:<VEL> 3 "reg_or_0_operand" " rJ, rJ, rJ,
rJ"))
+ (match_operand:V_VLSI_D 4 "register_operand" " 0, vr, 0,
vr"))
+ (match_operand:V_VLSI_D 5 "register_operand" " vr, 0, vr,
0"))
(match_operand:V_VLSI_D 2 "vector_undef_operand")))]
"TARGET_VECTOR && TARGET_64BIT"
"@
- vnmsac.vx\t%0,%z3,%4%p1
- vnmsac.vx\t%0,%z3,%4%p1"
+ vmadd.vx\t%0,%z3,%5%p1
+ vmacc.vx\t%0,%z3,%4%p1
+ vmadd.vx\t%0,%z3,%5%p1
+ vmacc.vx\t%0,%z3,%4%p1"
[(set_attr "type" "vimuladd")
(set_attr "mode" "<MODE>")])
+(define_expand "@pred_mul_then_plus_vx<mode>"
+ [(set (match_operand:V_VLSI_QHS 0 "register_operand")
+ (if_then_else:V_VLSI_QHS
+ (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:V_VLSI_QHS
+ (mult:V_VLSI_QHS
+ (vec_duplicate:V_VLSI_QHS
+ (match_operand:<VEL> 2 "reg_or_0_operand"))
+ (match_operand:V_VLSI_QHS 3 "register_operand"))
+ (match_operand:V_VLSI_QHS 4 "register_operand"))
+ (match_operand:V_VLSI_QHS 5 "vector_merge_operand")))]
+ "TARGET_VECTOR"
+ {
+ riscv_vector::prepare_ternary_operands (operands);
+ })
+
+(define_expand "@pred_mul_then_plus_vx<mode>"
+ [(set (match_operand:V_VLSI_D 0 "register_operand")
+ (if_then_else:V_VLSI_D
+ (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:V_VLSI_D
+ (mult:V_VLSI_D
+ (vec_duplicate:V_VLSI_D
+ (match_operand:<VEL> 2 "reg_or_0_operand"))
+ (match_operand:V_VLSI_D 3 "register_operand"))
+ (match_operand:V_VLSI_D 4 "register_operand"))
+ (match_operand:V_VLSI_D 5 "vector_merge_operand")))]
+ "TARGET_VECTOR && TARGET_64BIT"
+ {
+ riscv_vector::prepare_ternary_operands (operands);
+ })
+
(include "autovec.md")
(include "autovec-opt.md")
(include "sifive-vector.md")
--
2.43.0