RE: [PATCH v1] RISC-V: Support rounding mode for VFMADD/VFMACC autovec
Committed, thanks Kito. Pan -Original Message- From: Kito Cheng Sent: Thursday, August 31, 2023 9:10 PM To: Li, Pan2 Cc: gcc-patches@gcc.gnu.org; juzhe.zh...@rivai.ai; Wang, Yanzhang Subject: Re: [PATCH v1] RISC-V: Support rounding mode for VFMADD/VFMACC autovec LGTM On Thu, Aug 24, 2023 at 12:49 PM Pan Li via Gcc-patches wrote: > > From: Pan Li > > There will be a case like below for intrinsic and autovec combination > > vfadd RTZ <- intrinisc static rounding > vfmadd <- autovec/autovec-opt > > The autovec generated vfmadd should take DYN mode, and the > frm must be restored before the vfmadd insn. This patch > would like to fix this issue by: > > * Add the frm operand to the vfmadd/vfmacc autovec/autovec-opt pattern. > * Set the frm_mode attr to DYN. > > Thus, the frm flow when combine autovec and intrinsic should be. > > + > | frrm a5 > | ... > | fsrmi 4 > | vfadd <- intrinsic static rounding. > | ... > | fsrm a5 > | vfmadd <- autovec/autovec-opt > | ... > + > > However, we leverage unspec instead of use to consume the FRM register > because there are some restrictions from the combine pass. Some code > path of try_combine may require the XVECLEN(pat, 0) == 2 for the > recog_for_combine, and add new use will make the XVECLEN(pat, 0) == 3 > and result in the vfwmacc optimization failure. For example, in the > test widen-complicate-5.c and widen-8.c > > Finally, there will be other fma cases and they will be covered in > the underlying patches. > > Signed-off-by: Pan Li > Co-Authored-By: Ju-Zhe Zhong > > gcc/ChangeLog: > > * config/riscv/autovec-opt.md: Add FRM_REGNUM to vfmadd/vfmacc. > * config/riscv/autovec.md: Ditto. > * config/riscv/vector-iterators.md: Add UNSPEC_VFFMA. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/rvv/base/float-point-frm-autovec-1.c: New test. > --- > gcc/config/riscv/autovec-opt.md | 32 --- > gcc/config/riscv/autovec.md | 26 +++--- > gcc/config/riscv/vector-iterators.md | 2 + > .../rvv/base/float-point-frm-autovec-1.c | 88 +++ > 4 files changed, 125 insertions(+), 23 deletions(-) > create mode 100644 > gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-1.c > > diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md > index 99b609a99d9..4b07e80ad95 100644 > --- a/gcc/config/riscv/autovec-opt.md > +++ b/gcc/config/riscv/autovec-opt.md > @@ -459,12 +459,14 @@ (define_insn_and_split "*pred_single_widen_mul" > ;; vect__13.182_33 = .FMA (vect__11.180_35, vect__8.176_40, vect__4.172_45); > (define_insn_and_split "*double_widen_fma" >[(set (match_operand:VWEXTF 0 "register_operand") > - (fma:VWEXTF > - (float_extend:VWEXTF > - (match_operand: 2 "register_operand")) > - (float_extend:VWEXTF > - (match_operand: 3 "register_operand")) > - (match_operand:VWEXTF 1 "register_operand")))] > + (unspec:VWEXTF > + [(fma:VWEXTF > + (float_extend:VWEXTF > + (match_operand: 2 "register_operand")) > + (float_extend:VWEXTF > + (match_operand: 3 "register_operand")) > + (match_operand:VWEXTF 1 "register_operand")) > + (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))] >"TARGET_VECTOR && can_create_pseudo_p ()" >"#" >"&& 1" > @@ -475,16 +477,19 @@ (define_insn_and_split "*double_widen_fma" > DONE; >} >[(set_attr "type" "vfwmuladd") > - (set_attr "mode" "")]) > + (set_attr "mode" "") > + (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) > > ;; This helps to match ext + fma. > (define_insn_and_split "*single_widen_fma" >[(set (match_operand:VWEXTF 0 "register_operand") > - (fma:VWEXTF > - (float_extend:VWEXTF > - (match_operand: 2 "register_operand")) > - (match_operand:VWEXTF 3 "register_operand") > - (match_operand:VWEXTF 1 "register_operand")))] > + (unspec:VWEXTF > + [(fma:VWEXTF > + (float_extend:VWEXTF > + (match_operand: 2 "register_operand")) > + (match_operand:VWEXTF 3 "register_operand") > + (match_operand:VWEXTF 1 "register_operand")) > + (reg:SI FRM_REGNUM)] UNSPE
Re: [PATCH v1] RISC-V: Support rounding mode for VFMADD/VFMACC autovec
LGTM On Thu, Aug 24, 2023 at 12:49 PM Pan Li via Gcc-patches wrote: > > From: Pan Li > > There will be a case like below for intrinsic and autovec combination > > vfadd RTZ <- intrinisc static rounding > vfmadd <- autovec/autovec-opt > > The autovec generated vfmadd should take DYN mode, and the > frm must be restored before the vfmadd insn. This patch > would like to fix this issue by: > > * Add the frm operand to the vfmadd/vfmacc autovec/autovec-opt pattern. > * Set the frm_mode attr to DYN. > > Thus, the frm flow when combine autovec and intrinsic should be. > > + > | frrm a5 > | ... > | fsrmi 4 > | vfadd <- intrinsic static rounding. > | ... > | fsrm a5 > | vfmadd <- autovec/autovec-opt > | ... > + > > However, we leverage unspec instead of use to consume the FRM register > because there are some restrictions from the combine pass. Some code > path of try_combine may require the XVECLEN(pat, 0) == 2 for the > recog_for_combine, and add new use will make the XVECLEN(pat, 0) == 3 > and result in the vfwmacc optimization failure. For example, in the > test widen-complicate-5.c and widen-8.c > > Finally, there will be other fma cases and they will be covered in > the underlying patches. > > Signed-off-by: Pan Li > Co-Authored-By: Ju-Zhe Zhong > > gcc/ChangeLog: > > * config/riscv/autovec-opt.md: Add FRM_REGNUM to vfmadd/vfmacc. > * config/riscv/autovec.md: Ditto. > * config/riscv/vector-iterators.md: Add UNSPEC_VFFMA. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/rvv/base/float-point-frm-autovec-1.c: New test. > --- > gcc/config/riscv/autovec-opt.md | 32 --- > gcc/config/riscv/autovec.md | 26 +++--- > gcc/config/riscv/vector-iterators.md | 2 + > .../rvv/base/float-point-frm-autovec-1.c | 88 +++ > 4 files changed, 125 insertions(+), 23 deletions(-) > create mode 100644 > gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-1.c > > diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md > index 99b609a99d9..4b07e80ad95 100644 > --- a/gcc/config/riscv/autovec-opt.md > +++ b/gcc/config/riscv/autovec-opt.md > @@ -459,12 +459,14 @@ (define_insn_and_split "*pred_single_widen_mul" > ;; vect__13.182_33 = .FMA (vect__11.180_35, vect__8.176_40, vect__4.172_45); > (define_insn_and_split "*double_widen_fma" >[(set (match_operand:VWEXTF 0 "register_operand") > - (fma:VWEXTF > - (float_extend:VWEXTF > - (match_operand: 2 "register_operand")) > - (float_extend:VWEXTF > - (match_operand: 3 "register_operand")) > - (match_operand:VWEXTF 1 "register_operand")))] > + (unspec:VWEXTF > + [(fma:VWEXTF > + (float_extend:VWEXTF > + (match_operand: 2 "register_operand")) > + (float_extend:VWEXTF > + (match_operand: 3 "register_operand")) > + (match_operand:VWEXTF 1 "register_operand")) > + (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))] >"TARGET_VECTOR && can_create_pseudo_p ()" >"#" >"&& 1" > @@ -475,16 +477,19 @@ (define_insn_and_split "*double_widen_fma" > DONE; >} >[(set_attr "type" "vfwmuladd") > - (set_attr "mode" "")]) > + (set_attr "mode" "") > + (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) > > ;; This helps to match ext + fma. > (define_insn_and_split "*single_widen_fma" >[(set (match_operand:VWEXTF 0 "register_operand") > - (fma:VWEXTF > - (float_extend:VWEXTF > - (match_operand: 2 "register_operand")) > - (match_operand:VWEXTF 3 "register_operand") > - (match_operand:VWEXTF 1 "register_operand")))] > + (unspec:VWEXTF > + [(fma:VWEXTF > + (float_extend:VWEXTF > + (match_operand: 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" > @@ -501,7 +506,8 @@ (define_insn_and_split "*single_widen_fma" > DONE; >} >[(set_attr "type" "vfwmuladd") > - (set_attr "mode" "")]) > + (set_attr "mode" "") > + (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) > > ;; - > ;; [FP] VFWNMSAC > diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md > index acca4c22b90..4894986d2a5 100644 > --- a/gcc/config/riscv/autovec.md > +++ b/gcc/config/riscv/autovec.md > @@ -1126,22 +1126,27 @@ (define_insn_and_split "*fnma" > (define_expand "fma4" >[(parallel > [(set (match_operand:VF 0 "register_operand") > - (fma:VF > - (match_operand:VF 1 "register_operand") > - (match_operand:VF 2 "register_operand") > - (match_operand:VF 3 "register_oper
[PATCH v1] RISC-V: Support rounding mode for VFMADD/VFMACC autovec
From: Pan Li There will be a case like below for intrinsic and autovec combination vfadd RTZ <- intrinisc static rounding vfmadd <- autovec/autovec-opt The autovec generated vfmadd should take DYN mode, and the frm must be restored before the vfmadd insn. This patch would like to fix this issue by: * Add the frm operand to the vfmadd/vfmacc autovec/autovec-opt pattern. * Set the frm_mode attr to DYN. Thus, the frm flow when combine autovec and intrinsic should be. + | frrm a5 | ... | fsrmi 4 | vfadd <- intrinsic static rounding. | ... | fsrm a5 | vfmadd <- autovec/autovec-opt | ... + However, we leverage unspec instead of use to consume the FRM register because there are some restrictions from the combine pass. Some code path of try_combine may require the XVECLEN(pat, 0) == 2 for the recog_for_combine, and add new use will make the XVECLEN(pat, 0) == 3 and result in the vfwmacc optimization failure. For example, in the test widen-complicate-5.c and widen-8.c Finally, there will be other fma cases and they will be covered in the underlying patches. Signed-off-by: Pan Li Co-Authored-By: Ju-Zhe Zhong gcc/ChangeLog: * config/riscv/autovec-opt.md: Add FRM_REGNUM to vfmadd/vfmacc. * config/riscv/autovec.md: Ditto. * config/riscv/vector-iterators.md: Add UNSPEC_VFFMA. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/float-point-frm-autovec-1.c: New test. --- gcc/config/riscv/autovec-opt.md | 32 --- gcc/config/riscv/autovec.md | 26 +++--- gcc/config/riscv/vector-iterators.md | 2 + .../rvv/base/float-point-frm-autovec-1.c | 88 +++ 4 files changed, 125 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-autovec-1.c diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md index 99b609a99d9..4b07e80ad95 100644 --- a/gcc/config/riscv/autovec-opt.md +++ b/gcc/config/riscv/autovec-opt.md @@ -459,12 +459,14 @@ (define_insn_and_split "*pred_single_widen_mul" ;; vect__13.182_33 = .FMA (vect__11.180_35, vect__8.176_40, vect__4.172_45); (define_insn_and_split "*double_widen_fma" [(set (match_operand:VWEXTF 0 "register_operand") - (fma:VWEXTF - (float_extend:VWEXTF - (match_operand: 2 "register_operand")) - (float_extend:VWEXTF - (match_operand: 3 "register_operand")) - (match_operand:VWEXTF 1 "register_operand")))] + (unspec:VWEXTF + [(fma:VWEXTF + (float_extend:VWEXTF + (match_operand: 2 "register_operand")) + (float_extend:VWEXTF + (match_operand: 3 "register_operand")) + (match_operand:VWEXTF 1 "register_operand")) + (reg:SI FRM_REGNUM)] UNSPEC_VFFMA))] "TARGET_VECTOR && can_create_pseudo_p ()" "#" "&& 1" @@ -475,16 +477,19 @@ (define_insn_and_split "*double_widen_fma" DONE; } [(set_attr "type" "vfwmuladd") - (set_attr "mode" "")]) + (set_attr "mode" "") + (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) ;; This helps to match ext + fma. (define_insn_and_split "*single_widen_fma" [(set (match_operand:VWEXTF 0 "register_operand") - (fma:VWEXTF - (float_extend:VWEXTF - (match_operand: 2 "register_operand")) - (match_operand:VWEXTF 3 "register_operand") - (match_operand:VWEXTF 1 "register_operand")))] + (unspec:VWEXTF + [(fma:VWEXTF + (float_extend:VWEXTF + (match_operand: 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" @@ -501,7 +506,8 @@ (define_insn_and_split "*single_widen_fma" DONE; } [(set_attr "type" "vfwmuladd") - (set_attr "mode" "")]) + (set_attr "mode" "") + (set (attr "frm_mode") (symbol_ref "riscv_vector::FRM_DYN"))]) ;; - ;; [FP] VFWNMSAC diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index acca4c22b90..4894986d2a5 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1126,22 +1126,27 @@ (define_insn_and_split "*fnma" (define_expand "fma4" [(parallel [(set (match_operand:VF 0 "register_operand") - (fma:VF - (match_operand:VF 1 "register_operand") - (match_operand:VF 2 "register_operand") - (match_operand:VF 3 "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"