public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-2373] RISC-V: Fix one bug for floating-point static frm
@ 2023-07-07  0:39 Pan Li
  0 siblings, 0 replies; only message in thread
From: Pan Li @ 2023-07-07  0:39 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:55900189ab517906efe08f8d17f3e4a310ee7fff

commit r14-2373-g55900189ab517906efe08f8d17f3e4a310ee7fff
Author: Pan Li <pan2.li@intel.com>
Date:   Tue Jul 4 22:05:36 2023 +0800

    RISC-V: Fix one bug for floating-point static frm
    
    This patch would like to fix one bug to align below items of spec.
    
    RVV floating-point instructions always (implicitly) use the dynamic
    rounding mode.  This implies that rounding is performed according to the
    rounding mode set in the FRM register.  The FRM register itself
    only holds proper rounding modes and never the dynamic rounding mode.
    
    Signed-off-by: Pan Li <pan2.li@intel.com>
    Co-Authored-By: Robin Dapp <rdapp@ventanamicro.com>
    
    gcc/ChangeLog:
    
            * config/riscv/riscv.cc (riscv_emit_mode_set): Avoid emit insn
            when FRM_MODE_DYN.
            (riscv_mode_entry): Take FRM_MODE_DYN as entry mode.
            (riscv_mode_exit): Likewise for exit mode.
            (riscv_mode_needed): Likewise for needed mode.
            (riscv_mode_after): Likewise for after mode.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/rvv/base/float-point-frm-insert-6.c: New test.

Diff:
---
 gcc/config/riscv/riscv.cc                          | 27 +++++++++++++++----
 .../riscv/rvv/base/float-point-frm-insert-6.c      | 31 ++++++++++++++++++++++
 2 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index e4dc8115e69..38d8eb2fcf5 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -7670,8 +7670,19 @@ riscv_emit_mode_set (int entity, int mode, int prev_mode,
 	emit_insn (gen_vxrmsi (gen_int_mode (mode, SImode)));
       break;
     case RISCV_FRM:
-      if (mode != FRM_MODE_NONE && mode != prev_mode)
+      /* Switching to the dynamic rounding mode is not necessary.  When an
+	 instruction requests it, it effectively uses the rounding mode already
+	 set in the FRM register.  All other rounding modes require us to
+	 switch the rounding mode via the FRM register.  */
+      if (mode != FRM_MODE_DYN && mode != prev_mode)
 	{
+	  /* TODO: By design, FRM_MODE_xxx used by mode switch which is
+	     different from the FRM value like FRM_RTZ defined in
+	     riscv-protos.h.  When mode switching we actually need a conversion
+	     function to convert the mode of mode switching to the actual
+	     FRM value like FRM_RTZ.  For now, the value between the mode of
+	     mode swith and the FRM value in riscv-protos.h take the same value,
+	     and then we leverage this assumption when emit.  */
 	  rtx scaler = gen_reg_rtx (SImode);
 	  rtx imm = gen_int_mode (mode, SImode);
 
@@ -7697,7 +7708,10 @@ riscv_mode_needed (int entity, rtx_insn *insn)
     case RISCV_VXRM:
       return code >= 0 ? get_attr_vxrm_mode (insn) : VXRM_MODE_NONE;
     case RISCV_FRM:
-      return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_NONE;
+      /* TODO: Here we may return FRM_MODE_NONE from get_attr_frm_mode, as well
+	 as FRM_MODE_DYN as default.  It is kind of inconsistent and we will
+	 take care of it after dynamic rounding mode.  */
+      return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_DYN;
     default:
       gcc_unreachable ();
     }
@@ -7757,7 +7771,7 @@ riscv_mode_after (int entity, int mode, rtx_insn *insn)
     case RISCV_FRM:
       return riscv_entity_mode_after (FRM_REGNUM, insn, mode,
 				      (int (*)(rtx_insn *)) get_attr_frm_mode,
-				      FRM_MODE_NONE);
+				      FRM_MODE_DYN);
     default:
       gcc_unreachable ();
     }
@@ -7774,7 +7788,10 @@ riscv_mode_entry (int entity)
     case RISCV_VXRM:
       return VXRM_MODE_NONE;
     case RISCV_FRM:
-      return FRM_MODE_NONE;
+      /* According to RVV 1.0 spec, all vector floating-point operations use
+	 the dynamic rounding mode in the frm register.  Likewise in other
+	 similar places.  */
+      return FRM_MODE_DYN;
     default:
       gcc_unreachable ();
     }
@@ -7791,7 +7808,7 @@ riscv_mode_exit (int entity)
     case RISCV_VXRM:
       return VXRM_MODE_NONE;
     case RISCV_FRM:
-      return FRM_MODE_NONE;
+      return FRM_MODE_DYN;
     default:
       gcc_unreachable ();
     }
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.c
new file mode 100644
index 00000000000..6d896e0953e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-6.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_vfadd_vv_f32m1_rm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) {
+  return __riscv_vfadd_vv_f32m1_rm (op1, op2, 7, vl);
+}
+
+vfloat32m1_t
+test_vfadd_vv_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, vfloat32m1_t op2,
+			 size_t vl) {
+  return __riscv_vfadd_vv_f32m1_m_rm(mask, op1, op2, 7, vl);
+}
+
+vfloat32m1_t
+test_vfadd_vf_f32m1_rm(vfloat32m1_t op1, float32_t op2, size_t vl) {
+  return __riscv_vfadd_vf_f32m1_rm(op1, op2, 7, vl);
+}
+
+vfloat32m1_t
+test_vfadd_vf_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, float32_t op2,
+			 size_t vl) {
+  return __riscv_vfadd_vf_f32m1_m_rm(mask, op1, op2, 7, vl);
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */
+/* { dg-final { scan-assembler-not {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} } } */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-07-07  0:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-07  0:39 [gcc r14-2373] RISC-V: Fix one bug for floating-point static frm Pan Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).