[v1] RISC-V: Remove unnecessary frm restore volatile define_insn
Checks
Context |
Check |
Description |
rivoscibot/toolchain-ci-rivos-apply-patch |
success
|
Patch applied
|
rivoscibot/toolchain-ci-rivos-lint |
success
|
Lint passed
|
rivoscibot/toolchain-ci-rivos-build--newlib-rv64gcv-lp64d-multilib |
success
|
Build passed
|
rivoscibot/toolchain-ci-rivos-build--linux-rv64gcv-lp64d-multilib |
success
|
Build passed
|
rivoscibot/toolchain-ci-rivos-build--linux-rv64gc_zba_zbb_zbc_zbs-lp64d-multilib |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
rivoscibot/toolchain-ci-rivos-test |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Test passed
|
Commit Message
From: Pan Li <pan2.li@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.li@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(-)
Comments
On 1/26/25 6:33 AM, pan2.li@intel.com wrote:
> From: Pan Li <pan2.li@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.
It's a nice cleanup, but let's defer since it doesn't fix a bug.
jeff
> It's a nice cleanup, but let's defer since it doesn't fix a bug.
Sure thing, will defer to gcc-16.
Pan
-----Original Message-----
From: Jeff Law <jeffreyalaw@gmail.com>
Sent: Sunday, January 26, 2025 9:34 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches@gcc.gnu.org
Cc: juzhe.zhong@rivai.ai; kito.cheng@gmail.com; rdapp.gcc@gmail.com; vineetg@rivosinc.com
Subject: Re: [PATCH v1] RISC-V: Remove unnecessary frm restore volatile define_insn
On 1/26/25 6:33 AM, pan2.li@intel.com wrote:
> From: Pan Li <pan2.li@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.
It's a nice cleanup, but let's defer since it doesn't fix a bug.
jeff
On 1/26/25 05:33, pan2.li@intel.com wrote:
> From: Pan Li <pan2.li@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.li@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]} } } */
> 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.
Sure, I will send v2 after gcc-16 open.
Pan
-----Original Message-----
From: Vineet Gupta <vineetg@rivosinc.com>
Sent: Tuesday, January 28, 2025 11:01 AM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches@gcc.gnu.org
Cc: juzhe.zhong@rivai.ai; kito.cheng@gmail.com; jeffreyalaw@gmail.com; rdapp.gcc@gmail.com
Subject: Re: [PATCH v1] RISC-V: Remove unnecessary frm restore volatile define_insn
On 1/26/25 05:33, pan2.li@intel.com wrote:
> From: Pan Li <pan2.li@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.li@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]} } } */
@@ -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;
+
+ 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. */
@@ -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")
@@ -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")
@@ -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]} } } */
@@ -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]} } } */
@@ -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]} } } */
@@ -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]} } } */
@@ -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]} } } */