diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 332fa720f01..bd2cf8176a7 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -69,6 +69,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-iterator.h"
 #include "gimple-expr.h"
 #include "tree-vectorizer.h"
+#include "gcse.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -90,6 +91,12 @@ along with GCC; see the file COPYING3.  If not see
 /* True if bit BIT is set in VALUE.  */
 #define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
 
+/* Extract the backup dynamic frm rtl.  */
+#define DYNAMIC_FRM_RTL(c) ((c)->machine->mode_sw_info.dynamic_frm)
+
+/* True the mode switching has static frm, or false.  */
+#define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p)
+
 /* Information about a function's frame layout.  */
 struct GTY(())  riscv_frame_info {
   /* The size of the frame in bytes.  */
@@ -125,6 +132,22 @@ enum riscv_privilege_levels {
   UNKNOWN_MODE, USER_MODE, SUPERVISOR_MODE, MACHINE_MODE
 };
 
+struct GTY(()) mode_switching_info {
+  /* The RTL variable which stores the dynamic FRM value.  We always use this
+     RTX to restore dynamic FRM rounding mode in mode switching.  */
+  rtx dynamic_frm;
+
+  /* The boolean variables indicates there is at least one static rounding
+     mode instruction in the function or not.  */
+  bool static_frm_p;
+
+  mode_switching_info ()
+    {
+      dynamic_frm = NULL_RTX;
+      static_frm_p = false;
+    }
+};
+
 struct GTY(())  machine_function {
   /* The number of extra stack bytes taken up by register varargs.
      This area is allocated by the callee at the very top of the frame.  */
@@ -148,9 +171,7 @@ struct GTY(())  machine_function {
      not be considered by the prologue and epilogue.  */
   bool reg_is_wrapped_separately[FIRST_PSEUDO_REGISTER];
 
-  /* The RTL variable which stores the dynamic FRM value.  We always use this
-     RTX to restore dynamic FRM rounding mode in mode switching.  */
-  rtx dynamic_frm;
+  struct mode_switching_info mode_sw_info;
 };
 
 /* Information about a single argument.  */
@@ -7709,9 +7730,13 @@ riscv_static_frm_mode_p (int mode)
 static void
 riscv_emit_frm_mode_set (int mode, int prev_mode)
 {
+  rtx backup_reg = DYNAMIC_FRM_RTL (cfun);
+
+  if (prev_mode == FRM_MODE_DYN_CALL)
+    emit_insn (gen_frrmsi (backup_reg)); /* Backup frm when DYN_CALL.  */
+
   if (mode != prev_mode)
     {
-      rtx backup_reg = cfun->machine->dynamic_frm;
       /* 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
@@ -7721,9 +7746,13 @@ riscv_emit_frm_mode_set (int mode, int prev_mode)
 	 and then we leverage this assumption when emit.  */
       rtx frm = gen_int_mode (mode, SImode);
 
-      if (mode == FRM_MODE_DYN_EXIT && prev_mode != FRM_MODE_DYN)
+      if (mode == FRM_MODE_DYN_CALL && prev_mode != FRM_MODE_DYN)
 	/* No need to emit when prev mode is DYN already.  */
-	emit_insn (gen_fsrmsi_restore_exit (backup_reg));
+	emit_insn (gen_fsrmsi_restore_volatile (backup_reg));
+      else if (mode == FRM_MODE_DYN_EXIT && STATIC_FRM_P (cfun)
+	&& prev_mode != FRM_MODE_DYN && prev_mode != FRM_MODE_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 == FRM_MODE_DYN)
 	/* Restore frm value from backup when switch to DYN mode.  */
 	emit_insn (gen_fsrmsi_restore (backup_reg));
@@ -7753,6 +7782,102 @@ riscv_emit_mode_set (int entity, int mode, int prev_mode,
     }
 }
 
+/* Adjust the FRM_MODE_NONE insn after a call to FRM_MODE_DYN for the
+   underlying emit.  */
+
+static int
+riscv_frm_adjust_mode_after_call (rtx_insn *cur_insn)
+{
+  rtx_insn *insn;
+  int mode = FRM_MODE_NONE;
+  basic_block bb = BLOCK_FOR_INSN (cur_insn);
+
+  for (insn = PREV_INSN (cur_insn); insn; insn = PREV_INSN (insn))
+    {
+      if (INSN_P (insn))
+	{
+	  if (CALL_P (insn))
+	    mode = FRM_MODE_DYN;
+	  break;
+	}
+
+      if (insn == BB_HEAD (bb))
+	break;
+    }
+
+  return mode;
+}
+
+/* Insert the backup frm insn to the end of the bb if and only if the call
+   is the last insn of this bb.  */
+
+static void
+riscv_frm_reconcile_call_as_bb_end (rtx_insn *cur_insn)
+{
+  rtx_insn *insn;
+  basic_block bb = BLOCK_FOR_INSN (cur_insn);
+
+  gcc_assert (CALL_P (cur_insn));
+
+  if (cur_insn != BB_END (bb))
+    {
+      for (insn = NEXT_INSN (cur_insn); insn; insn = NEXT_INSN (insn))
+	{
+	  if (INSN_P (insn)) /* If there is one insn after call, do nothing.  */
+	    return;
+
+	  if (insn == BB_END (bb))
+	    break;
+	}
+    }
+
+  /* Then we need to emit backup inst to the end of bb.  */
+  start_sequence ();
+  emit_insn (gen_frrmsi (DYNAMIC_FRM_RTL (cfun)));
+  rtx_insn *backup_insn = get_insns ();
+  end_sequence ();
+
+  insert_insn_end_basic_block (backup_insn, bb);
+}
+
+/* Return mode that frm must be switched into
+   prior to the execution of insn.  */
+
+static int
+riscv_frm_mode_needed (rtx_insn *cur_insn, int code)
+{
+  if (!DYNAMIC_FRM_RTL(cfun))
+    {
+      /* The dynamic frm will be initialized only onece during cfun.  */
+      DYNAMIC_FRM_RTL (cfun) = gen_reg_rtx (SImode);
+      emit_insn_at_entry (gen_frrmsi (DYNAMIC_FRM_RTL (cfun)));
+    }
+
+  if (CALL_P (cur_insn))
+    {
+      riscv_frm_reconcile_call_as_bb_end (cur_insn);
+      return FRM_MODE_DYN_CALL;
+    }
+
+  int mode = code >= 0 ? get_attr_frm_mode (cur_insn) : FRM_MODE_NONE;
+
+  if (mode == FRM_MODE_NONE)
+      /* After meet a call, we need to backup the frm because it may be
+	 updated during the call. Here, for each insn, we will check if
+	 the previous insn is a call or not. When previous insn is call,
+	 there will be 2 cases for the emit mode set.
+
+	 1. Current insn is not MODE_NONE, then the mode switch framework
+	    will do the mode switch from MODE_CALL to MODE_NON_NONE natively.
+	 2. Current insn is MODE_NONE, we need to adjust the MODE_NONE to
+	    the MODE_DYN, and leave the mode switch itself to perform
+	    the emit mode set.
+       */
+    mode = riscv_frm_adjust_mode_after_call (cur_insn);
+
+  return mode;
+}
+
 /* Return mode that entity must be switched into
    prior to the execution of insn.  */
 
@@ -7766,7 +7891,7 @@ 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;
+      return riscv_frm_mode_needed (insn, code);
     default:
       gcc_unreachable ();
     }
@@ -7843,6 +7968,11 @@ riscv_vxrm_mode_after (rtx_insn *insn, int mode)
 static int
 riscv_frm_mode_after (rtx_insn *insn, int mode)
 {
+  STATIC_FRM_P (cfun) = STATIC_FRM_P (cfun) || riscv_static_frm_mode_p (mode);
+
+  if (CALL_P (insn))
+    return FRM_MODE_DYN_CALL;
+
   if (frm_unknown_dynamic_p (insn))
     return FRM_MODE_DYN;
 
@@ -7883,12 +8013,6 @@ riscv_mode_entry (int entity)
       return VXRM_MODE_NONE;
     case RISCV_FRM:
       {
-	if (!cfun->machine->dynamic_frm)
-	  {
-	    cfun->machine->dynamic_frm = gen_reg_rtx (SImode);
-	    emit_insn_at_entry (gen_frrmsi (cfun->machine->dynamic_frm));
-	  }
-
 	  /* 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.  */
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 69680de2600..63b2d3a9b82 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -694,7 +694,7 @@ (define_attr "vxrm_mode" "rnu,rne,rdn,rod,none"
 )
 
 ;; Defines rounding mode of an floating-point operation.
-(define_attr "frm_mode" "rne,rtz,rdn,rup,rmm,dyn,dyn_exit,none"
+(define_attr "frm_mode" "rne,rtz,rdn,rup,rmm,dyn,dyn_exit,dyn_call,none"
   (cond
     [
       (eq_attr "type" "vfalu")
@@ -829,7 +829,7 @@ (define_insn "fsrmsi_restore"
 ;; 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_exit"
+(define_insn "fsrmsi_restore_volatile"
   [(set (reg:SI FRM_REGNUM)
 	(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
 			    UNSPECV_FRM_RESTORE_EXIT))]
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-33.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-33.c
new file mode 100644
index 00000000000..4bd520ea2af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-33.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+  vl = normalize_vl (vl);
+  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+
+  return result;
+}
+
+/* { 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]+} 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-34.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-34.c
new file mode 100644
index 00000000000..6c7cf7ef69c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-34.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+
+  vl = normalize_vl (vl);
+
+  return vl > 128 ? result : 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 {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { 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-35.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-35.c
new file mode 100644
index 00000000000..b7f5a6919f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-35.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  vl = normalize_vl (vl);
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+
+  return result;
+}
+
+/* { 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 {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { 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-36.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-36.c
new file mode 100644
index 00000000000..4485cea24d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-36.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  if (vl % 4 != 0)
+    vl = normalize_vl (vl);
+
+  return vl > 16 ? result : op2;
+}
+
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */
+/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-37.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-37.c
new file mode 100644
index 00000000000..a1fca1a2a3f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-37.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			      int count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (int i = 0; i < count; i++)
+    {
+      if (i % 2 == 0)
+        result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+      else
+        vl = normalize_vl (vl);
+    }
+
+  return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */
+/* { 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]} 1 } } */
+/* { 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-38.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-38.c
new file mode 100644
index 00000000000..8d59cae9a87
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-38.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			      int count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (int i = 0; i < count; i++)
+    {
+      result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+      vl = normalize_vl (vl);
+    }
+
+  return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\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]} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-39.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-39.c
new file mode 100644
index 00000000000..04c54877393
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-39.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			      int count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (int i = 0; i < count; i++)
+    {
+      result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+
+      if (vl % 8 != 0)
+        vl = normalize_vl (vl);
+    }
+
+  return result;
+}
+
+/* { 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]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { 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-40.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-40.c
new file mode 100644
index 00000000000..49cf52f739b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-40.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+
+  vl = normalize_vl (vl);
+  vl = normalize_vl (vl);
+
+  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+
+  return result;
+}
+
+/* { 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 {fsrmi\s+[01234]} 2 } } */
+/* { 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-41.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-41.c
new file mode 100644
index 00000000000..79ef55b2c9f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-41.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+
+  vl = normalize_vl (vl);
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+
+  vl = normalize_vl (vl);
+
+  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl);
+
+  return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */
+/* { 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-42.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-42.c
new file mode 100644
index 00000000000..d2a17ad715f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-42.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+
+  vl = normalize_vl (vl);
+
+  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+
+  vl = normalize_vl (vl);
+
+  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+
+  return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { 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-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-43.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-43.c
new file mode 100644
index 00000000000..50e1da2c3c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-43.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+
+  vl = normalize_vl (vl);
+
+  if (vl % 16 == 0)
+    result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+
+  vl = normalize_vl (vl);
+
+  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+  return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { 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-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-44.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-44.c
new file mode 100644
index 00000000000..a66ca89308b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-44.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+size_t __attribute__ ((noinline))
+normalize_vl (size_t vl)
+{
+  if (vl % 4 == 0)
+    return vl;
+
+  return ((vl / 4) + 1) * 4;
+}
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+
+  vl = normalize_vl (vl);
+
+  if (vl % 16 == 0)
+    result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+
+
+  if (vl % 7 != 0)
+    vl = normalize_vl (vl);
+
+  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+  return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { 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]+} 4 } } */
+/* { 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-45.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-45.c
new file mode 100644
index 00000000000..d9c1ef29450
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-45.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+	  vl = normalize_vl (vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	  vl = normalize_vl (vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-46.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-46.c
new file mode 100644
index 00000000000..b990fb434f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-46.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+	  vl = normalize_vl (vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 3, vl);
+	  vl = normalize_vl (vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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 {fsrmi\s+[01234]} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 1 } } */
+/* { 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-47.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-47.c
new file mode 100644
index 00000000000..2c3481b980e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-47.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	  vl = normalize_vl_1 (vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	  vl = normalize_vl_2 (vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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]+} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-48.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-48.c
new file mode 100644
index 00000000000..4aeae2ee0cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-48.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	  vl = normalize_vl_1 (vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+	  vl = normalize_vl_2 (vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
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
new file mode 100644
index 00000000000..350bd4924eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-49.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+	}
+      else
+	{
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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]+} 4 } } */
+/* { 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
new file mode 100644
index 00000000000..23f72664426
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-50.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+	}
+      else
+	{
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 3, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-51.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-51.c
new file mode 100644
index 00000000000..8737ab930aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-51.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	}
+      else
+	{
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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]+} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrmi\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
new file mode 100644
index 00000000000..a73d414866b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-52.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	}
+      else
+	{
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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]+} 4 } } */
+/* { 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-53.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-53.c
new file mode 100644
index 00000000000..510210b4f5a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-53.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */
+/* { 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-54.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-54.c
new file mode 100644
index 00000000000..52c99039564
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-54.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 5 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { 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-55.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-55.c
new file mode 100644
index 00000000000..a70fc19b5c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-55.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { 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-56.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-56.c
new file mode 100644
index 00000000000..803ec80b5de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-56.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 4 } } */
+/* { 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-57.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-57.c
new file mode 100644
index 00000000000..846aece4307
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-57.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 5 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { 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-58.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-58.c
new file mode 100644
index 00000000000..c5f96bc45c0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-58.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 4 } } */
+/* { 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-59.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-59.c
new file mode 100644
index 00000000000..06c7fcf1b89
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-59.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 4 } } */
+/* { 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-60.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-60.c
new file mode 100644
index 00000000000..ad3a7f81a69
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-60.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */
+/* { 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-61.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-61.c
new file mode 100644
index 00000000000..0ae9c67ce86
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-61.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { 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-62.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-62.c
new file mode 100644
index 00000000000..1dd5a63b381
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-62.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 2, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 4 } } */
+/* { 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-63.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-63.c
new file mode 100644
index 00000000000..f73383fc279
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-63.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 4 } } */
+/* { 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-64.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-64.c
new file mode 100644
index 00000000000..ed6f22c41d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-64.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */
+/* { 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-65.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-65.c
new file mode 100644
index 00000000000..3e43aecd913
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-65.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 4 } } */
+/* { 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-66.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-66.c
new file mode 100644
index 00000000000..ea99831f31f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-66.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */
+/* { 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-67.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-67.c
new file mode 100644
index 00000000000..344701f3cb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-67.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 3 } } */
+/* { 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-68.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-68.c
new file mode 100644
index 00000000000..1dbf6dba208
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-68.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+extern size_t normalize_vl_2 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  for (unsigned i = 0; i < count; i++)
+    {
+      if (i % 3 == 0)
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl);
+	  vl = normalize_vl_1 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+	}
+      else
+	{
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+	  vl = normalize_vl_2 (vl);
+	  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 4, vl);
+	}
+    }
+
+  return result;
+}
+
+/* { 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-times {frrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrm\s+[axs][0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 4 } } */
+/* { 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-69.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-69.c
new file mode 100644
index 00000000000..b08ab1ef605
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-69.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result;
+  vfloat32m1_t f32_res = op1;
+  vint32m1_t i32_res = __riscv_vreinterpret_v_f32m1_i32m1 (op2);
+
+  if (count & vl == 0x1f)
+    i32_res = __riscv_vadd_vv_i32m1 (i32_res, i32_res, vl);
+  else
+    vl = normalize_vl_1 (vl);
+
+  f32_res = __riscv_vreinterpret_v_i32m1_f32m1 (i32_res);
+  result = __riscv_vfadd_vv_f32m1_rm (f32_res, op2, 4, vl);
+
+  return result;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {frrm\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]} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-70.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-70.c
new file mode 100644
index 00000000000..5a2b8a16952
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-70.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  if (count & vl == 0x1f)
+    result = __riscv_vfadd_vv_f32m1 (result, op2, vl);
+  else
+    vl = normalize_vl_1 (vl);
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+
+  return result;
+}
+
+/* { 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]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { 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-71.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-71.c
new file mode 100644
index 00000000000..185a04cc2bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-71.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  if (count & vl == 0x1f)
+    result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+  else
+    vl = normalize_vl_1 (vl);
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+
+  return result;
+}
+
+/* { 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]+} 1 } } */
+/* { 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-72.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-72.c
new file mode 100644
index 00000000000..6a07cfa6df9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-72.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 (size_t vl);
+
+vfloat32m1_t
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			     unsigned count, size_t vl)
+{
+  vfloat32m1_t result = op1;
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 1, vl);
+  vl = normalize_vl_1 (vl);
+
+  vint32m1_t tmp_1 = __riscv_vreinterpret_v_f32m1_i32m1 (op1);
+  vint32m1_t tmp_2 = __riscv_vreinterpret_v_f32m1_i32m1 (op2);
+
+  tmp_1 = __riscv_vadd_vv_i32m1 (tmp_1, tmp_2, vl);
+  tmp_2 = __riscv_vadd_vv_i32m1 (tmp_2, tmp_1, vl);
+  tmp_1 = __riscv_vadd_vv_i32m1 (tmp_1, tmp_2, vl);
+
+  result = __riscv_vfadd_vv_f32m1_rm (result, op2, 3, vl);
+
+  return result;
+}
+
+/* { 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]+} 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-73.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-73.c
new file mode 100644
index 00000000000..91b015c51e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-73.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 ();
+extern size_t normalize_vl_2 ();
+
+void
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			      size_t vl, int cond)
+{
+  vfloat32m1_t result_1;
+
+  asm volatile ("#def %0" : "=vr"(result_1));
+
+  result_1 = __riscv_vfadd_vv_f32m1 (op1, op2, vl);
+
+  asm volatile ("#use %0" : : "vr"(result_1));
+
+  if (cond)
+    normalize_vl_1 ();
+  else
+    normalize_vl_2 ();
+
+  vfloat32m1_t result_2;
+
+  asm volatile ("#def %0" : "=vr"(result_2));
+
+  result_2 = __riscv_vfadd_vv_f32m1_rm (op1, op2, 3, vl);
+
+  asm volatile ("#use %0" : : "vr"(result_2));
+}
+
+/* { 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]+} 1 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { 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
new file mode 100644
index 00000000000..ad599b8ef67
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-74.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 ();
+extern size_t normalize_vl_2 ();
+
+void
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			      size_t vl, int cond)
+{
+  vfloat32m1_t result_1;
+
+  asm volatile ("#def %0" : "=vr"(result_1));
+
+  result_1 = __riscv_vfadd_vv_f32m1_rm (op1, op2, 1, vl);
+
+  asm volatile ("#use %0" : : "vr"(result_1));
+
+  if (cond)
+    normalize_vl_1 ();
+  else
+    normalize_vl_2 ();
+
+  vfloat32m1_t result_2;
+
+  asm volatile ("#def %0" : "=vr"(result_2));
+
+  result_2 = __riscv_vfadd_vv_f32m1_rm (op1, op2, 3, vl);
+
+  asm volatile ("#use %0" : : "vr"(result_2));
+}
+
+/* { 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 {fsrm\s+[axs][0-9]+} 3 } } */
+/* { 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
new file mode 100644
index 00000000000..76752e4af28
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-75.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 ();
+extern size_t normalize_vl_2 ();
+
+void
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			      size_t vl, int cond)
+{
+  vfloat32m1_t result_1;
+
+  asm volatile ("#def %0" : "=vr"(result_1));
+
+  result_1 = __riscv_vfadd_vv_f32m1_rm (op1, op2, 1, vl);
+
+  asm volatile ("#use %0" : : "vr"(result_1));
+
+  if (cond)
+    normalize_vl_1 ();
+  else
+    normalize_vl_2 ();
+
+  vfloat32m1_t result_2;
+
+  asm volatile ("#def %0" : "=vr"(result_2));
+
+  result_2 = __riscv_vfadd_vv_f32m1 (op1, op2, vl);
+
+  asm volatile ("#use %0" : : "vr"(result_2));
+}
+
+/* { 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 {fsrm\s+[axs][0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {fsrmi\s+[01234]} 1 } } */
+/* { 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-76.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-76.c
new file mode 100644
index 00000000000..dd8e870c787
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-76.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+extern size_t normalize_vl_1 ();
+extern size_t normalize_vl_2 ();
+
+void
+test_float_point_dynamic_frm (vfloat32m1_t op1, vfloat32m1_t op2,
+			      size_t vl, int cond)
+{
+  vfloat32m1_t result_1;
+
+  asm volatile ("#def %0" : "=vr"(result_1));
+
+  result_1 = __riscv_vfadd_vv_f32m1 (op1, op2, vl);
+
+  asm volatile ("#use %0" : : "vr"(result_1));
+
+  if (cond)
+    normalize_vl_1 ();
+  else
+    normalize_vl_2 ();
+
+  vfloat32m1_t result_2;
+
+  asm volatile ("#def %0" : "=vr"(result_2));
+
+  result_2 = __riscv_vfadd_vv_f32m1 (op1, op2, vl);
+
+  asm volatile ("#use %0" : : "vr"(result_2));
+}
+
+/* { 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]+} 2 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */
+/* { 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-77.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-77.c
new file mode 100644
index 00000000000..c3d12cfe04e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-dynamic-frm-77.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zbb --param=riscv-autovec-preference=fixed-vlmax -ffast-math -mabi=lp64 -O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+
+double sum(double *d)
+{
+  double sum = 0.0;
+
+  for (int i = 0; i < 8; ++i)
+    sum += d[i];
+
+  return sum;
+}
+
+/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */
+/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c
index 12db112dd0b..6de9d06b875 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-insert-7.c
@@ -26,6 +26,7 @@ test_float_point_frm_static (float *out, 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 {fsrm\s+[axs][0-9]+} 1 } } */
-/* { dg-final { scan-assembler-times {frrm\s+[axs][0-9]+} 1 } } */
+/* { 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 } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[axs][0-9]+,\s*[01234]} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-4.c
new file mode 100644
index 00000000000..5796aa53a73
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-4.c
@@ -0,0 +1,82 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-options "-O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+#include <stdio.h>
+#include <stdint-gcc.h>
+
+#define ORIGINAL_FRM 1
+
+static int
+get_frm ()
+{
+  int frm = -1;
+
+  __asm__ volatile (
+    "frrm %0"
+    :"=r"(frm)
+    :
+    :
+  );
+
+  return frm;
+}
+
+static void
+set_frm (int frm)
+{
+  __asm__ volatile (
+    "fsrm %0"
+    :
+    :"r"(frm)
+    :
+  );
+}
+
+static inline void
+assert_equal (int a, int b, char *message)
+{
+  if (a != b)
+    {
+      fprintf (stdout, "%s, but get %d != %d\n", message, a, b);
+      __builtin_abort ();
+    }
+}
+
+vfloat32m1_t __attribute__ ((noinline))
+other_function (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = op2;
+
+  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+
+  assert_equal (ORIGINAL_FRM, get_frm (),
+		"The value of frm register should be ORIGINAL_FRM.");
+
+  return result;
+}
+
+vfloat32m1_t __attribute__ ((noinline))
+test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = {};
+
+  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 4, vl);
+
+  assert_equal (4, get_frm (), "The value of frm register should be 4.");
+
+  return other_function (result, op2, vl);
+}
+
+int
+main ()
+{
+  size_t vl = 8;
+  vfloat32m1_t op1 = {};
+  vfloat32m1_t op2 = {};
+
+  set_frm (ORIGINAL_FRM);
+  test_float_point_frm_run (op1, op2, vl);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-5.c
new file mode 100644
index 00000000000..208a65fcd3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-5.c
@@ -0,0 +1,83 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-options "-O3 -Wno-psabi" } */
+
+#include "riscv_vector.h"
+#include <stdio.h>
+#include <stdint-gcc.h>
+
+#define ORIGINAL_FRM 1
+#define NEW_FRM 4
+
+static int
+get_frm ()
+{
+  int frm = -1;
+
+  __asm__ volatile (
+    "frrm %0"
+    :"=r"(frm)
+    :
+    :
+  );
+
+  return frm;
+}
+
+static void
+set_frm (int frm)
+{
+  __asm__ volatile (
+    "fsrm %0"
+    :
+    :"r"(frm)
+    :
+  );
+}
+
+static inline void
+assert_equal (int a, int b, char *message)
+{
+  if (a != b)
+    {
+      fprintf (stdout, "%s, but get %d != %d\n", message, a, b);
+      __builtin_abort ();
+    }
+}
+
+void __attribute__ ((noinline))
+other_function ()
+{
+  set_frm (NEW_FRM);
+}
+
+vfloat32m1_t __attribute__ ((noinline))
+test_float_point_frm_run (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl)
+{
+  vfloat32m1_t result = {};
+
+  other_function ();
+  assert_equal (NEW_FRM, get_frm (),
+		"The value of frm register should be NEW_FRM.");
+
+  result = __riscv_vfadd_vv_f32m1_rm (op1, result, 2, vl);
+  assert_equal (2, get_frm (), "The value of frm register should be 2.");
+
+  result = __riscv_vfadd_vv_f32m1 (op1, result, vl);
+  assert_equal (NEW_FRM, get_frm (),
+		"The value of frm register should be NEW_FRM.");
+
+  return result;
+}
+
+int
+main ()
+{
+  size_t vl = 8;
+  vfloat32m1_t op1 = {};
+  vfloat32m1_t op2 = {};
+
+  set_frm (ORIGINAL_FRM);
+  test_float_point_frm_run (op1, op2, vl);
+
+  return 0;
+}
