[clang] [llvm] [RISCV][MC] add experimental `Zvvfmm` MC support (PR #196486)
via cfe-commits
cfe-commits at lists.llvm.org
Sat May 9 05:17:56 PDT 2026
https://github.com/imkiva updated https://github.com/llvm/llvm-project/pull/196486
>From 3ad3df42706cf787489ced8d9c1a09cdf4a10ad4 Mon Sep 17 00:00:00 2001
From: imkiva <zengtao at iscas.ac.cn>
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
More information about the cfe-commits
mailing list