I defer this patch's review to kito since I am not sure whether vfrec7 needs rounding mode. juzhe.zhong@rivai.ai From: pan2.li Date: 2023-08-14 20:49 To: gcc-patches CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng Subject: [PATCH v1] RISC-V: Support RVV VFREC7 rounding mode intrinsic API From: Pan Li This patch would like to support the rounding mode API for the VFREC7 as the below samples. * __riscv_vfrec7_v_f32m1_rm * __riscv_vfrec7_v_f32m1_rm_m Signed-off-by: Pan Li gcc/ChangeLog: * config/riscv/riscv-vector-builtins-bases.cc (class vfrec7_frm): New class for frm. (vfrec7_frm_obj): New declaration. (BASE): Ditto. * config/riscv/riscv-vector-builtins-bases.h: Ditto. * config/riscv/riscv-vector-builtins-functions.def (vfrec7_frm): New intrinsic function definition. * config/riscv/vector-iterators.md (VFMISC): Remove VFREC7. (misc_op): Ditto. (float_insn_type): Ditto. (VFMISC_FRM): New int iterator. (misc_frm_op): New op for frm. (float_frm_insn_type): New type for frm. * config/riscv/vector.md (@pred_): New pattern for misc frm. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/float-point-rec7.c: New test. --- .../riscv/riscv-vector-builtins-bases.cc | 17 ++++++++++ .../riscv/riscv-vector-builtins-bases.h | 1 + .../riscv/riscv-vector-builtins-functions.def | 2 ++ gcc/config/riscv/vector-iterators.md | 12 +++++-- gcc/config/riscv/vector.md | 23 ++++++++++++++ .../riscv/rvv/base/float-point-rec7.c | 31 +++++++++++++++++++ 6 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-rec7.c diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index 2074dac0f16..249ac4e68cd 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -646,6 +646,21 @@ public: } }; +/* Implements below instructions for frm + - vfrec7 +*/ +template +class vfrec7_frm : public function_base +{ +public: + bool has_rounding_mode_operand_p () const override { return true; } + + rtx expand (function_expander &e) const override + { + return e.use_exact_insn (code_for_pred (UNSPEC, e.vector_mode ())); + } +}; + /* Implements vrsub. */ class vrsub : public function_base { @@ -2433,6 +2448,7 @@ static CONSTEXPR const unop vfsqrt_obj; static CONSTEXPR const unop_frm vfsqrt_frm_obj; static CONSTEXPR const float_misc vfrsqrt7_obj; static CONSTEXPR const float_misc vfrec7_obj; +static CONSTEXPR const vfrec7_frm vfrec7_frm_obj; static CONSTEXPR const binop vfmin_obj; static CONSTEXPR const binop vfmax_obj; static CONSTEXPR const float_misc vfsgnj_obj; @@ -2681,6 +2697,7 @@ BASE (vfsqrt) BASE (vfsqrt_frm) BASE (vfrsqrt7) BASE (vfrec7) +BASE (vfrec7_frm) BASE (vfmin) BASE (vfmax) BASE (vfsgnj) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h index 5c91381bd4c..2a9381eec5e 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.h +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h @@ -187,6 +187,7 @@ extern const function_base *const vfsqrt; extern const function_base *const vfsqrt_frm; extern const function_base *const vfrsqrt7; extern const function_base *const vfrec7; +extern const function_base *const vfrec7_frm; extern const function_base *const vfmin; extern const function_base *const vfmax; extern const function_base *const vfsgnj; diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def index a821aca6a4b..34def6bb82f 100644 --- a/gcc/config/riscv/riscv-vector-builtins-functions.def +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def @@ -396,6 +396,8 @@ DEF_RVV_FUNCTION (vfrsqrt7, alu, full_preds, f_v_ops) // 13.10. Vector Floating-Point Reciprocal Estimate Instruction DEF_RVV_FUNCTION (vfrec7, alu, full_preds, f_v_ops) +DEF_RVV_FUNCTION (vfrec7_frm, alu_frm, full_preds, f_v_ops) + // 13.11. Vector Floating-Point MIN/MAX Instructions DEF_RVV_FUNCTION (vfmin, alu, full_preds, f_vvv_ops) DEF_RVV_FUNCTION (vfmin, alu, full_preds, f_vvf_ops) diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 30808ceb241..9dd611e254b 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -1867,7 +1867,9 @@ (define_int_iterator VSAT_SHIFT_OP [UNSPEC_VSSRL UNSPEC_VSSRA]) (define_int_iterator VMISC [UNSPEC_VMSBF UNSPEC_VMSIF UNSPEC_VMSOF]) -(define_int_iterator VFMISC [UNSPEC_VFRSQRT7 UNSPEC_VFREC7]) +(define_int_iterator VFMISC [UNSPEC_VFRSQRT7]) + +(define_int_iterator VFMISC_FRM [UNSPEC_VFREC7]) (define_int_iterator VFCVTS [UNSPEC_VFCVT UNSPEC_UNSIGNED_VFCVT]) @@ -1890,9 +1892,13 @@ (define_int_attr sat_insn_type [(UNSPEC_VAADDU "vaalu") (UNSPEC_VAADD "vaalu") (UNSPEC_VNCLIPU "vnclip")]) (define_int_attr misc_op [(UNSPEC_VMSBF "sbf") (UNSPEC_VMSIF "sif") (UNSPEC_VMSOF "sof") - (UNSPEC_VFRSQRT7 "rsqrt7") (UNSPEC_VFREC7 "rec7")]) + (UNSPEC_VFRSQRT7 "rsqrt7")]) + +(define_int_attr misc_frm_op [(UNSPEC_VFREC7 "rec7")]) + +(define_int_attr float_insn_type [(UNSPEC_VFRSQRT7 "vfsqrt")]) -(define_int_attr float_insn_type [(UNSPEC_VFRSQRT7 "vfsqrt") (UNSPEC_VFREC7 "vfrecp")]) +(define_int_attr float_frm_insn_type [(UNSPEC_VFREC7 "vfrecp")]) (define_int_iterator VCOPYSIGNS [UNSPEC_VCOPYSIGN UNSPEC_VXORSIGN]) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 2550fc9a630..ff84f3fe750 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -6812,6 +6812,29 @@ (define_insn "@pred_" [(set_attr "type" "") (set_attr "mode" "")]) +(define_insn "@pred_" + [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr") + (if_then_else:VF + (unspec: + [(match_operand: 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") + (match_operand 4 "vector_length_operand" " rK, rK, rK, rK") + (match_operand 5 "const_int_operand" " i, i, i, i") + (match_operand 6 "const_int_operand" " i, i, i, i") + (match_operand 7 "const_int_operand" " i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM) + (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) + (unspec:VF + [(match_operand:VF 3 "register_operand" " vr, vr, vr, vr")] VFMISC_FRM) + (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))] + "TARGET_VECTOR" + "vf.v\t%0,%3%p1" + [(set_attr "type" "") + (set_attr "mode" "") + (set (attr "frm_mode") + (symbol_ref "riscv_vector::get_frm_mode (operands[8])"))]) + (define_insn "@pred_class" [(set (match_operand: 0 "register_operand" "=vd, vd, vr, vr") (if_then_else: diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-rec7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-rec7.c new file mode 100644 index 00000000000..a8e10d0853a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-rec7.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ + +#include "riscv_vector.h" + +typedef float float32_t; + +vfloat32m1_t +test_riscv_vfrec7_vv_f32m1_rm (vfloat32m1_t op1, size_t vl) { + return __riscv_vfrec7_v_f32m1_rm (op1, 0, vl); +} + +vfloat32m1_t +test_vfrec7_vv_f32m1_rm_m (vbool32_t mask, vfloat32m1_t op1, size_t vl) { + return __riscv_vfrec7_v_f32m1_rm_m (mask, op1, 1, vl); +} + +vfloat32m1_t +test_riscv_vfrec7_vv_f32m1 (vfloat32m1_t op1, size_t vl) { + return __riscv_vfrec7_v_f32m1 (op1, vl); +} + +vfloat32m1_t +test_vfrec7_vv_f32m1_m (vbool32_t mask, vfloat32m1_t op1, size_t vl) { + return __riscv_vfrec7_v_f32m1_m (mask, op1, vl); +} + +/* { dg-final { scan-assembler-times {vfrec7\.v\s+v[0-9]+,\s*v[0-9]+} 4 } } */ +/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ -- 2.34.1