From: Pan Li <pan2...@intel.com> The signed avg_floor totally match the sematics of fixed point rvv insn vaadd, within round down. Thus, leverage it directly to implement the avf_floor.
The spec of RVV is somehow not that clear about the difference between the float point and fixed point for the rounding that discard least-significant information. For float point which is not two's complement, the "discard least-significant information" indicates truncation round. For example as below: * 3.5 -> 3 * -2.3 -> -2 For fixed point which is two's complement, the "discard least-significant information" indicates round down. For example as below: * 3.5 -> 3 * -2.3 -> -3 And the vaadd takes the round down which is totally matching the sematics of the avf_floor. The below test suites are passed for this patch series. * The rv64gcv fully regression test. gcc/ChangeLog: * config/riscv/autovec.md (avg<v_double_trunc>3_floor): Remove. (avg<mode>3_floor): Add new mode for avg_floor to leverage vaadd directly. Signed-off-by: Pan Li <pan2...@intel.com> --- gcc/config/riscv/autovec.md | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 9e51e3ce6a3..9de786014a7 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -2481,29 +2481,17 @@ (define_expand "len_fold_extract_last_<mode>" ;; op[0] = (narrow) ((wide) op[1] + (wide) op[2] + 1)) >> 1; ;; ------------------------------------------------------------------------- -(define_expand "avg<v_double_trunc>3_floor" - [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand") - (truncate:<V_DOUBLE_TRUNC> - (ashiftrt:VWEXTI - (plus:VWEXTI - (sign_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 1 "register_operand")) - (sign_extend:VWEXTI - (match_operand:<V_DOUBLE_TRUNC> 2 "register_operand"))))))] +(define_expand "avg<mode>3_floor" + [(match_operand:V_VLSI 0 "register_operand") + (match_operand:V_VLSI 1 "register_operand") + (match_operand:V_VLSI 2 "register_operand")] "TARGET_VECTOR" -{ - /* First emit a widening addition. */ - rtx tmp1 = gen_reg_rtx (<MODE>mode); - rtx ops1[] = {tmp1, operands[1], operands[2]}; - insn_code icode = code_for_pred_dual_widen (PLUS, SIGN_EXTEND, <MODE>mode); - riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops1); - - /* Then a narrowing shift. */ - rtx ops2[] = {operands[0], tmp1, const1_rtx}; - icode = code_for_pred_narrow_scalar (ASHIFTRT, <MODE>mode); - riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops2); - DONE; -}) + { + insn_code icode = code_for_pred (UNSPEC_VAADD, <MODE>mode); + riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP_VXRM_RDN, operands); + DONE; + } +) (define_expand "avg<v_double_trunc>3_ceil" [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand") -- 2.43.0