https://github.com/imkiva updated https://github.com/llvm/llvm-project/pull/198229
>From 352454dca6b6359edee846c8e5910bfc8ce0da10 Mon Sep 17 00:00:00 2001 From: imkiva <[email protected]> Date: Mon, 18 May 2026 12:24:55 +0800 Subject: [PATCH 1/7] [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 | 18 ++- 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(+), 5 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 82ef3e54dab29..f9a19fca60f18 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -256,6 +256,8 @@ // CHECK-NEXT: zvkgs 0.7 'Zvkgs' (Vector-Scalar GCM instructions for Cryptography) // 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 71d91f73383b5..cc40f5fbea586 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>`__. To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using. To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`. Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`. diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 2e3f6146789b4..1421b35d20be3 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -206,6 +206,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. ### Changes to the WebAssembly Backend diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 1b2742c76da05..402c6e5c7f43e 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); @@ -639,6 +640,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; } @@ -2508,8 +2513,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) @@ -2543,6 +2553,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 e2416f832aecc..fa04f7537e256 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp @@ -352,6 +352,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 199ac77bef72f..6ef71489f134e 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -906,6 +906,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)">; + // Vector instruction predicates def HasVInstructions : Predicate<"Subtarget->hasVInstructions()">, @@ -2085,4 +2102,3 @@ def TuneSiFive7 : SubtargetFeature<"sifive7", "RISCVProcFamily", "SiFive7", def TuneVentanaVeyron : SubtargetFeature<"ventana-veyron", "RISCVProcFamily", "VentanaVeyron", "Ventana Veyron-Series processors">; - 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 96f193a2633f5..8c279d53fb7f4 100644 --- a/llvm/test/CodeGen/RISCV/features-info.ll +++ b/llvm/test/CodeGen/RISCV/features-info.ll @@ -41,6 +41,8 @@ ; CHECK-NEXT: experimental-zvkgs - 'Zvkgs' (Vector-Scalar GCM instructions for Cryptography). ; 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 26406fe846213c59a3461261bf1c1ec1c341aa83 Mon Sep 17 00:00:00 2001 From: imkiva <[email protected]> Date: Mon, 18 May 2026 12:42:13 +0800 Subject: [PATCH 2/7] 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 cc40f5fbea586..77f42360058f1 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>`__. To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using. To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`. Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`. >From 13d3f1ce968cc0e61eba55adf45ddd5a54cdf88e Mon Sep 17 00:00:00 2001 From: imkiva <[email protected]> Date: Mon, 18 May 2026 12:45:13 +0800 Subject: [PATCH 3/7] 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 339d3ccce0898b2942f1998ff843bfc948359f8a Mon Sep 17 00:00:00 2001 From: imkiva <[email protected]> Date: Mon, 18 May 2026 14:52:33 +0800 Subject: [PATCH 4/7] 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 402c6e5c7f43e..7d71136523013 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -641,7 +641,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. @@ -2566,32 +2566,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 cd0dcf98f50de..475658c43da0b 100644 --- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp @@ -1387,6 +1387,8 @@ Experimental extensions zvkgs 0.7 zvvfmm 0.1 zvvmm 0.1 + zvvmtls 0.1 + zvvmttls 0.1 zvzip 0.1 smpmpmt 0.6 svukte 0.3 >From 60b3806fb0e4a2c1fbc29cedd64911d0b47cfd8f Mon Sep 17 00:00:00 2001 From: imkiva <[email protected]> Date: Tue, 19 May 2026 16:30:53 +0800 Subject: [PATCH 5/7] 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 7d71136523013..aa61e6557e02b 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -2515,7 +2515,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; @@ -2563,10 +2563,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 575e5f3499a4f09751e3f4a8f663e3cb140d4b70 Mon Sep 17 00:00:00 2001 From: imkiva <[email protected]> Date: Tue, 19 May 2026 16:35:45 +0800 Subject: [PATCH 6/7] 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 aa61e6557e02b..2830737d1be0d 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -2563,8 +2563,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 eb9893c74ff8e4e42a7fcb3b5f888a92019217d3 Mon Sep 17 00:00:00 2001 From: imkiva <[email protected]> Date: Tue, 2 Jun 2026 12:05:47 +0800 Subject: [PATCH 7/7] 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 b5aade96d4093..e38c0d239eb59 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 f2cfee8477883..82868af26ba62 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 { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
