https://github.com/imkiva updated 
https://github.com/llvm/llvm-project/pull/198229

>From 4981614e2a011f0f04fb6d06eec79a2a096cea2b Mon Sep 17 00:00:00 2001
From: imkiva <[email protected]>
Date: Mon, 18 May 2026 12:24:55 +0800
Subject: [PATCH 1/8] [RISCV][MC] Add experimental `Zvvmtls` and `Zvvmttls`
 support

---
 .../Driver/print-supported-extensions-riscv.c |   2 +
 llvm/docs/RISCVUsage.rst                      |  11 +-
 llvm/docs/ReleaseNotes.md                     |   2 +
 .../Target/RISCV/AsmParser/RISCVAsmParser.cpp |  61 +++++++++-
 .../RISCV/MCTargetDesc/RISCVInstPrinter.cpp   |  14 +++
 .../RISCV/MCTargetDesc/RISCVInstPrinter.h     |   2 +
 llvm/lib/Target/RISCV/RISCVFeatures.td        |  17 +++
 llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td   | 115 ++++++++++++++++++
 llvm/test/CodeGen/RISCV/features-info.ll      |   2 +
 llvm/test/MC/RISCV/rvv/zvvmtls-invalid.s      |  32 +++++
 llvm/test/MC/RISCV/rvv/zvvmtls.s              |  57 +++++++++
 llvm/test/MC/RISCV/rvv/zvvmttls-invalid.s     |  32 +++++
 llvm/test/MC/RISCV/rvv/zvvmttls.s             |  57 +++++++++
 13 files changed, 400 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/MC/RISCV/rvv/zvvmtls-invalid.s
 create mode 100644 llvm/test/MC/RISCV/rvv/zvvmtls.s
 create mode 100644 llvm/test/MC/RISCV/rvv/zvvmttls-invalid.s
 create mode 100644 llvm/test/MC/RISCV/rvv/zvvmttls.s

diff --git a/clang/test/Driver/print-supported-extensions-riscv.c 
b/clang/test/Driver/print-supported-extensions-riscv.c
index 6185b6a19d5e3..8cd438b797287 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -261,6 +261,8 @@
 // CHECK-NEXT:     zvqwbdota8i          0.2       'Zvqwbdota8i' (8-bit integer 
batched dot-product extension)
 // CHECK-NEXT:     zvvfmm               0.1       'Zvvfmm' (Floating-Point 
Matrix Multiply-Accumulate)
 // CHECK-NEXT:     zvvmm                0.1       'Zvvmm' (Integer Matrix 
Multiply-Accumulate)
+// CHECK-NEXT:     zvvmtls              0.1       'Zvvmtls' (Matrix Tile 
Load/Store)
+// CHECK-NEXT:     zvvmttls             0.1       'Zvvmttls' (Transposing 
Matrix Tile Load/Store)
 // CHECK-NEXT:     zvzip                0.1       'Zvzip' (Vector Reordering 
Structured Data)
 // CHECK-NEXT:     smpmpmt              0.6       'Smpmpmt' (PMP-based Memory 
Types Extension)
 // CHECK-NEXT:     svukte               0.3       'Svukte' 
(Address-Independent Latency of User-Mode Faults to Supervisor Addresses)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 103c9114c272d..95d4a4271c7ca 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -258,6 +258,10 @@ on support follow.
      ``Zvksg``         Supported (`See note <#riscv-vector-crypto-note>`__)
      ``Zvksh``         Supported (`See note <#riscv-vector-crypto-note>`__)
      ``Zvkt``          Supported
+     ``Zvvfmm``        Assembly Support
+     ``Zvvmm``         Assembly Support
+     ``Zvvmtls``       Assembly Support
+     ``Zvvmttls``      Assembly Support
      ``Zvl32b``        (`Partially <#riscv-vlen-32-note>`__) Supported
      ``Zvl64b``        Supported
      ``Zvl128b``       Supported
@@ -364,10 +368,13 @@ The primary goal of experimental support is to assist in 
the process of ratifica
   LLVM implements the `0.1 draft specification 
<https://github.com/ved-rivos/riscv-isa-manual/blob/zvzip/src/zvzip.adoc>`__.
 
 ``experimental-zvvfmm``
-  LLVM implements the `0.1 draft specification 
<https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-fa55752-2026-05-04>`__.
+  LLVM implements the `0.1 draft specification 
<https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-71c48b9-2026-05-17>`__.
 
 ``experimental-zvvmm``
-  LLVM implements the `0.1 draft specification 
<https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-fa55752-2026-05-04>`__.
+  LLVM implements the `0.1 draft specification 
<https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-71c48b9-2026-05-17>`__.
+
+``experimental-zvvmtls``, ``experimental-zvvmttls``
+  LLVM implements the `0.1 draft specification 
<https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-71c48b9-2026-05-17>`__.
 
 ``experimental-zvqwbdota8i``, ``experimental-zvqwbdota16i``, 
``experimental-zvfqwbdota8f``, ``experimental-zvfwbdota16bf``, 
``experimental-zvfbdota32f``
   LLVM implements the `0.2 draft specification 
<https://github.com/aswaterman/riscv-misc/blob/main/isa/ldot-bdot/ldot-bdot.adoc>`__.
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index ef77fe1ba28a8..e5eeb9ba03315 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -233,6 +233,8 @@ Makes programs 10x faster by doing Special New Thing.
 * Support for the experimental `XRivosVisni` vendor extension has been removed.
 * Adds experimental assembler support for the 'Zvvmm` (RISC-V Integer Matrix 
Multiply-Accumulate) extension.
 * Adds experimental assembler support for the 'Zvvfmm` (RISC-V Floating-Point 
Matrix Multiply-Accumulate) extension.
+* Adds experimental assembler support for the 'Zvvmtls` and 'Zvvmttls` (RISC-V
+  Matrix Tile Load/Store) extensions.
 * Adds support for 'Ziccid' (Instruction/Data Coherence and Consistency) 
extension.
 * Adds experimental assembler support for the `Xqccmt` (Qualcomm 16-bit Table 
Jump) vendor extension.
 * `-mcpu=sifive-870` has been renamed `-mcpu=sifive-p870-d`.
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp 
b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 66ed507cf36f4..58df4606ad3d2 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -207,6 +207,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
   ParseStatus parseVTypeI(OperandVector &Operands);
   ParseStatus parseMaskReg(OperandVector &Operands);
   ParseStatus parseVScaleReg(OperandVector &Operands);
+  ParseStatus parseTileLambda(OperandVector &Operands);
   ParseStatus parseInsnDirectiveOpcode(OperandVector &Operands);
   ParseStatus parseInsnCDirectiveOpcode(OperandVector &Operands);
   ParseStatus parseGPRAsFPR(OperandVector &Operands);
@@ -644,6 +645,10 @@ struct RISCVOperand final : public MCParsedAsmOperand {
     return Kind == KindTy::VType && RISCVVType::isValidXSfmmVType(VType.Val);
   }
 
+  bool isTileLambda() const {
+    return isUImmPred([](int64_t Imm) { return Imm >= 1 && Imm <= 7; });
+  }
+
   /// Return true if the operand is a valid for the fence instruction e.g.
   /// ('iorw').
   bool isFenceArg() const { return Kind == KindTy::Fence; }
@@ -2552,8 +2557,13 @@ ParseStatus RISCVAsmParser::parseMaskReg(OperandVector 
&Operands) {
     return ParseStatus::NoMatch;
 
   StringRef Name = getLexer().getTok().getIdentifier();
-  if (!Name.consume_back(".t"))
-    return Error(getLoc(), "expected '.t' suffix");
+  if (!Name.consume_back(".t")) {
+    // Non-register identifiers may belong to another optional operand in an
+    // overloaded mnemnoic. Let the matcher try those alternatives.
+    if (matchRegisterNameHelper(Name))
+      return Error(getLoc(), "expected '.t' suffix");
+    return ParseStatus::NoMatch;
+  }
   MCRegister Reg = matchRegisterNameHelper(Name);
 
   if (!Reg)
@@ -2587,6 +2597,53 @@ ParseStatus RISCVAsmParser::parseVScaleReg(OperandVector 
&Operands) {
   return ParseStatus::Success;
 }
 
+ParseStatus RISCVAsmParser::parseTileLambda(OperandVector &Operands) {
+  if (getLexer().isNot(AsmToken::Identifier))
+    return ParseStatus::NoMatch;
+
+  SMLoc S = getLoc();
+  StringRef Name = getLexer().getTok().getIdentifier();
+  if (!Name.consume_front("L"))
+    return ParseStatus::NoMatch;
+
+  unsigned Lambda;
+  if (Name.getAsInteger(10, Lambda))
+    return Error(S, "operand must be L1, L2, L4, L8, L16, L32, or L64");
+
+  unsigned EncodedLambda;
+  switch (Lambda) {
+  case 1:
+    EncodedLambda = 1;
+    break;
+  case 2:
+    EncodedLambda = 2;
+    break;
+  case 4:
+    EncodedLambda = 3;
+    break;
+  case 8:
+    EncodedLambda = 4;
+    break;
+  case 16:
+    EncodedLambda = 5;
+    break;
+  case 32:
+    EncodedLambda = 6;
+    break;
+  case 64:
+    EncodedLambda = 7;
+    break;
+  default:
+    return Error(S, "operand must be L1, L2, L4, L8, L16, L32, or L64");
+  }
+
+  SMLoc E = getTok().getEndLoc();
+  getLexer().Lex();
+  Operands.push_back(RISCVOperand::createExpr(
+      MCConstantExpr::create(EncodedLambda, getContext()), S, E, isRV64()));
+  return ParseStatus::Success;
+}
+
 ParseStatus RISCVAsmParser::parseGPRAsFPR64(OperandVector &Operands) {
   if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
     return ParseStatus::NoMatch;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp 
b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index aa7ce5bf5e2a2..918dbe90bfa73 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -356,6 +356,20 @@ void RISCVInstPrinter::printVScaleReg(const MCInst *MI, 
unsigned OpNo,
   O << ".scale";
 }
 
+void RISCVInstPrinter::printTileLambda(const MCInst *MI, unsigned OpNo,
+                                       const MCSubtargetInfo &STI,
+                                       raw_ostream &O) {
+  const MCOperand &MO = MI->getOperand(OpNo);
+
+  assert(MO.isImm() && "printTileLambda can only print immediate operands");
+  unsigned Lambda = MO.getImm();
+  if (Lambda == 0)
+    return;
+
+  assert(Lambda <= 7 && "Unexpected tile lambda encoding");
+  O << ", L" << (1U << (Lambda - 1));
+}
+
 void RISCVInstPrinter::printImm(const MCInst *MI, unsigned OpNo,
                                 const MCSubtargetInfo &STI, raw_ostream &O) {
   const MCOperand &Op = MI->getOperand(OpNo);
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h 
b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
index fb0598faff2be..587eb41803a45 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
@@ -54,6 +54,8 @@ class RISCVInstPrinter : public MCInstPrinter {
                      const MCSubtargetInfo &STI, raw_ostream &O);
   void printVScaleReg(const MCInst *MI, unsigned OpNo,
                       const MCSubtargetInfo &STI, raw_ostream &O);
+  void printTileLambda(const MCInst *MI, unsigned OpNo,
+                       const MCSubtargetInfo &STI, raw_ostream &O);
   void printImm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
                 raw_ostream &O);
   void printRegList(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo 
&STI,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td 
b/llvm/lib/Target/RISCV/RISCVFeatures.td
index ff875b745cb0e..4b0553a193bb4 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -901,6 +901,23 @@ def HasStdExtZvvfmm : 
Predicate<"Subtarget->hasStdExtZvvfmm()">,
                       AssemblerPredicate<(all_of FeatureStdExtZvvfmm),
                           "'Zvvfmm' (Floating-Point Matrix 
Multiply-Accumulate)">;
 
+// Integrated Matrix Extension matrix tile load/store
+def FeatureStdExtZvvmtls
+    : RISCVExperimentalExtension<0, 1, "Matrix Tile Load/Store",
+                                 [FeatureStdExtZve32x]>;
+def HasStdExtZvvmtls : Predicate<"Subtarget->hasStdExtZvvmtls()">,
+                       AssemblerPredicate<(all_of FeatureStdExtZvvmtls),
+                           "'Zvvmtls' (Matrix Tile Load/Store)">;
+
+// Integrated Matrix Extension transposing matrix tile load/store
+def FeatureStdExtZvvmttls
+    : RISCVExperimentalExtension<0, 1,
+                                 "Transposing Matrix Tile Load/Store",
+                                 [FeatureStdExtZve32x]>;
+def HasStdExtZvvmttls : Predicate<"Subtarget->hasStdExtZvvmttls()">,
+                        AssemblerPredicate<(all_of FeatureStdExtZvvmttls),
+                            "'Zvvmttls' (Transposing Matrix Tile Load/Store)">;
+
 // Zvbdota family of batched dot-product extensions
 def FeatureStdExtZvqwbdota8i
     : RISCVExperimentalExtension<0, 2,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
index 0a358ba9ba0bb..b03559ab7f4f3 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
@@ -16,6 +16,28 @@
 // Instructions
 
//===----------------------------------------------------------------------===//
 
+def TileLambdaAsmOperand : AsmOperandClass {
+  let Name = "TileLambda";
+  let RenderMethod = "addImmOperands";
+  let ParserMethod = "parseTileLambda";
+  let DiagnosticType = "InvalidTileLambda";
+  let DiagnosticString = "operand must be L1, L2, L4, L8, L16, L32, or L64";
+}
+
+def TileLambdaOp : RISCVOp {
+  let ParserMatchClass = TileLambdaAsmOperand;
+  let PrintMethod = "printTileLambda";
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeUImmOperand<3>";
+  let OperandType = "OPERAND_UIMM3";
+  let MCOperandPredicate = [{
+    int64_t Imm;
+    if (!MCOp.evaluateAsConstantImm(Imm))
+      return false;
+    return Imm >= 1 && Imm <= 7;
+  }];
+}
+
 def VScaleAsmOperand : AsmOperandClass {
   let Name = "RVVScaleRegOpOperand";
   let RenderMethod = "addRegOperands";
@@ -34,6 +56,84 @@ def VScaleOp : RegisterOperand<VMV0> {
   let DecoderMethod = "decodeVMaskReg";
 }
 
+class VTileLoadBase<bits<2> mop, dag ins, string opcodestr, string argstr>
+    : RVInst<(outs VR:$vd),
+             ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> vd;
+  bits<5> rs1;
+  bits<5> rs2;
+  bit vm;
+  bits<3> vlambda;
+
+  let Inst{31-29} = vlambda;
+  let Inst{28} = 1;
+  let Inst{27-26} = mop;
+  let Inst{25} = vm;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = 0b111;
+  let Inst{11-7} = vd;
+  let Inst{6-0} = OPC_LOAD_FP.Value;
+
+  let mayLoad = 1;
+  let mayStore = 0;
+  let hasSideEffects = 0;
+  let Uses = [VL, VTYPE];
+  let VMConstraint = true;
+  let UseNamedOperandTable = true;
+}
+
+class VTileStoreBase<bits<2> mop, dag ins, string opcodestr, string argstr>
+    : RVInst<(outs),
+             ins, opcodestr, argstr, [], InstFormatR> {
+  bits<5> vs3;
+  bits<5> rs1;
+  bits<5> rs2;
+  bit vm;
+  bits<3> vlambda;
+
+  let Inst{31-29} = vlambda;
+  let Inst{28} = 1;
+  let Inst{27-26} = mop;
+  let Inst{25} = vm;
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = 0b111;
+  let Inst{11-7} = vs3;
+  let Inst{6-0} = OPC_STORE_FP.Value;
+
+  let mayLoad = 0;
+  let mayStore = 1;
+  let hasSideEffects = 0;
+  let Uses = [VL, VTYPE];
+  let UseNamedOperandTable = true;
+}
+
+class VTileLoad<bits<2> mop, string opcodestr>
+    : VTileLoadBase<mop, (ins GPRMemZeroOffset:$rs1, GPR:$rs2, VMaskOp:$vm),
+                    opcodestr, "$vd, $rs1, $rs2$vm"> {
+  let vlambda = 0;
+}
+
+class VTileLoadLambda<bits<2> mop, string opcodestr>
+    : VTileLoadBase<mop, (ins GPRMemZeroOffset:$rs1, GPR:$rs2,
+                              TileLambdaOp:$vlambda, VMaskOp:$vm),
+                    opcodestr, "$vd, $rs1, $rs2$vlambda$vm">;
+
+class VTileStore<bits<2> mop, string opcodestr>
+    : VTileStoreBase<mop,
+                     (ins VR:$vs3, GPRMemZeroOffset:$rs1, GPR:$rs2,
+                          VMaskOp:$vm),
+                     opcodestr, "$vs3, $rs1, $rs2$vm"> {
+  let vlambda = 0;
+}
+
+class VTileStoreLambda<bits<2> mop, string opcodestr>
+    : VTileStoreBase<mop,
+                     (ins VR:$vs3, GPRMemZeroOffset:$rs1, GPR:$rs2,
+                          TileLambdaOp:$vlambda, VMaskOp:$vm),
+                     opcodestr, "$vs3, $rs1, $rs2$vlambda$vm">;
+
 class VIMEMACVV<bits<6> funct6, string opcodestr>
     : RVInstVV<funct6, OPIVV, (outs VR:$vd_wb),
                (ins VR:$vd, VR:$vs1, VR:$vs2), opcodestr,
@@ -42,6 +142,7 @@ class VIMEMACVV<bits<6> funct6, string opcodestr>
   let mayStore = 0;
   let hasSideEffects = 0;
   let Constraints = "$vd = $vd_wb";
+  let Uses = [VL, VTYPE];
   let vm = 1;
   let VMConstraint = false;
 }
@@ -111,3 +212,17 @@ let Predicates = [HasStdExtZvvfmm] in {
   def VFQIMMACC_VV : VIFMEMACScaleVV<0b111010, "vfqimmacc.vv">;
   def VF8WIMMACC_VV : VIFMEMACScaleVV<0b111011, "vf8wimmacc.vv">;
 } // Predicates = [HasStdExtZvvfmm]
+
+let Predicates = [HasStdExtZvvmtls] in {
+  def VMTL_V_L : VTileLoadLambda<0b00, "vmtl.v">, VLSSchedMC<64>;
+  def VMTL_V : VTileLoad<0b00, "vmtl.v">, VLSSchedMC<64>;
+  def VMTS_V_L : VTileStoreLambda<0b00, "vmts.v">, VSSSchedMC<64>;
+  def VMTS_V : VTileStore<0b00, "vmts.v">, VSSSchedMC<64>;
+} // Predicates = [HasStdExtZvvmtls]
+
+let Predicates = [HasStdExtZvvmttls] in {
+  def VMTTL_V_L : VTileLoadLambda<0b01, "vmttl.v">, VLSSchedMC<64>;
+  def VMTTL_V : VTileLoad<0b01, "vmttl.v">, VLSSchedMC<64>;
+  def VMTTS_V_L : VTileStoreLambda<0b01, "vmtts.v">, VSSSchedMC<64>;
+  def VMTTS_V : VTileStore<0b01, "vmtts.v">, VSSSchedMC<64>;
+} // Predicates = [HasStdExtZvvmttls]
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll 
b/llvm/test/CodeGen/RISCV/features-info.ll
index 610152c3a1f22..866878a06a346 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -47,6 +47,8 @@
 ; CHECK-NEXT:   experimental-zvqwbdota8i         - 'Zvqwbdota8i' (8-bit 
integer batched dot-product extension).
 ; CHECK-NEXT:   experimental-zvvfmm              - 'Zvvfmm' (Floating-Point 
Matrix Multiply-Accumulate).
 ; CHECK-NEXT:   experimental-zvvmm               - 'Zvvmm' (Integer Matrix 
Multiply-Accumulate).
+; CHECK-NEXT:   experimental-zvvmtls             - 'Zvvmtls' (Matrix Tile 
Load/Store).
+; CHECK-NEXT:   experimental-zvvmttls            - 'Zvvmttls' (Transposing 
Matrix Tile Load/Store).
 ; CHECK-NEXT:   experimental-zvzip               - 'Zvzip' (Vector Reordering 
Structured Data).
 ; CHECK-NEXT:   f                                - 'F' (Single-Precision 
Floating-Point).
 ; CHECK-NEXT:   forced-atomics                   - Assume that lock-free 
native-width atomics are available.
diff --git a/llvm/test/MC/RISCV/rvv/zvvmtls-invalid.s 
b/llvm/test/MC/RISCV/rvv/zvvmtls-invalid.s
new file mode 100644
index 0000000000000..20a5b3400097b
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvvmtls-invalid.s
@@ -0,0 +1,32 @@
+# RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-zvvmtls %s 2>&1 \
+# RUN:        | FileCheck %s
+
+vmtl.v v8, (a0), a1, L0
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmtl.v v8, (a0), a1, L3
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmtl.v v8, (a0), a1, L128
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmtl.v v8, (a0), a1, L4, v1.t
+# CHECK: error: operand must be v0.t
+
+vmtl.v v8, (a0), a1, v0.t, L4
+# CHECK: error: invalid operand for instruction
+
+vmts.v v12, (a0), a1, L0
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmts.v v12, (a0), a1, L3
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmts.v v12, (a0), a1, L128
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmts.v v12, (a0), a1, L4, v1.t
+# CHECK: error: operand must be v0.t
+
+vmts.v v12, (a0), a1, v0.t, L4
+# CHECK: error: invalid operand for instruction
diff --git a/llvm/test/MC/RISCV/rvv/zvvmtls.s b/llvm/test/MC/RISCV/rvv/zvvmtls.s
new file mode 100644
index 0000000000000..be00fa314dea2
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvvmtls.s
@@ -0,0 +1,57 @@
+# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-zvvmtls %s 
\
+# RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: not llvm-mc -triple=riscv64 -show-encoding %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+experimental-zvvmtls %s \
+# RUN:        | llvm-objdump -d --mattr=+experimental-zvvmtls - \
+# RUN:        | FileCheck %s --check-prefix=CHECK-INST
+
+vmtl.v v8, (a0), a1
+# CHECK-INST: vmtl.v v8, (a0), a1
+# CHECK-ENCODING: [0x07,0x74,0xb5,0x12]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
+
+vmtl.v v8, (a0), a1, L4
+# CHECK-INST: vmtl.v v8, (a0), a1, L4
+# CHECK-ENCODING: [0x07,0x74,0xb5,0x72]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
+
+vmtl.v v8, (a0), a1, v0.t
+# CHECK-INST: vmtl.v v8, (a0), a1, v0.t
+# CHECK-ENCODING: [0x07,0x74,0xb5,0x10]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
+
+vmtl.v v8, (a0), a1, L4, v0.t
+# CHECK-INST: vmtl.v v8, (a0), a1, L4, v0.t
+# CHECK-ENCODING: [0x07,0x74,0xb5,0x70]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
+
+vmtl.v v8, (a0), zero, L64, v0.t
+# CHECK-INST: vmtl.v v8, (a0), zero, L64, v0.t
+# CHECK-ENCODING: [0x07,0x74,0x05,0xf0]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
+
+vmts.v v12, (a0), a1
+# CHECK-INST: vmts.v v12, (a0), a1
+# CHECK-ENCODING: [0x27,0x76,0xb5,0x12]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
+
+vmts.v v12, (a0), a1, L4
+# CHECK-INST: vmts.v v12, (a0), a1, L4
+# CHECK-ENCODING: [0x27,0x76,0xb5,0x72]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
+
+vmts.v v12, (a0), a1, v0.t
+# CHECK-INST: vmts.v v12, (a0), a1, v0.t
+# CHECK-ENCODING: [0x27,0x76,0xb5,0x10]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
+
+vmts.v v12, (a0), a1, L4, v0.t
+# CHECK-INST: vmts.v v12, (a0), a1, L4, v0.t
+# CHECK-ENCODING: [0x27,0x76,0xb5,0x70]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
+
+vmts.v v12, (a0), zero, L64, v0.t
+# CHECK-INST: vmts.v v12, (a0), zero, L64, v0.t
+# CHECK-ENCODING: [0x27,0x76,0x05,0xf0]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
diff --git a/llvm/test/MC/RISCV/rvv/zvvmttls-invalid.s 
b/llvm/test/MC/RISCV/rvv/zvvmttls-invalid.s
new file mode 100644
index 0000000000000..226680f32b7c5
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvvmttls-invalid.s
@@ -0,0 +1,32 @@
+# RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-zvvmttls %s 2>&1 \
+# RUN:        | FileCheck %s
+
+vmttl.v v8, (a0), a1, L0
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmttl.v v8, (a0), a1, L3
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmttl.v v8, (a0), a1, L128
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmttl.v v8, (a0), a1, L4, v1.t
+# CHECK: error: operand must be v0.t
+
+vmttl.v v8, (a0), a1, v0.t, L4
+# CHECK: error: invalid operand for instruction
+
+vmtts.v v12, (a0), a1, L0
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmtts.v v12, (a0), a1, L3
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmtts.v v12, (a0), a1, L128
+# CHECK: error: operand must be L1, L2, L4, L8, L16, L32, or L64
+
+vmtts.v v12, (a0), a1, L4, v1.t
+# CHECK: error: operand must be v0.t
+
+vmtts.v v12, (a0), a1, v0.t, L4
+# CHECK: error: invalid operand for instruction
diff --git a/llvm/test/MC/RISCV/rvv/zvvmttls.s 
b/llvm/test/MC/RISCV/rvv/zvvmttls.s
new file mode 100644
index 0000000000000..07c6b1cbce243
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvvmttls.s
@@ -0,0 +1,57 @@
+# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-zvvmttls 
%s \
+# RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: not llvm-mc -triple=riscv64 -show-encoding %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+experimental-zvvmttls %s 
\
+# RUN:        | llvm-objdump -d --mattr=+experimental-zvvmttls - \
+# RUN:        | FileCheck %s --check-prefix=CHECK-INST
+
+vmttl.v v8, (a0), a1
+# CHECK-INST: vmttl.v v8, (a0), a1
+# CHECK-ENCODING: [0x07,0x74,0xb5,0x16]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
+
+vmttl.v v8, (a0), a1, L4
+# CHECK-INST: vmttl.v v8, (a0), a1, L4
+# CHECK-ENCODING: [0x07,0x74,0xb5,0x76]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
+
+vmttl.v v8, (a0), a1, v0.t
+# CHECK-INST: vmttl.v v8, (a0), a1, v0.t
+# CHECK-ENCODING: [0x07,0x74,0xb5,0x14]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
+
+vmttl.v v8, (a0), a1, L4, v0.t
+# CHECK-INST: vmttl.v v8, (a0), a1, L4, v0.t
+# CHECK-ENCODING: [0x07,0x74,0xb5,0x74]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
+
+vmttl.v v8, (a0), zero, L64, v0.t
+# CHECK-INST: vmttl.v v8, (a0), zero, L64, v0.t
+# CHECK-ENCODING: [0x07,0x74,0x05,0xf4]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
+
+vmtts.v v12, (a0), a1
+# CHECK-INST: vmtts.v v12, (a0), a1
+# CHECK-ENCODING: [0x27,0x76,0xb5,0x16]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
+
+vmtts.v v12, (a0), a1, L4
+# CHECK-INST: vmtts.v v12, (a0), a1, L4
+# CHECK-ENCODING: [0x27,0x76,0xb5,0x76]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
+
+vmtts.v v12, (a0), a1, v0.t
+# CHECK-INST: vmtts.v v12, (a0), a1, v0.t
+# CHECK-ENCODING: [0x27,0x76,0xb5,0x14]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
+
+vmtts.v v12, (a0), a1, L4, v0.t
+# CHECK-INST: vmtts.v v12, (a0), a1, L4, v0.t
+# CHECK-ENCODING: [0x27,0x76,0xb5,0x74]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
+
+vmtts.v v12, (a0), zero, L64, v0.t
+# CHECK-INST: vmtts.v v12, (a0), zero, L64, v0.t
+# CHECK-ENCODING: [0x27,0x76,0x05,0xf4]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}

>From 85699b55dddc97ed6bc47ef7562f716ff26a0db7 Mon Sep 17 00:00:00 2001
From: imkiva <[email protected]>
Date: Mon, 18 May 2026 12:42:13 +0800
Subject: [PATCH 2/8] Update docs

---
 llvm/docs/RISCVUsage.rst | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 95d4a4271c7ca..d8c7642da35df 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -373,7 +373,10 @@ The primary goal of experimental support is to assist in 
the process of ratifica
 ``experimental-zvvmm``
   LLVM implements the `0.1 draft specification 
<https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-71c48b9-2026-05-17>`__.
 
-``experimental-zvvmtls``, ``experimental-zvvmttls``
+``experimental-zvvmtls``
+  LLVM implements the `0.1 draft specification 
<https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-71c48b9-2026-05-17>`__.
+
+``experimental-zvvmttls``
   LLVM implements the `0.1 draft specification 
<https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-71c48b9-2026-05-17>`__.
 
 ``experimental-zvqwbdota8i``, ``experimental-zvqwbdota16i``, 
``experimental-zvfqwbdota8f``, ``experimental-zvfwbdota16bf``, 
``experimental-zvfbdota32f``

>From 097fd247a785ab750858870151095fa1a5145e3a Mon Sep 17 00:00:00 2001
From: imkiva <[email protected]>
Date: Mon, 18 May 2026 12:45:13 +0800
Subject: [PATCH 3/8] Update docs

---
 llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
index b03559ab7f4f3..ea33880972b04 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
@@ -214,15 +214,15 @@ let Predicates = [HasStdExtZvvfmm] in {
 } // Predicates = [HasStdExtZvvfmm]
 
 let Predicates = [HasStdExtZvvmtls] in {
-  def VMTL_V_L : VTileLoadLambda<0b00, "vmtl.v">, VLSSchedMC<64>;
-  def VMTL_V : VTileLoad<0b00, "vmtl.v">, VLSSchedMC<64>;
-  def VMTS_V_L : VTileStoreLambda<0b00, "vmts.v">, VSSSchedMC<64>;
-  def VMTS_V : VTileStore<0b00, "vmts.v">, VSSSchedMC<64>;
+  def VMTL_V_L : VTileLoadLambda<0b00, "vmtl.v">;
+  def VMTL_V : VTileLoad<0b00, "vmtl.v">;
+  def VMTS_V_L : VTileStoreLambda<0b00, "vmts.v">;
+  def VMTS_V : VTileStore<0b00, "vmts.v">;
 } // Predicates = [HasStdExtZvvmtls]
 
 let Predicates = [HasStdExtZvvmttls] in {
-  def VMTTL_V_L : VTileLoadLambda<0b01, "vmttl.v">, VLSSchedMC<64>;
-  def VMTTL_V : VTileLoad<0b01, "vmttl.v">, VLSSchedMC<64>;
-  def VMTTS_V_L : VTileStoreLambda<0b01, "vmtts.v">, VSSSchedMC<64>;
-  def VMTTS_V : VTileStore<0b01, "vmtts.v">, VSSSchedMC<64>;
+  def VMTTL_V_L : VTileLoadLambda<0b01, "vmttl.v">;
+  def VMTTL_V : VTileLoad<0b01, "vmttl.v">;
+  def VMTTS_V_L : VTileStoreLambda<0b01, "vmtts.v">;
+  def VMTTS_V : VTileStore<0b01, "vmtts.v">;
 } // Predicates = [HasStdExtZvvmttls]

>From 917f4f0f5091fd0bcbc3058adec96e67eab8356b Mon Sep 17 00:00:00 2001
From: imkiva <[email protected]>
Date: Mon, 18 May 2026 14:52:33 +0800
Subject: [PATCH 4/8] Review

---
 .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 30 ++-------------
 llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td   | 38 +++++++++----------
 .../TargetParser/RISCVISAInfoTest.cpp         |  2 +
 3 files changed, 25 insertions(+), 45 deletions(-)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp 
b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 58df4606ad3d2..63e36cd1665f6 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -646,7 +646,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
   }
 
   bool isTileLambda() const {
-    return isUImmPred([](int64_t Imm) { return Imm >= 1 && Imm <= 7; });
+    return isUImmPred([](int64_t Imm) { return Imm && isUInt<3>(Imm); });
   }
 
   /// Return true if the operand is a valid for the fence instruction e.g.
@@ -2610,32 +2610,10 @@ ParseStatus 
RISCVAsmParser::parseTileLambda(OperandVector &Operands) {
   if (Name.getAsInteger(10, Lambda))
     return Error(S, "operand must be L1, L2, L4, L8, L16, L32, or L64");
 
-  unsigned EncodedLambda;
-  switch (Lambda) {
-  case 1:
-    EncodedLambda = 1;
-    break;
-  case 2:
-    EncodedLambda = 2;
-    break;
-  case 4:
-    EncodedLambda = 3;
-    break;
-  case 8:
-    EncodedLambda = 4;
-    break;
-  case 16:
-    EncodedLambda = 5;
-    break;
-  case 32:
-    EncodedLambda = 6;
-    break;
-  case 64:
-    EncodedLambda = 7;
-    break;
-  default:
+  if (!isPowerOf2_32(Lambda) || Lambda >= 128)
     return Error(S, "operand must be L1, L2, L4, L8, L16, L32, or L64");
-  }
+
+  unsigned EncodedLambda = Log2_32(Lambda) + 1;
 
   SMLoc E = getTok().getEndLoc();
   getLexer().Lex();
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
index ea33880972b04..23e69eaf7a24b 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
@@ -34,7 +34,7 @@ def TileLambdaOp : RISCVOp {
     int64_t Imm;
     if (!MCOp.evaluateAsConstantImm(Imm))
       return false;
-    return Imm >= 1 && Imm <= 7;
+    return Imm && isUInt<3>(Imm);
   }];
 }
 
@@ -75,9 +75,9 @@ class VTileLoadBase<bits<2> mop, dag ins, string opcodestr, 
string argstr>
   let Inst{11-7} = vd;
   let Inst{6-0} = OPC_LOAD_FP.Value;
 
-  let mayLoad = 1;
-  let mayStore = 0;
-  let hasSideEffects = 0;
+  let mayLoad = true;
+  let mayStore = false;
+  let hasSideEffects = false;
   let Uses = [VL, VTYPE];
   let VMConstraint = true;
   let UseNamedOperandTable = true;
@@ -102,9 +102,9 @@ class VTileStoreBase<bits<2> mop, dag ins, string 
opcodestr, string argstr>
   let Inst{11-7} = vs3;
   let Inst{6-0} = OPC_STORE_FP.Value;
 
-  let mayLoad = 0;
-  let mayStore = 1;
-  let hasSideEffects = 0;
+  let mayLoad = false;
+  let mayStore = true;
+  let hasSideEffects = false;
   let Uses = [VL, VTYPE];
   let UseNamedOperandTable = true;
 }
@@ -138,9 +138,9 @@ class VIMEMACVV<bits<6> funct6, string opcodestr>
     : RVInstVV<funct6, OPIVV, (outs VR:$vd_wb),
                (ins VR:$vd, VR:$vs1, VR:$vs2), opcodestr,
                "$vd, $vs1, $vs2"> {
-  let mayLoad = 0;
-  let mayStore = 0;
-  let hasSideEffects = 0;
+  let mayLoad = false;
+  let mayStore = false;
+  let hasSideEffects = false;
   let Constraints = "$vd = $vd_wb";
   let Uses = [VL, VTYPE];
   let vm = 1;
@@ -151,9 +151,9 @@ class VFMEMACVV<bits<6> funct6, string opcodestr>
     : RVInstVV<funct6, OPFVV, (outs VR:$vd_wb),
                (ins VR:$vd, VR:$vs1, VR:$vs2), opcodestr,
                "$vd, $vs1, $vs2"> {
-  let mayLoad = 0;
-  let mayStore = 0;
-  let hasSideEffects = 0;
+  let mayLoad = false;
+  let mayStore = false;
+  let hasSideEffects = false;
   let Constraints = "$vd = $vd_wb";
   let Uses = [FRM, VL, VTYPE];
   let mayRaiseFPException = true;
@@ -165,9 +165,9 @@ class VFMEMACScaleVV<bits<6> funct6, string opcodestr>
     : RVInstVV<funct6, OPFVV, (outs VR:$vd_wb),
                (ins VR:$vd, VR:$vs1, VR:$vs2, VScaleOp:$vm), opcodestr,
                "$vd, $vs1, $vs2$vm"> {
-  let mayLoad = 0;
-  let mayStore = 0;
-  let hasSideEffects = 0;
+  let mayLoad = false;
+  let mayStore = false;
+  let hasSideEffects = false;
   let Constraints = "$vd = $vd_wb";
   let Uses = [FRM, VL, VTYPE];
   let mayRaiseFPException = true;
@@ -179,9 +179,9 @@ class VIFMEMACScaleVV<bits<6> funct6, string opcodestr>
     : RVInstVV<funct6, OPIVV, (outs VR:$vd_wb),
                (ins VR:$vd, VR:$vs1, VR:$vs2, VScaleOp:$vm), opcodestr,
                "$vd, $vs1, $vs2$vm"> {
-  let mayLoad = 0;
-  let mayStore = 0;
-  let hasSideEffects = 0;
+  let mayLoad = false;
+  let mayStore = false;
+  let hasSideEffects = false;
   let Constraints = "$vd = $vd_wb";
   let Uses = [FRM, VL, VTYPE];
   let mayRaiseFPException = true;
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp 
b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index a1702af0f5325..87539f4dd98f7 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1397,6 +1397,8 @@ Experimental extensions
     zvqwbdota8i          0.2
     zvvfmm               0.1
     zvvmm                0.1
+    zvvmtls              0.1
+    zvvmttls             0.1
     zvzip                0.1
     smpmpmt              0.6
     svukte               0.3

>From 0287a01dea821c0ceda27fc5ae80be27ccc414d8 Mon Sep 17 00:00:00 2001
From: imkiva <[email protected]>
Date: Tue, 19 May 2026 16:30:53 +0800
Subject: [PATCH 5/8] Review

---
 llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp |  8 +++-----
 llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td        | 11 ++---------
 2 files changed, 5 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp 
b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 63e36cd1665f6..5b78b5ce089e5 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2559,7 +2559,7 @@ ParseStatus RISCVAsmParser::parseMaskReg(OperandVector 
&Operands) {
   StringRef Name = getLexer().getTok().getIdentifier();
   if (!Name.consume_back(".t")) {
     // Non-register identifiers may belong to another optional operand in an
-    // overloaded mnemnoic. Let the matcher try those alternatives.
+    // overloaded mnemonic. Let the matcher try those alternatives.
     if (matchRegisterNameHelper(Name))
       return Error(getLoc(), "expected '.t' suffix");
     return ParseStatus::NoMatch;
@@ -2607,10 +2607,8 @@ ParseStatus 
RISCVAsmParser::parseTileLambda(OperandVector &Operands) {
     return ParseStatus::NoMatch;
 
   unsigned Lambda;
-  if (Name.getAsInteger(10, Lambda))
-    return Error(S, "operand must be L1, L2, L4, L8, L16, L32, or L64");
-
-  if (!isPowerOf2_32(Lambda) || Lambda >= 128)
+  if (Name.getAsInteger(10, Lambda) || !isPowerOf2_32(Lambda) ||
+      Lambda >= 128)
     return Error(S, "operand must be L1, L2, L4, L8, L16, L32, or L64");
 
   unsigned EncodedLambda = Log2_32(Lambda) + 1;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
index 23e69eaf7a24b..a630eb1d35deb 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
@@ -28,14 +28,8 @@ def TileLambdaOp : RISCVOp {
   let ParserMatchClass = TileLambdaAsmOperand;
   let PrintMethod = "printTileLambda";
   let EncoderMethod = "getImmOpValue";
-  let DecoderMethod = "decodeUImmOperand<3>";
+  let DecoderMethod = "decodeUImmNonZeroOperand<3>";
   let OperandType = "OPERAND_UIMM3";
-  let MCOperandPredicate = [{
-    int64_t Imm;
-    if (!MCOp.evaluateAsConstantImm(Imm))
-      return false;
-    return Imm && isUInt<3>(Imm);
-  }];
 }
 
 def VScaleAsmOperand : AsmOperandClass {
@@ -84,8 +78,7 @@ class VTileLoadBase<bits<2> mop, dag ins, string opcodestr, 
string argstr>
 }
 
 class VTileStoreBase<bits<2> mop, dag ins, string opcodestr, string argstr>
-    : RVInst<(outs),
-             ins, opcodestr, argstr, [], InstFormatR> {
+    : RVInst<(outs), ins, opcodestr, argstr, [], InstFormatR> {
   bits<5> vs3;
   bits<5> rs1;
   bits<5> rs2;

>From 2d63096f9cc6e7f88deeffebcdf22ee3c356c6cc Mon Sep 17 00:00:00 2001
From: imkiva <[email protected]>
Date: Tue, 19 May 2026 16:35:45 +0800
Subject: [PATCH 6/8] Format

---
 llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp 
b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 5b78b5ce089e5..373a520fa2f7e 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2607,8 +2607,7 @@ ParseStatus RISCVAsmParser::parseTileLambda(OperandVector 
&Operands) {
     return ParseStatus::NoMatch;
 
   unsigned Lambda;
-  if (Name.getAsInteger(10, Lambda) || !isPowerOf2_32(Lambda) ||
-      Lambda >= 128)
+  if (Name.getAsInteger(10, Lambda) || !isPowerOf2_32(Lambda) || Lambda >= 128)
     return Error(S, "operand must be L1, L2, L4, L8, L16, L32, or L64");
 
   unsigned EncodedLambda = Log2_32(Lambda) + 1;

>From 19e38a3d70bffc34815812cfd2179c147443716f Mon Sep 17 00:00:00 2001
From: imkiva <[email protected]>
Date: Tue, 2 Jun 2026 12:05:47 +0800
Subject: [PATCH 7/8] Add OPERAND_UIMM3_NONZERO

---
 llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 1 +
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp           | 3 +++
 llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td        | 2 +-
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h 
b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 7f1aa83075f1f..f5773083ee367 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -32,6 +32,7 @@ enum OperandType : unsigned {
   OPERAND_UIMM2,
   OPERAND_UIMM2_LSB0,
   OPERAND_UIMM3,
+  OPERAND_UIMM3_NONZERO,
   OPERAND_UIMM4,
   OPERAND_UIMM4_PLUS1,
   OPERAND_UIMM5,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp 
b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index c622d188c67a1..cbb4d1d16a038 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3030,6 +3030,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr 
&MI,
         CASE_OPERAND_UIMM_LSB_ZEROS(8, 000)
         CASE_OPERAND_UIMM_LSB_ZEROS(9, 000)
         // clang-format on
+        case RISCVOp::OPERAND_UIMM3_NONZERO:
+          Ok = isUInt<3>(Imm) && (Imm != 0);
+          break;
         case RISCVOp::OPERAND_UIMM5_NONZERO:
           Ok = isUInt<5>(Imm) && (Imm != 0);
           break;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
index a630eb1d35deb..5f63d33e819bc 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
@@ -29,7 +29,7 @@ def TileLambdaOp : RISCVOp {
   let PrintMethod = "printTileLambda";
   let EncoderMethod = "getImmOpValue";
   let DecoderMethod = "decodeUImmNonZeroOperand<3>";
-  let OperandType = "OPERAND_UIMM3";
+  let OperandType = "OPERAND_UIMM3_NONZERO";
 }
 
 def VScaleAsmOperand : AsmOperandClass {

>From 5588da74a4067637c91d170da04a050b5a6cf075 Mon Sep 17 00:00:00 2001
From: imkiva <[email protected]>
Date: Tue, 2 Jun 2026 20:32:52 +0800
Subject: [PATCH 8/8] Support lowercase lambda tile

---
 llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp |  2 +-
 llvm/test/MC/RISCV/rvv/zvvmtls.s                   | 10 ++++++++++
 llvm/test/MC/RISCV/rvv/zvvmttls.s                  | 10 ++++++++++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp 
b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 373a520fa2f7e..79ddd1ac9fe7f 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2603,7 +2603,7 @@ ParseStatus RISCVAsmParser::parseTileLambda(OperandVector 
&Operands) {
 
   SMLoc S = getLoc();
   StringRef Name = getLexer().getTok().getIdentifier();
-  if (!Name.consume_front("L"))
+  if (!Name.consume_front("L") && !Name.consume_front("l"))
     return ParseStatus::NoMatch;
 
   unsigned Lambda;
diff --git a/llvm/test/MC/RISCV/rvv/zvvmtls.s b/llvm/test/MC/RISCV/rvv/zvvmtls.s
index be00fa314dea2..54a91f6a4d25e 100644
--- a/llvm/test/MC/RISCV/rvv/zvvmtls.s
+++ b/llvm/test/MC/RISCV/rvv/zvvmtls.s
@@ -16,6 +16,11 @@ vmtl.v v8, (a0), a1, L4
 # CHECK-ENCODING: [0x07,0x74,0xb5,0x72]
 # CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
 
+vmtl.v v8, (a0), a1, l2
+# CHECK-INST: vmtl.v v8, (a0), a1, L2
+# CHECK-ENCODING: [0x07,0x74,0xb5,0x52]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
+
 vmtl.v v8, (a0), a1, v0.t
 # CHECK-INST: vmtl.v v8, (a0), a1, v0.t
 # CHECK-ENCODING: [0x07,0x74,0xb5,0x10]
@@ -51,6 +56,11 @@ vmts.v v12, (a0), a1, L4, v0.t
 # CHECK-ENCODING: [0x27,0x76,0xb5,0x70]
 # CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
 
+vmts.v v12, (a0), a1, l2, v0.t
+# CHECK-INST: vmts.v v12, (a0), a1, L2, v0.t
+# CHECK-ENCODING: [0x27,0x76,0xb5,0x50]
+# CHECK-ERROR: instruction requires the following: 'Zvvmtls' (Matrix Tile 
Load/Store){{$}}
+
 vmts.v v12, (a0), zero, L64, v0.t
 # CHECK-INST: vmts.v v12, (a0), zero, L64, v0.t
 # CHECK-ENCODING: [0x27,0x76,0x05,0xf0]
diff --git a/llvm/test/MC/RISCV/rvv/zvvmttls.s 
b/llvm/test/MC/RISCV/rvv/zvvmttls.s
index 07c6b1cbce243..68a47844ee56f 100644
--- a/llvm/test/MC/RISCV/rvv/zvvmttls.s
+++ b/llvm/test/MC/RISCV/rvv/zvvmttls.s
@@ -16,6 +16,11 @@ vmttl.v v8, (a0), a1, L4
 # CHECK-ENCODING: [0x07,0x74,0xb5,0x76]
 # CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
 
+vmttl.v v8, (a0), a1, l2
+# CHECK-INST: vmttl.v v8, (a0), a1, L2
+# CHECK-ENCODING: [0x07,0x74,0xb5,0x56]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
+
 vmttl.v v8, (a0), a1, v0.t
 # CHECK-INST: vmttl.v v8, (a0), a1, v0.t
 # CHECK-ENCODING: [0x07,0x74,0xb5,0x14]
@@ -51,6 +56,11 @@ vmtts.v v12, (a0), a1, L4, v0.t
 # CHECK-ENCODING: [0x27,0x76,0xb5,0x74]
 # CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
 
+vmtts.v v12, (a0), a1, l2, v0.t
+# CHECK-INST: vmtts.v v12, (a0), a1, L2, v0.t
+# CHECK-ENCODING: [0x27,0x76,0xb5,0x54]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing 
Matrix Tile Load/Store){{$}}
+
 vmtts.v v12, (a0), zero, L64, v0.t
 # CHECK-INST: vmtts.v v12, (a0), zero, L64, v0.t
 # CHECK-ENCODING: [0x27,0x76,0x05,0xf4]

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to