This pattern enables the combine pass to merge a vec_duplicate into a plus-mult
or minus-mult RTL instruction.

Before this patch, we have two instructions, e.g.:
  vfmv.v.f        v6,fa0
  vfmadd.vv       v9,v6,v7

After, we get only one:
  vfmadd.vf       v9,fa0,v7

On SPEC2017's 503.bwaves_r, depending on the workload, the reduction in dynamic
instruction count varies from -4.66% to -4.75%.

gcc/ChangeLog:

        PR target/119100
        * config/riscv/vector.md (*pred_<madd_msub><mode>_scalar): Define.
---
 gcc/config/riscv/vector.md | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git gcc/config/riscv/vector.md gcc/config/riscv/vector.md
index 8ee43cf0ce1..6f538eeefda 100644
--- gcc/config/riscv/vector.md
+++ gcc/config/riscv/vector.md
@@ -6633,6 +6633,29 @@
    (set (attr "frm_mode")
        (symbol_ref "riscv_vector::get_frm_mode (operands[9])"))])
 
+(define_insn_and_split "*pred_<madd_msub><mode>_scalar"
+  [(set (match_operand:V_VLSF 0 "register_operand"            "=vd, vr")
+    (plus_minus:V_VLSF
+           (mult:V_VLSF
+             (vec_duplicate:V_VLSF
+               (match_operand:<VEL> 1 "register_operand" "  f,    f"))
+             (match_operand:V_VLSF 2 "register_operand"      "  0,    0"))
+           (match_operand:V_VLSF 3 "register_operand"        " vr,   vr")))]
+  "TARGET_VECTOR"
+  "#"
+  "!reload_completed"
+  [(const_int 0)]
+  {
+    rtx ops[] = {operands[0], operands[1], operands[2], operands[3],
+                 operands[2]};
+    riscv_vector::emit_vlmax_insn (code_for_pred_mul_scalar (<CODE>, 
<MODE>mode),
+                                    riscv_vector::TERNARY_OP_FRM_DYN, ops);
+    DONE;
+  }
+  [(set_attr "type" "vfmuladd")
+   (set_attr "mode" "<MODE>")]
+)
+
 (define_insn "*pred_<macc_msac><mode>_scalar"
   [(set (match_operand:V_VLSF 0 "register_operand"            "=vd, vr")
        (if_then_else:V_VLSF
-- 
2.34.1

Reply via email to