[clang] 0f18088 - [RISCV][MC] Add experimental `Zvvmtls` and `Zvvmttls` support (#198229)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 5 01:10:39 PDT 2026
Author: Kiva
Date: 2026-06-05T16:10:34+08:00
New Revision: 0f18088dca8aa03124cac4d174e97174a9aa35be
URL: https://github.com/llvm/llvm-project/commit/0f18088dca8aa03124cac4d174e97174a9aa35be
DIFF: https://github.com/llvm/llvm-project/commit/0f18088dca8aa03124cac4d174e97174a9aa35be.diff
LOG: [RISCV][MC] Add experimental `Zvvmtls` and `Zvvmttls` support (#198229)
This patch adds experimental MC-layer support for the [RISC-V Integrated
Matrix
Extension](https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-71c48b9-2026-05-17),
specifically the tile load/store extensions: `Zvvmtls` and `Zvvmttls`
This PR:
- Adds the optional tile lambda operand syntax (`L1` through `L64`), and
related asm operand.
- Adds the `vmtl.v`, `vmts.v`, `vmttl.v` and `vmtts.v` instructions to
the MC
- Modifies `parseMaskReg` to return `NoMatch` to allow overloaded
mnemonics to continue matching alternative optional operands, such as
parsing `vmtl.v v8, (a0), a1, L4` as the tile-lambda form instead of
failing by treating `L4` as a malformed mask operand. Real mask
registers missing .t, such as v0, still produce the existing diagnostic.
Added:
llvm/test/MC/RISCV/rvv/zvvmtls-invalid.s
llvm/test/MC/RISCV/rvv/zvvmtls.s
llvm/test/MC/RISCV/rvv/zvvmttls-invalid.s
llvm/test/MC/RISCV/rvv/zvvmttls.s
Modified:
clang/test/Driver/print-supported-extensions-riscv.c
llvm/docs/RISCVUsage.rst
llvm/docs/ReleaseNotes.md
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
llvm/lib/Target/RISCV/RISCVFeatures.td
llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
llvm/test/CodeGen/RISCV/features-info.ll
llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
Removed:
################################################################################
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 4254009e0fa86..34c651891538d 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -265,6 +265,8 @@
// CHECK-NEXT: zvqwdota8i 0.2 'Zvqwdota8i' (8-bit Integer Dot-Product)
// 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 058a931ebe318..13d5f521246ee 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
@@ -367,10 +371,16 @@ 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``
+ 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``
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 19d51ce17355e..e3d9b38d1370c 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -236,6 +236,8 @@ Makes programs 10x faster by doing Special New Thing.
* Support for the experimental `XRivosVizip` 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 35438250a78dc..49ebce6508673 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);
@@ -655,6 +656,10 @@ struct RISCVOperand final : public MCParsedAsmOperand {
return Kind == KindTy::VType && RISCVVType::isValidXSfmmVType(VType.Val);
}
+ bool isTileLambda() const {
+ return isUImmPred([](int64_t Imm) { return Imm && isUInt<3>(Imm); });
+ }
+
/// Return true if the operand is a valid for the fence instruction e.g.
/// ('iorw').
bool isFenceArg() const { return Kind == KindTy::Fence; }
@@ -2541,8 +2546,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 mnemonic. Let the matcher try those alternatives.
+ if (matchRegisterNameHelper(Name))
+ return Error(getLoc(), "expected '.t' suffix");
+ return ParseStatus::NoMatch;
+ }
MCRegister Reg = matchRegisterNameHelper(Name);
if (!Reg)
@@ -2576,6 +2586,28 @@ 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") && !Name.consume_front("l"))
+ return ParseStatus::NoMatch;
+
+ unsigned Lambda;
+ 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;
+
+ 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 455c4676cf2eb..6b2a2f48c3f65 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -361,6 +361,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 f3e6e69e5e0e9..4025b39401b2b 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -927,6 +927,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..067a9c0e404d4 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
@@ -16,6 +16,22 @@
// 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";
+}
+
def VScaleAsmOperand : AsmOperandClass {
let Name = "RVVScaleRegOpOperand";
let RenderMethod = "addRegOperands";
@@ -34,14 +50,78 @@ 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 = true;
+ let mayStore = false;
+ let hasSideEffects = false;
+ 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 = false;
+ let mayStore = true;
+ let hasSideEffects = false;
+ let Uses = [VL, VTYPE];
+ let UseNamedOperandTable = true;
+}
+
+class VTileLoad<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,
+ 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,
"$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;
let VMConstraint = false;
}
@@ -50,9 +130,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;
@@ -64,9 +144,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;
@@ -78,9 +158,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;
@@ -111,3 +191,25 @@ 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 : VTileLoad<0b00, "vmtl.v">;
+ def VMTS_V : VTileStore<0b00, "vmts.v">;
+ def : InstAlias<"vmtl.v $vd, $rs1, $rs2$vm",
+ (VMTL_V VR:$vd, GPRMemZeroOffset:$rs1, GPR:$rs2, 0,
+ VMaskOp:$vm), 0>;
+ def : InstAlias<"vmts.v $vs3, $rs1, $rs2$vm",
+ (VMTS_V VR:$vs3, GPRMemZeroOffset:$rs1, GPR:$rs2, 0,
+ VMaskOp:$vm), 0>;
+} // Predicates = [HasStdExtZvvmtls]
+
+let Predicates = [HasStdExtZvvmttls] in {
+ def VMTTL_V : VTileLoad<0b01, "vmttl.v">;
+ def VMTTS_V : VTileStore<0b01, "vmtts.v">;
+ def : InstAlias<"vmttl.v $vd, $rs1, $rs2$vm",
+ (VMTTL_V VR:$vd, GPRMemZeroOffset:$rs1, GPR:$rs2, 0,
+ VMaskOp:$vm), 0>;
+ def : InstAlias<"vmtts.v $vs3, $rs1, $rs2$vm",
+ (VMTTS_V VR:$vs3, GPRMemZeroOffset:$rs1, GPR:$rs2, 0,
+ VMaskOp:$vm), 0>;
+} // Predicates = [HasStdExtZvvmttls]
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 3d5e08a1f565c..8abe64b8ecda4 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -50,6 +50,8 @@
; CHECK-NEXT: experimental-zvqwdota8i - 'Zvqwdota8i' (8-bit Integer Dot-Product).
; 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..54a91f6a4d25e
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvvmtls.s
@@ -0,0 +1,67 @@
+# 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, 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]
+# 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), 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]
+# 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..68a47844ee56f
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvvmttls.s
@@ -0,0 +1,67 @@
+# 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, 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]
+# 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), 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]
+# CHECK-ERROR: instruction requires the following: 'Zvvmttls' (Transposing Matrix Tile Load/Store){{$}}
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index feaea1f484e36..851685d5f68d1 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1401,6 +1401,8 @@ Experimental extensions
zvqwdota8i 0.2
zvvfmm 0.1
zvvmm 0.1
+ zvvmtls 0.1
+ zvvmttls 0.1
zvzip 0.1
smpmpmt 0.6
svukte 0.3
More information about the cfe-commits
mailing list