diff --git a/gcc/config/riscv/riscv-vector-costs.cc b/gcc/config/riscv/riscv-vector-costs.cc
index df3c0b0d93a1886af70e11f23b59948042fd6944..0c485dc4f298082228d622b2691cba812604fca6 100644
--- a/gcc/config/riscv/riscv-vector-costs.cc
+++ b/gcc/config/riscv/riscv-vector-costs.cc
@@ -89,9 +89,9 @@ namespace riscv_vector {
 */
 
 static bool
-is_gimple_assign_or_call (gimple_stmt_iterator si)
+is_gimple_assign_or_call (gimple *stmt)
 {
-  return is_gimple_assign (gsi_stmt (si)) || is_gimple_call (gsi_stmt (si));
+  return is_gimple_assign (stmt) || is_gimple_call (stmt);
 }
 
 /* Return the program point of 1st vectorized lanes statement.  */
@@ -121,6 +121,42 @@ get_last_lane_point (const vec<stmt_point> program_points,
   return max_point;
 }
 
+/* Return the last variable that is in the live range list.  */
+static pair *
+get_live_range (hash_map<tree, pair> *live_ranges, tree arg)
+{
+  auto *r = live_ranges->get (arg);
+  if (r)
+    return r;
+  else
+    {
+      tree t = arg;
+      gimple *def_stmt = NULL;
+      while (t && TREE_CODE (t) == SSA_NAME && !r
+	     && (def_stmt = SSA_NAME_DEF_STMT (t)))
+	{
+	  if (gimple_assign_cast_p (def_stmt))
+	    {
+	      t = gimple_assign_rhs1 (def_stmt);
+	      r = live_ranges->get (t);
+	      def_stmt = NULL;
+	    }
+	  else
+	    /* FIXME: Currently we don't see any fold for
+	       non-conversion statements.  */
+	    t = NULL_TREE;
+	}
+      if (r)
+	return r;
+      else
+	{
+	  bool insert_p = live_ranges->put (arg, pair (0, 0));
+	  gcc_assert (!insert_p);
+	  return live_ranges->get (arg);
+	}
+    }
+}
+
 /* Collect all STMTs that are vectorized and compute their program points.
    Note that we don't care about the STMTs that are not vectorized and
    we only build the local graph (within a block) of program points.
@@ -163,9 +199,9 @@ compute_local_program_points (
 	    dump_printf_loc (MSG_NOTE, vect_location,
 			     "Compute local program points for bb %d:\n",
 			     bb->index);
-	  for (si = gsi_start_bb (bbs[i]); !gsi_end_p (si); gsi_next (&si))
+	  for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
 	    {
-	      if (!is_gimple_assign_or_call (si))
+	      if (!is_gimple_assign_or_call (gsi_stmt (si)))
 		continue;
 	      stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si));
 	      enum stmt_vec_info_type type
@@ -282,13 +318,33 @@ compute_local_live_ranges (
 			  == VMAT_LOAD_STORE_LANES)
 			point = get_last_lane_point (program_points,
 						     program_point.stmt_info);
+		      else if (existed_p)
+			point = MAX (live_range.second, point);
 		      if (existed_p)
 			/* We will grow the live range for each use.  */
 			live_range = pair (live_range.first, point);
 		      else
-			/* We assume the variable is live from the start of
-			   this block.  */
-			live_range = pair (0, point);
+			{
+			  gimple *def_stmt;
+			  if (TREE_CODE (var) == SSA_NAME
+			      && (def_stmt = SSA_NAME_DEF_STMT (var))
+			      && gimple_bb (def_stmt) == bb
+			      && is_gimple_assign_or_call (def_stmt))
+			    {
+			      live_ranges->remove (var);
+			      for (unsigned int j = 0;
+				   j < gimple_num_args (def_stmt); j++)
+				{
+				  tree arg = gimple_arg (def_stmt, j);
+				  auto *r = get_live_range (live_ranges, arg);
+				  gcc_assert (r);
+				  (*r).second = MAX (point, (*r).second);
+				}
+			    }
+			  else
+			    /* The splat vector lives the whole block.  */
+			    live_range = pair (0, program_points.length ());
+			}
 		    }
 		}
 	    }
@@ -589,7 +645,7 @@ update_local_live_ranges (
 	}
       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
 	{
-	  if (!is_gimple_assign_or_call (si))
+	  if (!is_gimple_assign_or_call (gsi_stmt (si)))
 	    continue;
 	  stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si));
 	  enum stmt_vec_info_type type
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-3.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-3.c
index cd476cb80ca0850add66164e27cc05d3ec26c68a..9af91b0b8639ecc963b4a9910d39dcba60640b5a 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-3.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-3.c
@@ -39,9 +39,10 @@ void foo2 (int64_t *__restrict a,
     }
 }
 
-/* { dg-final { scan-assembler {e64,m4} } } */
+/* { dg-final { scan-assembler {e32,m4} } } */
+/* { dg-final { scan-assembler {e64,m8} } } */
 /* { dg-final { scan-assembler-not {csrr} } } */
-/* { dg-final { scan-tree-dump-times "Preferring smaller LMUL loop because it has unexpected spills" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-not "Preferring smaller LMUL loop because it has unexpected spills" "vect" } } */
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 8" 1 "vect" } } */
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 4" 1 "vect" } } */
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 2" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c
index d48a37666aeb547447d7d1b8948d685400d69c1a..2a881da0b0178bc27f8f5ec8f78bdf65e91053a0 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/dynamic-lmul4-5.c
@@ -45,3 +45,5 @@ void foo2 (int16_t *__restrict a,
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 8" 1 "vect" } } */
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 4" 1 "vect" } } */
 /* { dg-final { scan-tree-dump-times "Maximum lmul = 2" 1 "vect" } } */
+/* { dg-final { scan-tree-dump "start = 8, end = 10" "vect" } } */
+/* { dg-final { scan-tree-dump "2: type = unsigned short, start = 0, end = 34" "vect" } } */