On 1/26/25 05:33, pan2...@intel.com wrote: > From: Pan Li <pan2...@intel.com> > > After we add the frm register to the global_regs, we may not need to > define_insn that volatile to emit the frm restore insns. The > cooperatively-managed global register will help to handle this, instead > of emit the volatile define_insn explicitly. > > gcc/ChangeLog: > > * config/riscv/riscv.cc (riscv_emit_frm_mode_set): Refactor > the frm mode set by removing fsrmsi_restore_volatile. > * config/riscv/vector-iterators.md (unspecv): Remove as unnecessary. > * config/riscv/vector.md (fsrmsi_restore_volatile): Ditto. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/rvv/base/float-point-dynamic-frm-49.c: Adjust > the asm dump check times. > * gcc.target/riscv/rvv/base/float-point-dynamic-frm-50.c: Ditto. > * gcc.target/riscv/rvv/base/float-point-dynamic-frm-52.c: Ditto. > * gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c: Ditto. > * gcc.target/riscv/rvv/base/float-point-dynamic-frm-75.c: Ditto. > > Signed-off-by: Pan Li <pan2...@intel.com> > --- > gcc/config/riscv/riscv.cc | 43 ++++++++++--------- > gcc/config/riscv/vector-iterators.md | 4 -- > gcc/config/riscv/vector.md | 13 ------ > .../rvv/base/float-point-dynamic-frm-49.c | 2 +- > .../rvv/base/float-point-dynamic-frm-50.c | 2 +- > .../rvv/base/float-point-dynamic-frm-52.c | 2 +- > .../rvv/base/float-point-dynamic-frm-74.c | 2 +- > .../rvv/base/float-point-dynamic-frm-75.c | 2 +- > 8 files changed, 28 insertions(+), 42 deletions(-) > > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > index dd50fe4eddf..8e3bf0077cd 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -12031,27 +12031,30 @@ riscv_emit_frm_mode_set (int mode, int prev_mode) > if (prev_mode == riscv_vector::FRM_DYN_CALL) > emit_insn (gen_frrmsi (backup_reg)); /* Backup frm when DYN_CALL. */ > > - if (mode != prev_mode) > - { > - rtx frm = gen_int_mode (mode, SImode); > - > - if (mode == riscv_vector::FRM_DYN_CALL > - && prev_mode != riscv_vector::FRM_DYN && STATIC_FRM_P (cfun)) > - /* No need to emit when prev mode is DYN already. */ > - emit_insn (gen_fsrmsi_restore_volatile (backup_reg)); > - else if (mode == riscv_vector::FRM_DYN_EXIT && STATIC_FRM_P (cfun) > - && prev_mode != riscv_vector::FRM_DYN > - && prev_mode != riscv_vector::FRM_DYN_CALL) > - /* No need to emit when prev mode is DYN or DYN_CALL already. */ > - emit_insn (gen_fsrmsi_restore_volatile (backup_reg)); > - else if (mode == riscv_vector::FRM_DYN > - && prev_mode != riscv_vector::FRM_DYN_CALL) > - /* Restore frm value from backup when switch to DYN mode. */ > - emit_insn (gen_fsrmsi_restore (backup_reg)); > - else if (riscv_static_frm_mode_p (mode)) > - /* Set frm value when switch to static mode. */ > - emit_insn (gen_fsrmsi_restore (frm)); > + if (mode == prev_mode) > + return;
Nit, can you move this check in the caller riscv_emit_mode_set () which already checks similarly for VXRM (unless there's a corner case where the gen_frrmsi is needed despite both prev and curr being same. riscv_emit_mode_set (int entity, int mode, int prev_mode, HARD_REG_SET regs_live ATTRIBUTE_UNUSED) { switch (entity) { case RISCV_VXRM: if (mode != VXRM_MODE_NONE && mode != prev_mode) emit_insn (gen_vxrmsi (gen_int_mode (mode, SImode))); break; case RISCV_FRM: + if (mode != prev_mode) riscv_emit_frm_mode_set (mode, prev_mode); break; > + > + if (riscv_static_frm_mode_p (mode)) > + { > + /* Set frm value when switch to static mode. */ > + emit_insn (gen_fsrmsi_restore (gen_int_mode (mode, SImode))); > + return; > } > + > + bool restore_p > + = /* No need to emit when prev mode is DYN. */ > + (STATIC_FRM_P (cfun) && mode == riscv_vector::FRM_DYN_CALL > + && prev_mode != riscv_vector::FRM_DYN) > + /* No need to emit if prev mode is DYN or DYN_CALL. */ > + || (STATIC_FRM_P (cfun) && mode == riscv_vector::FRM_DYN_EXIT > + && prev_mode != riscv_vector::FRM_DYN > + && prev_mode != riscv_vector::FRM_DYN_CALL) > + /* Restore frm value when switch to DYN mode. */ > + || (mode == riscv_vector::FRM_DYN > + && prev_mode != riscv_vector::FRM_DYN_CALL); > + > + if (restore_p) > + emit_insn (gen_fsrmsi_restore (backup_reg)); > } > > /* Implement Mode switching. */ > diff --git a/gcc/config/riscv/vector-iterators.md > b/gcc/config/riscv/vector-iterators.md > index c1bd7397441..f64e7ad70dd 100644 > --- a/gcc/config/riscv/vector-iterators.md > +++ b/gcc/config/riscv/vector-iterators.md > @@ -122,10 +122,6 @@ (define_c_enum "unspec" [ > UNSPEC_SF_VFNRCLIPU > ]) > > -(define_c_enum "unspecv" [ > - UNSPECV_FRM_RESTORE_EXIT > -]) > - > ;; Subset of VI with fractional LMUL types > (define_mode_iterator VI_FRAC [ > RVVMF2QI RVVMF4QI (RVVMF8QI "TARGET_MIN_VLEN > 32") > diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md > index cf22b39d6cb..fe10eabeb2e 100644 > --- a/gcc/config/riscv/vector.md > +++ b/gcc/config/riscv/vector.md > @@ -1116,19 +1116,6 @@ (define_insn "fsrmsi_restore" > (set_attr "mode" "SI")] > ) > > -;; The volatile fsrmsi restore is used for the exit point for the > -;; dynamic mode switching. It will generate one volatile fsrm a5 > -;; which won't be eliminated. > -(define_insn "fsrmsi_restore_volatile" > - [(set (reg:SI FRM_REGNUM) > - (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] > - UNSPECV_FRM_RESTORE_EXIT))] > - "TARGET_VECTOR" > - "fsrm\t%0" > - [(set_attr "type" "wrfrm") > - (set_attr "mode" "SI")] > -) > - > ;; Read FRM > (define_insn "frrmsi" > [(set (match_operand:SI 0 "register_operand" "=r") > diff --git > a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-49.c > b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-49.c > index af89f628657..3e8a9808ba7 100644 > --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-49.c > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-49.c > @@ -32,5 +32,5 @@ test_float_point_dynamic_frm (vfloat32m1_t op1, > vfloat32m1_t op2, > /* { dg-final { scan-assembler-times > {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ > /* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 3 } } */ > /* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ > -/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */ > +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ > /* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ > diff --git > a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-50.c > b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-50.c > index 5b759355547..e8fc7bbd6c2 100644 > --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-50.c > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-50.c > @@ -32,5 +32,5 @@ test_float_point_dynamic_frm (vfloat32m1_t op1, > vfloat32m1_t op2, > /* { dg-final { scan-assembler-times > {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ > /* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 3 } } */ > /* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ > -/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */ > +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ > /* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ > diff --git > a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-52.c > b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-52.c > index cd23141e72e..9828987d7d2 100644 > --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-52.c > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-52.c > @@ -32,5 +32,5 @@ test_float_point_dynamic_frm (vfloat32m1_t op1, > vfloat32m1_t op2, > /* { dg-final { scan-assembler-times > {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ > /* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 3 } } */ > /* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ > -/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */ > +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ > /* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ > diff --git > a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c > b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c > index fb57803640c..c8a580038ec 100644 > --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c > @@ -34,6 +34,6 @@ test_float_point_dynamic_frm (vfloat32m1_t op1, > vfloat32m1_t op2, > > /* { dg-final { scan-assembler-times > {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ > /* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 2 } } */ > -/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */ > +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ > /* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 2 } } */ > /* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */ > diff --git > a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-75.c > b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-75.c > index 09067d3dce7..186f6c565c7 100644 > --- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-75.c > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-75.c > @@ -34,6 +34,6 @@ test_float_point_dynamic_frm (vfloat32m1_t op1, > vfloat32m1_t op2, > > /* { dg-final { scan-assembler-times > {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 2 } } */ > /* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */ > -/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */ > +/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */ > /* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */ > /* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */