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/9] [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/9] 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/9] 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/9] 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/9] 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/9] 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/9] 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/9] 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] >From c3fbb7f731f29dc992e6f83ce09132c3f7683564 Mon Sep 17 00:00:00 2001 From: imkiva <[email protected]> Date: Thu, 4 Jun 2026 20:24:55 +0800 Subject: [PATCH 9/9] Use InstAlias with EmitPriority=0 to handle optional lambda tile --- .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 1 - llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 3 -- llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td | 34 ++++++++----------- 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index f5773083ee367..7f1aa83075f1f 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -32,7 +32,6 @@ 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 cbb4d1d16a038..c622d188c67a1 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -3030,9 +3030,6 @@ 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 5f63d33e819bc..067a9c0e404d4 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td @@ -28,8 +28,8 @@ def TileLambdaOp : RISCVOp { let ParserMatchClass = TileLambdaAsmOperand; let PrintMethod = "printTileLambda"; let EncoderMethod = "getImmOpValue"; - let DecoderMethod = "decodeUImmNonZeroOperand<3>"; - let OperandType = "OPERAND_UIMM3_NONZERO"; + let DecoderMethod = "decodeUImmOperand<3>"; + let OperandType = "OPERAND_UIMM3"; } def VScaleAsmOperand : AsmOperandClass { @@ -103,25 +103,11 @@ class VTileStoreBase<bits<2> mop, dag ins, string opcodestr, string argstr> } 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), @@ -207,15 +193,23 @@ let Predicates = [HasStdExtZvvfmm] in { } // Predicates = [HasStdExtZvvfmm] let Predicates = [HasStdExtZvvmtls] in { - 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">; + 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_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">; + 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] _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
