diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -64,6 +64,12 @@
 
     {"zvamo", RISCVExtensionVersion{0, 10}},
     {"zvlsseg", RISCVExtensionVersion{0, 10}},
+    {"zvl32b", RISCVExtensionVersion{0, 10}},
+    {"zvl64b", RISCVExtensionVersion{0, 10}},
+    {"zvl128b", RISCVExtensionVersion{0, 10}},
+    {"zvl256b", RISCVExtensionVersion{0, 10}},
+    {"zvl512b", RISCVExtensionVersion{0, 10}},
+    {"zvl1024b", RISCVExtensionVersion{0, 10}},
 
     {"zfh", RISCVExtensionVersion{0, 1}},
 };
diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -189,6 +189,13 @@
                                AssemblerPredicate<(all_of FeatureExtZvamo),
                                "'Zvamo' (Vector AMO Operations)">;
 
+foreach i = [32, 64, 128, 256, 512, 1024] in
+    def FeatureExtZvl#i
+        : SubtargetFeature<"experimental-zvl"#i#"b", "ZvlLen", "ExtZvl::Zvl"#i#"b",
+          "'Zvl' (Minimum Vector Length) "#i,
+          [FeatureStdExtV]>;
+def HasStdExtZvl : Predicate<"Subtarget->hasStdExtZvl()">;
+
 def Feature64Bit
     : SubtargetFeature<"64bit", "HasRV64", "true", "Implements RV64">;
 def IsRV64 : Predicate<"Subtarget->is64Bit()">,
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -32,6 +32,18 @@
 namespace llvm {
 class StringRef;
 
+namespace {
+enum ExtZvl : unsigned {
+  NotSet = 0,
+  Zvl32b = 32,
+  Zvl64b = 64,
+  Zvl128b = 128,
+  Zvl256b = 256,
+  Zvl512b = 512,
+  Zvl1024b = 1024
+};
+} // End anonymous namespace
+
 class RISCVSubtarget : public RISCVGenSubtargetInfo {
   virtual void anchor();
   bool HasStdExtM = false;
@@ -61,6 +73,7 @@
   bool EnableRVCHintInstrs = true;
   bool EnableSaveRestore = false;
   unsigned XLen = 32;
+  ExtZvl ZvlLen = ExtZvl::NotSet;
   MVT XLenVT = MVT::i32;
   uint8_t MaxInterleaveFactor = 2;
   RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;
@@ -121,6 +134,7 @@
   bool hasStdExtZbproposedc() const { return HasStdExtZbproposedc; }
   bool hasStdExtV() const { return HasStdExtV; }
   bool hasStdExtZvlsseg() const { return HasStdExtZvlsseg; }
+  bool hasStdExtZvl() const { return ZvlLen != ExtZvl::NotSet; }
   bool hasStdExtZvamo() const { return HasStdExtZvamo; }
   bool hasStdExtZfh() const { return HasStdExtZfh; }
   bool is64Bit() const { return HasRV64; }
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -109,32 +109,35 @@
   assert(hasStdExtV() && "Tried to get vector length without V support!");
   if (RVVVectorBitsMax == 0)
     return 0;
-  assert(RVVVectorBitsMax >= 128 && RVVVectorBitsMax <= 65536 &&
+  assert(RVVVectorBitsMax >= 32 && RVVVectorBitsMax <= 65536 &&
          isPowerOf2_32(RVVVectorBitsMax) &&
-         "V extension requires vector length to be in the range of 128 to "
+         "V extension requires vector length to be in the range of 32 to "
          "65536 and a power of 2!");
   assert(RVVVectorBitsMax >= RVVVectorBitsMin &&
          "Minimum V extension vector length should not be larger than its "
          "maximum!");
   unsigned Max = std::max(RVVVectorBitsMin, RVVVectorBitsMax);
-  return PowerOf2Floor((Max < 128 || Max > 65536) ? 0 : Max);
+  return PowerOf2Floor((Max < 32 || Max > 65536) ? 0 : Max);
 }
 
 unsigned RISCVSubtarget::getMinRVVVectorSizeInBits() const {
   assert(hasStdExtV() &&
          "Tried to get vector length without V extension support!");
   assert((RVVVectorBitsMin == 0 ||
-          (RVVVectorBitsMin >= 128 && RVVVectorBitsMax <= 65536 &&
+          (RVVVectorBitsMin >= 32 && RVVVectorBitsMax <= 65536 &&
            isPowerOf2_32(RVVVectorBitsMin))) &&
-         "V extension requires vector length to be in the range of 128 to "
+         "V extension requires vector length to be in the range of 32 to "
          "65536 and a power of 2!");
   assert((RVVVectorBitsMax >= RVVVectorBitsMin || RVVVectorBitsMax == 0) &&
          "Minimum V extension vector length should not be larger than its "
          "maximum!");
+  assert(RVVVectorBitsMin >= ZvlLen &&
+         "Minimum V extension vector length should be at least the length "
+         "of specified zvl extension!");
   unsigned Min = RVVVectorBitsMin;
   if (RVVVectorBitsMax != 0)
     Min = std::min(RVVVectorBitsMin, RVVVectorBitsMax);
-  return PowerOf2Floor((Min < 128 || Min > 65536) ? 0 : Min);
+  return PowerOf2Floor((Min < 32 || Min > 65536) ? 0 : Min);
 }
 
 unsigned RISCVSubtarget::getMaxLMULForFixedLengthVectors() const {