https://github.com/imkiva updated https://github.com/llvm/llvm-project/pull/196486
>From 3ad3df42706cf787489ced8d9c1a09cdf4a10ad4 Mon Sep 17 00:00:00 2001 From: imkiva <[email protected]> Date: Sat, 9 May 2026 14:11:34 +0800 Subject: [PATCH] [RISCV][MC] Add experimental Zvvfmm support --- .../Driver/print-supported-extensions-riscv.c | 1 + llvm/docs/RISCVUsage.rst | 5 +- llvm/docs/ReleaseNotes.md | 1 + .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 59 ++++++++++++ .../RISCV/MCTargetDesc/RISCVInstPrinter.cpp | 11 +++ .../RISCV/MCTargetDesc/RISCVInstPrinter.h | 2 + llvm/lib/Target/RISCV/RISCVFeatures.td | 9 ++ llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td | 84 +++++++++++++++- llvm/test/CodeGen/RISCV/features-info.ll | 1 + .../MC/RISCV/rvv/zvvfmm-invalid-encoding.s | 9 ++ llvm/test/MC/RISCV/rvv/zvvfmm-invalid.s | 95 +++++++++++++++++++ llvm/test/MC/RISCV/rvv/zvvfmm.s | 57 +++++++++++ .../TargetParser/RISCVISAInfoTest.cpp | 1 + 13 files changed, 330 insertions(+), 5 deletions(-) create mode 100644 llvm/test/MC/RISCV/rvv/zvvfmm-invalid-encoding.s create mode 100644 llvm/test/MC/RISCV/rvv/zvvfmm-invalid.s create mode 100644 llvm/test/MC/RISCV/rvv/zvvfmm.s diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index d0a773f8f43d8..82ef3e54dab29 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -254,6 +254,7 @@ // CHECK-NEXT: zvfbfa 0.1 'Zvfbfa' (Additional BF16 vector compute support) // CHECK-NEXT: zvfofp8min 0.2 'Zvfofp8min' (Vector OFP8 Converts) // 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: zvzip 0.1 'Zvzip' (Vector Reordering Structured Data) // CHECK-NEXT: smpmpmt 0.6 'Smpmpmt' (PMP-based Memory Types Extension) diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index 2b68827e7b136..71d91f73383b5 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -363,8 +363,11 @@ The primary goal of experimental support is to assist in the process of ratifica ``experimental-zvzip`` 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>`__. + ``experimental-zvvmm`` - LLVM implements the `0.1 draft specification <https://github.com/riscv/integrated-matrix-extension/blob/d2e64b4922f5c2c416761f3c7c997d4f0cf814d9/src/integrated-matrix.adoc>`__. + LLVM implements the `0.1 draft specification <https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-fa55752-2026-05-04>`__. 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 98f2205bc06a7..c4ca9f882f1ba 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -203,6 +203,7 @@ 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 support for 'Ziccid' (Instruction/Data Coherence and Consistency) extension. +* Adds experimental assembler support for the 'Zvvfmm` (RISC-V Floating-Point Matrix Multiply-Accumulate) 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 cbf3d0f518ac8..1b2742c76da05 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -206,6 +206,7 @@ class RISCVAsmParser : public MCTargetAsmParser { ParseStatus parseJALOffset(OperandVector &Operands); ParseStatus parseVTypeI(OperandVector &Operands); ParseStatus parseMaskReg(OperandVector &Operands); + ParseStatus parseVScaleReg(OperandVector &Operands); ParseStatus parseInsnDirectiveOpcode(OperandVector &Operands); ParseStatus parseInsnCDirectiveOpcode(OperandVector &Operands); ParseStatus parseGPRAsFPR(OperandVector &Operands); @@ -2522,6 +2523,26 @@ ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) { return ParseStatus::Success; } +ParseStatus RISCVAsmParser::parseVScaleReg(OperandVector &Operands) { + if (getLexer().isNot(AsmToken::Identifier)) + return ParseStatus::NoMatch; + + StringRef Name = getLexer().getTok().getIdentifier(); + if (!Name.consume_back(".scale")) + return Error(getLoc(), "expected '.scale' suffix"); + MCRegister Reg = matchRegisterNameHelper(Name); + + if (!Reg) + return ParseStatus::NoMatch; + if (Reg != RISCV::V0) + return ParseStatus::NoMatch; + SMLoc S = getLoc(); + SMLoc E = getTok().getEndLoc(); + getLexer().Lex(); + Operands.push_back(RISCVOperand::createReg(Reg, S, E)); + return ParseStatus::Success; +} + ParseStatus RISCVAsmParser::parseGPRAsFPR64(OperandVector &Operands) { if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF)) return ParseStatus::NoMatch; @@ -3903,6 +3924,20 @@ unsigned getLMULFromVectorRegister(MCRegister Reg) { return 1; } +static bool isZvvfmmScaleOpcode(unsigned Opcode) { + switch (Opcode) { + case RISCV::VFWMMACC_VV_SCALE: + case RISCV::VFQMMACC_VV_SCALE: + case RISCV::VF8WMMACC_VV_SCALE: + case RISCV::VFWIMMACC_VV: + case RISCV::VFQIMMACC_VV: + case RISCV::VF8WIMMACC_VV: + return true; + default: + return false; + } +} + bool RISCVAsmParser::validateInstruction(MCInst &Inst, OperandVector &Operands) { unsigned Opcode = Inst.getOpcode(); @@ -3939,6 +3974,30 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst, } } + if (isZvvfmmScaleOpcode(Opcode)) { + auto CheckOperandDoesNotOverlapV0 = [&](int OperandIdx, + unsigned ParsedIdx) { + if (Inst.getOperand(OperandIdx).getReg() == RISCV::V0) + return Error(Operands[ParsedIdx]->getStartLoc(), + "vd, vs1, and vs2 cannot overlap v0.scale"); + return false; + }; + + int DestIdx = + RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::vd); + int VS1Idx = + RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::vs1); + int VS2Idx = + RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::vs2); + assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 && + "Unexpected Zvvfmm scaled operand list"); + + if (CheckOperandDoesNotOverlapV0(DestIdx, 1) || + CheckOperandDoesNotOverlapV0(VS1Idx, 2) || + CheckOperandDoesNotOverlapV0(VS2Idx, 3)) + return true; + } + const MCInstrDesc &MCID = MII.get(Opcode); if (!(MCID.TSFlags & RISCVII::RVVConstraintMask)) return false; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp index b381b8f7147fc..e2416f832aecc 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp @@ -341,6 +341,17 @@ void RISCVInstPrinter::printVMaskReg(const MCInst *MI, unsigned OpNo, O << ".t"; } +void RISCVInstPrinter::printVScaleReg(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNo); + + assert(MO.isReg() && "printVScaleReg can only print register operands"); + O << ", "; + printRegName(O, MO.getReg()); + O << ".scale"; +} + 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 17469bd87e34e..fb0598faff2be 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h @@ -52,6 +52,8 @@ class RISCVInstPrinter : public MCInstPrinter { const MCSubtargetInfo &STI, raw_ostream &O); void printVMaskReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); + void printVScaleReg(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 a92fb63e3c3cd..199ac77bef72f 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -897,6 +897,15 @@ def HasStdExtZvvmm : Predicate<"Subtarget->hasStdExtZvvmm()">, AssemblerPredicate<(all_of FeatureStdExtZvvmm), "'Zvvmm' (Integer Matrix Multiply-Accumulate)">; +// Integrated Matrix Extension floating-point matrix multiply-accumulate +def FeatureStdExtZvvfmm + : RISCVExperimentalExtension<0, 1, + "Floating-Point Matrix Multiply-Accumulate", + [FeatureStdExtZve32f]>; +def HasStdExtZvvfmm : Predicate<"Subtarget->hasStdExtZvvfmm()">, + AssemblerPredicate<(all_of FeatureStdExtZvvfmm), + "'Zvvfmm' (Floating-Point Matrix Multiply-Accumulate)">; + // Vector instruction predicates def HasVInstructions : Predicate<"Subtarget->hasVInstructions()">, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td index d7620bf072ac3..0a358ba9ba0bb 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td @@ -6,10 +6,9 @@ // //===----------------------------------------------------------------------===// // -// This file describes the RISC-V instructions from the standard 'Zvvmm' -// extension for integer matrix multiply-accumulate. -// This version is still experimental as the 'Zvvmm' extension hasn't been -// ratified yet. +// This file describes the RISC-V instructions from the standard 'Zvvm' family +// of Integrated Matrix extensions. +// These extensions are still experimental as they haven't been ratified yet. // //===----------------------------------------------------------------------===// @@ -17,6 +16,24 @@ // Instructions //===----------------------------------------------------------------------===// +def VScaleAsmOperand : AsmOperandClass { + let Name = "RVVScaleRegOpOperand"; + let RenderMethod = "addRegOperands"; + let PredicateMethod = "isV0Reg"; + let ParserMethod = "parseVScaleReg"; + let DiagnosticType = "InvalidVScaleRegister"; + let DiagnosticString = "operand must be v0.scale"; +} + +// An always present v0.scale operand encoded with vm=0. Classes that use this +// must set the vm field in RVInstV* to 0. +def VScaleOp : RegisterOperand<VMV0> { + let ParserMatchClass = VScaleAsmOperand; + let PrintMethod = "printVScaleReg"; + let EncoderMethod = "getVMaskReg"; + let DecoderMethod = "decodeVMaskReg"; +} + class VIMEMACVV<bits<6> funct6, string opcodestr> : RVInstVV<funct6, OPIVV, (outs VR:$vd_wb), (ins VR:$vd, VR:$vs1, VR:$vs2), opcodestr, @@ -29,9 +46,68 @@ class VIMEMACVV<bits<6> funct6, string opcodestr> let VMConstraint = false; } +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 Constraints = "$vd = $vd_wb"; + let Uses = [FRM, VL, VTYPE]; + let mayRaiseFPException = true; + let vm = 1; + let VMConstraint = false; +} + +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 Constraints = "$vd = $vd_wb"; + let Uses = [FRM, VL, VTYPE]; + let mayRaiseFPException = true; + let vm = 0; + let VMConstraint = false; +} + +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 Constraints = "$vd = $vd_wb"; + let Uses = [FRM, VL, VTYPE]; + let mayRaiseFPException = true; + let vm = 0; + let VMConstraint = false; +} + let Predicates = [HasStdExtZvvmm] in { def VMMACC_VV : VIMEMACVV<0b111000, "vmmacc.vv">; def VWMMACC_VV : VIMEMACVV<0b111001, "vwmmacc.vv">; def VQMMACC_VV : VIMEMACVV<0b111010, "vqmmacc.vv">; def V8WMMACC_VV : VIMEMACVV<0b111011, "v8wmmacc.vv">; } // Predicates = [HasStdExtZvvmm] + +let Predicates = [HasStdExtZvvfmm] in { + def VFMMACC_VV : VFMEMACVV<0b010100, "vfmmacc.vv">; + def VFWMMACC_VV : VFMEMACVV<0b010101, "vfwmmacc.vv">; + def VFQMMACC_VV : VFMEMACVV<0b010110, "vfqmmacc.vv">; + def VF8WMMACC_VV : VFMEMACVV<0b010111, "vf8wmmacc.vv">; + def VFWMMACC_VV_SCALE : VFMEMACScaleVV<0b010101, "vfwmmacc.vv">; + def VFQMMACC_VV_SCALE : VFMEMACScaleVV<0b010110, "vfqmmacc.vv">; + def VF8WMMACC_VV_SCALE : VFMEMACScaleVV<0b010111, "vf8wmmacc.vv">; + // FIXME: The integer-input MX forms should be gated by the + // Zvvxi*/Zvvxni* microscaling extensions once LLVM models those + // individual extension names. They are temporarily enabled under + // experimental-zvvfmm for MC bring-up. + def VFWIMMACC_VV : VIFMEMACScaleVV<0b111001, "vfwimmacc.vv">; + def VFQIMMACC_VV : VIFMEMACScaleVV<0b111010, "vfqimmacc.vv">; + def VF8WIMMACC_VV : VIFMEMACScaleVV<0b111011, "vf8wimmacc.vv">; +} // Predicates = [HasStdExtZvvfmm] diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll index d4b920c08a096..96f193a2633f5 100644 --- a/llvm/test/CodeGen/RISCV/features-info.ll +++ b/llvm/test/CodeGen/RISCV/features-info.ll @@ -39,6 +39,7 @@ ; CHECK-NEXT: experimental-zvfbfa - 'Zvfbfa' (Additional BF16 vector compute support). ; CHECK-NEXT: experimental-zvfofp8min - 'Zvfofp8min' (Vector OFP8 Converts). ; 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-zvzip - 'Zvzip' (Vector Reordering Structured Data). ; CHECK-NEXT: f - 'F' (Single-Precision Floating-Point). diff --git a/llvm/test/MC/RISCV/rvv/zvvfmm-invalid-encoding.s b/llvm/test/MC/RISCV/rvv/zvvfmm-invalid-encoding.s new file mode 100644 index 0000000000000..239153b62c233 --- /dev/null +++ b/llvm/test/MC/RISCV/rvv/zvvfmm-invalid-encoding.s @@ -0,0 +1,9 @@ +# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+experimental-zvvfmm %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zvvfmm - \ +# RUN: | FileCheck %s + +# vm=0 is reserved for non-widening vfmmacc.vv, so this raw encoding must not +# decode as a scaled vfmmacc form. +.insn 0x4, 0x51421457 +# CHECK: <unknown> +# CHECK-NOT: vfmmacc.vv diff --git a/llvm/test/MC/RISCV/rvv/zvvfmm-invalid.s b/llvm/test/MC/RISCV/rvv/zvvfmm-invalid.s new file mode 100644 index 0000000000000..ccb1e7ebcd12d --- /dev/null +++ b/llvm/test/MC/RISCV/rvv/zvvfmm-invalid.s @@ -0,0 +1,95 @@ +# RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-zvvfmm %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-ERROR + +vfmmacc.vv v8, v4, v20, v0.t +# CHECK-ERROR: invalid operand for instruction +# CHECK-ERROR-LABEL: vfmmacc.vv v8, v4, v20, v0.t + +# vm=0 is reserved for non-widening vfmmacc.vv. +vfmmacc.vv v8, v4, v20, v0.scale +# CHECK-ERROR: invalid operand for instruction +# CHECK-ERROR-LABEL: vfmmacc.vv v8, v4, v20, v0.scale + +vfwmmacc.vv v8, v4, v20, v0.t +# CHECK-ERROR: expected '.scale' suffix +# CHECK-ERROR-LABEL: vfwmmacc.vv v8, v4, v20, v0.t + +vfwmmacc.vv v8, v4, v20, v1.scale +# CHECK-ERROR: operand must be v0.scale +# CHECK-ERROR-LABEL: vfwmmacc.vv v8, v4, v20, v1.scale + +vfqmmacc.vv v8, v4, v20, v0.t +# CHECK-ERROR: expected '.scale' suffix +# CHECK-ERROR-LABEL: vfqmmacc.vv v8, v4, v20, v0.t + +vfqmmacc.vv v8, v4, v20, v1.scale +# CHECK-ERROR: operand must be v0.scale +# CHECK-ERROR-LABEL: vfqmmacc.vv v8, v4, v20, v1.scale + +vf8wmmacc.vv v8, v4, v20, v0.t +# CHECK-ERROR: expected '.scale' suffix +# CHECK-ERROR-LABEL: vf8wmmacc.vv v8, v4, v20, v0.t + +vf8wmmacc.vv v8, v4, v20, v1.scale +# CHECK-ERROR: operand must be v0.scale +# CHECK-ERROR-LABEL: vf8wmmacc.vv v8, v4, v20, v1.scale + +vfwmmacc.vv v0, v4, v20, v0.scale +# CHECK-ERROR: vd, vs1, and vs2 cannot overlap v0.scale +# CHECK-ERROR-LABEL: vfwmmacc.vv v0, v4, v20, v0.scale + +vfqmmacc.vv v8, v0, v20, v0.scale +# CHECK-ERROR: vd, vs1, and vs2 cannot overlap v0.scale +# CHECK-ERROR-LABEL: vfqmmacc.vv v8, v0, v20, v0.scale + +vf8wmmacc.vv v8, v4, v0, v0.scale +# CHECK-ERROR: vd, vs1, and vs2 cannot overlap v0.scale +# CHECK-ERROR-LABEL: vf8wmmacc.vv v8, v4, v0, v0.scale + +vfwimmacc.vv v8, v4, v20 +# CHECK-ERROR: too few operands for instruction +# CHECK-ERROR-LABEL: vfwimmacc.vv v8, v4, v20 + +vfwimmacc.vv v8, v4, v20, v0.t +# CHECK-ERROR: expected '.scale' suffix +# CHECK-ERROR-LABEL: vfwimmacc.vv v8, v4, v20, v0.t + +vfwimmacc.vv v8, v4, v20, v1.scale +# CHECK-ERROR: operand must be v0.scale +# CHECK-ERROR-LABEL: vfwimmacc.vv v8, v4, v20, v1.scale + +vfwimmacc.vv v0, v4, v20, v0.scale +# CHECK-ERROR: vd, vs1, and vs2 cannot overlap v0.scale +# CHECK-ERROR-LABEL: vfwimmacc.vv v0, v4, v20, v0.scale + +vfqimmacc.vv v8, v4, v20 +# CHECK-ERROR: too few operands for instruction +# CHECK-ERROR-LABEL: vfqimmacc.vv v8, v4, v20 + +vfqimmacc.vv v8, v4, v20, v0.t +# CHECK-ERROR: expected '.scale' suffix +# CHECK-ERROR-LABEL: vfqimmacc.vv v8, v4, v20, v0.t + +vfqimmacc.vv v8, v4, v20, v1.scale +# CHECK-ERROR: operand must be v0.scale +# CHECK-ERROR-LABEL: vfqimmacc.vv v8, v4, v20, v1.scale + +vfqimmacc.vv v8, v0, v20, v0.scale +# CHECK-ERROR: vd, vs1, and vs2 cannot overlap v0.scale +# CHECK-ERROR-LABEL: vfqimmacc.vv v8, v0, v20, v0.scale + +vf8wimmacc.vv v8, v4, v20 +# CHECK-ERROR: too few operands for instruction +# CHECK-ERROR-LABEL: vf8wimmacc.vv v8, v4, v20 + +vf8wimmacc.vv v8, v4, v20, v0.t +# CHECK-ERROR: expected '.scale' suffix +# CHECK-ERROR-LABEL: vf8wimmacc.vv v8, v4, v20, v0.t + +vf8wimmacc.vv v8, v4, v20, v1.scale +# CHECK-ERROR: operand must be v0.scale +# CHECK-ERROR-LABEL: vf8wimmacc.vv v8, v4, v20, v1.scale + +vf8wimmacc.vv v8, v4, v0, v0.scale +# CHECK-ERROR: vd, vs1, and vs2 cannot overlap v0.scale +# CHECK-ERROR-LABEL: vf8wimmacc.vv v8, v4, v0, v0.scale diff --git a/llvm/test/MC/RISCV/rvv/zvvfmm.s b/llvm/test/MC/RISCV/rvv/zvvfmm.s new file mode 100644 index 0000000000000..4c6a60d5b3fff --- /dev/null +++ b/llvm/test/MC/RISCV/rvv/zvvfmm.s @@ -0,0 +1,57 @@ +# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-zvvfmm %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-zvvfmm %s \ +# RUN: | llvm-objdump -d --mattr=+experimental-zvvfmm - \ +# RUN: | FileCheck %s --check-prefix=CHECK-INST + +vfmmacc.vv v8, v4, v20 +# CHECK-INST: vfmmacc.vv v8, v4, v20 +# CHECK-ENCODING: [0x57,0x14,0x42,0x53] +# CHECK-ERROR: instruction requires the following: 'Zvvfmm' (Floating-Point Matrix Multiply-Accumulate){{$}} + +vfwmmacc.vv v8, v4, v20 +# CHECK-INST: vfwmmacc.vv v8, v4, v20 +# CHECK-ENCODING: [0x57,0x14,0x42,0x57] +# CHECK-ERROR: instruction requires the following: 'Zvvfmm' (Floating-Point Matrix Multiply-Accumulate){{$}} + +vfwmmacc.vv v8, v4, v20, v0.scale +# CHECK-INST: vfwmmacc.vv v8, v4, v20, v0.scale +# CHECK-ENCODING: [0x57,0x14,0x42,0x55] +# CHECK-ERROR: instruction requires the following: 'Zvvfmm' (Floating-Point Matrix Multiply-Accumulate){{$}} + +vfqmmacc.vv v8, v4, v20 +# CHECK-INST: vfqmmacc.vv v8, v4, v20 +# CHECK-ENCODING: [0x57,0x14,0x42,0x5b] +# CHECK-ERROR: instruction requires the following: 'Zvvfmm' (Floating-Point Matrix Multiply-Accumulate){{$}} + +vfqmmacc.vv v8, v4, v20, v0.scale +# CHECK-INST: vfqmmacc.vv v8, v4, v20, v0.scale +# CHECK-ENCODING: [0x57,0x14,0x42,0x59] +# CHECK-ERROR: instruction requires the following: 'Zvvfmm' (Floating-Point Matrix Multiply-Accumulate){{$}} + +vf8wmmacc.vv v8, v4, v20 +# CHECK-INST: vf8wmmacc.vv v8, v4, v20 +# CHECK-ENCODING: [0x57,0x14,0x42,0x5f] +# CHECK-ERROR: instruction requires the following: 'Zvvfmm' (Floating-Point Matrix Multiply-Accumulate){{$}} + +vf8wmmacc.vv v8, v4, v20, v0.scale +# CHECK-INST: vf8wmmacc.vv v8, v4, v20, v0.scale +# CHECK-ENCODING: [0x57,0x14,0x42,0x5d] +# CHECK-ERROR: instruction requires the following: 'Zvvfmm' (Floating-Point Matrix Multiply-Accumulate){{$}} + +vfwimmacc.vv v8, v4, v20, v0.scale +# CHECK-INST: vfwimmacc.vv v8, v4, v20, v0.scale +# CHECK-ENCODING: [0x57,0x04,0x42,0xe5] +# CHECK-ERROR: instruction requires the following: 'Zvvfmm' (Floating-Point Matrix Multiply-Accumulate){{$}} + +vfqimmacc.vv v8, v4, v20, v0.scale +# CHECK-INST: vfqimmacc.vv v8, v4, v20, v0.scale +# CHECK-ENCODING: [0x57,0x04,0x42,0xe9] +# CHECK-ERROR: instruction requires the following: 'Zvvfmm' (Floating-Point Matrix Multiply-Accumulate){{$}} + +vf8wimmacc.vv v8, v4, v20, v0.scale +# CHECK-INST: vf8wimmacc.vv v8, v4, v20, v0.scale +# CHECK-ENCODING: [0x57,0x04,0x42,0xed] +# CHECK-ERROR: instruction requires the following: 'Zvvfmm' (Floating-Point Matrix Multiply-Accumulate){{$}} diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index d28066d423b77..cd0dcf98f50de 100644 --- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp @@ -1385,6 +1385,7 @@ Experimental extensions zvfbfa 0.1 zvfofp8min 0.2 zvkgs 0.7 + zvvfmm 0.1 zvvmm 0.1 zvzip 0.1 smpmpmt 0.6 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
