diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index dbf213926572..ad21ca63fb59 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -116,6 +116,17 @@ enum stringop_strategy_enum {
   STRATEGY_AUTO = STRATEGY_SCALAR | STRATEGY_VECTOR
 };
 
+/* Behavior of VSETVL Pass.  */
+enum vsetvl_strategy_enum {
+  /* Simple: Insert a vsetvl* instruction for each Vector instruction.  */
+  VSETVL_SIMPLE = 1,
+  /* Optimal but with a caveat : Run LCM dataflow analysis which could
+     lead to redundant vsetvl* instructions, which are retained.  */
+  VSETVL_OPT_NO_DEL = 2,
+  /* Optimal: Same as optimal with any redundant vsetvl* removed.  */
+  VSETVL_OPT = 4
+};
+
 #define TARGET_ZICOND_LIKE (TARGET_ZICOND || (TARGET_XVENTANACONDOPS && TARGET_64BIT))
 
 /* Bit of riscv_zvl_flags will set contintuly, N-1 bit will set if N-bit is
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index eabaef80f898..e4f1372bce3f 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -3244,31 +3244,34 @@ pre_vsetvl::pre_global_vsetvl_info ()
 	}
     }
 
-  /* Remove vsetvl infos as LCM suggest */
-  for (const bb_info *bb : crtl->ssa->bbs ())
+  if (!(vsetvl_strategy & VSETVL_OPT_NO_DEL))
     {
-      sbitmap d = m_del[bb->index ()];
-      if (bitmap_count_bits (d) == 0)
-	continue;
-      gcc_assert (bitmap_count_bits (d) == 1);
-      unsigned expr_index = bitmap_first_set_bit (d);
-      vsetvl_info &info = *m_exprs[expr_index];
-      gcc_assert (info.valid_p ());
-      gcc_assert (info.get_bb () == bb);
-      const vsetvl_block_info &block_info = get_block_info (info.get_bb ());
-      gcc_assert (block_info.get_entry_info () == info);
-      info.set_delete ();
-    }
+      /* Remove vsetvl infos as LCM suggest.  */
+      for (const bb_info *bb : crtl->ssa->bbs ())
+	{
+	  sbitmap d = m_del[bb->index ()];
+	  if (bitmap_count_bits (d) == 0)
+	    continue;
+	  gcc_assert (bitmap_count_bits (d) == 1);
+	  unsigned expr_index = bitmap_first_set_bit (d);
+	  vsetvl_info &info = *m_exprs[expr_index];
+	  gcc_assert (info.valid_p ());
+	  gcc_assert (info.get_bb () == bb);
+	  const vsetvl_block_info &block_info = get_block_info (info.get_bb ());
+	  gcc_assert (block_info.get_entry_info () == info);
+	  info.set_delete ();
+	}
 
-  /* Remove vsetvl infos if all precessors are available to the block.  */
-  for (const bb_info *bb : crtl->ssa->bbs ())
-    {
-      vsetvl_block_info &block_info = get_block_info (bb);
-      if (block_info.empty_p () || !block_info.full_available)
-	continue;
+      /* Remove vsetvl infos if all precessors are available to the block.  */
+      for (const bb_info *bb : crtl->ssa->bbs ())
+	{
+	  vsetvl_block_info &block_info = get_block_info (bb);
+	  if (block_info.empty_p () || !block_info.full_available)
+	    continue;
 
-      vsetvl_info &info = block_info.get_entry_info ();
-      info.set_delete ();
+	  vsetvl_info &info = block_info.get_entry_info ();
+	  info.set_delete ();
+	}
     }
 
   for (const bb_info *bb : crtl->ssa->bbs ())
@@ -3627,7 +3630,7 @@ pass_vsetvl::execute (function *)
   if (!has_vector_insn (cfun))
     return 0;
 
-  if (!optimize)
+  if (!optimize || vsetvl_strategy & VSETVL_SIMPLE)
     simple_vsetvl ();
   else
     lazy_vsetvl ();
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 2bc1273fe284..5f824e2ddb3d 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -553,6 +553,23 @@ Target Undocumented Bool Var(riscv_vector_abi) Init(0)
 Enable the use of vector registers for function arguments and return value.
 This is an experimental switch and may be subject to change in the future.
 
+Enum
+Name(vsetvl_strategy) Type(enum vsetvl_strategy_enum)
+Valid arguments to -param=vsetvl-strategy=:
+
+EnumValue
+Enum(vsetvl_strategy) String(simple) Value(VSETVL_SIMPLE)
+
+EnumValue
+Enum(vsetvl_strategy) String(optim-no-del) Value(VSETVL_OPT_NO_DEL)
+
+EnumValue
+Enum(vsetvl_strategy) String(optim) Value(VSETVL_OPT)
+
+-param=vsetvl-strategy=
+Target RejectNegative Joined Enum(vsetvl_strategy) Var(vsetvl_strategy) Init(VSETVL_OPT)
+-param=vsetvl-strategy=<string>	Set the optimization level of VSETVL insert pass.
+
 Enum
 Name(stringop_strategy) Type(enum stringop_strategy_enum)
 Valid arguments to -mstringop-strategy=:
