Skip to content

[RISCV][MC] add experimental Zvvfmm MC support#196486

Merged
imkiva merged 2 commits into
llvm:mainfrom
imkiva:ime-zvvfmm
May 13, 2026
Merged

[RISCV][MC] add experimental Zvvfmm MC support#196486
imkiva merged 2 commits into
llvm:mainfrom
imkiva:ime-zvvfmm

Conversation

@imkiva
Copy link
Copy Markdown
Member

@imkiva imkiva commented May 8, 2026

This PR adds experimental MC layer support for the RISC-V Zvvfmm from Integrated Matrix Extension based on the riscv-isa-release-fa55752-2026-05-04 spec release. As a follow up of Zvvmm in #193956

This PR:

  • Renames RISCVInstrInfoZvvmm.td to RISCVInstrInfoZvvm.td so Zvvmm and Zvvfmm share the same IME instruction file according to the spec. And all future instructions from the Zvvm family will be placed here too.
  • Adds a new VScaleReg asm operand to support the v0.scale assembly syntax.
  • Adds assembler support for floating-point matrix instructions: vfmmacc.vv, vfwmmacc.vv, vfqmmacc.vv, vf8wmmacc.vv
  • Adds integer-input floating-point accumulate scaled instructions: vfwimmacc.vv, vfqimmacc.vv, vf8wimmacc.vv

Note: microscaling individual extension names (like Zvvxi*mm, Zvvxni*mm) are not implemented yet in this PR, so everything is currently gated by +experimental-zvvfmm flag.

@llvmorg-github-actions llvmorg-github-actions Bot added backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels May 8, 2026
@llvmorg-github-actions
Copy link
Copy Markdown

llvmorg-github-actions Bot commented May 8, 2026

@llvm/pr-subscribers-backend-risc-v

@llvm/pr-subscribers-clang-driver

Author: Kiva (imkiva)

Changes

This PR adds experimental MC layer support for the RISC-V Zvvfmm from Integrated Matrix Extension based on the riscv-isa-release-fa55752-2026-05-04 spec release.

This PR:

  • Renames RISCVInstrInfoZvvmm.td to RISCVInstrInfoZvvm.td so Zvvmm and Zvvfmm share the same IME instruction file according to the spec. And all future instructions from the Zvvm family will be placed here too.
  • Adds a new VScaleReg asm operand to support the v0.scale assembly syntax.
  • Adds assembler support for floating-point matrix instructions: vfmmacc.vv, vfwmmacc.vv, vfqmmacc.vv, vf8wmmacc.vv
  • Adds integer-input floating-point accumulate scaled instructions: vfwimmacc.vv, vfqimmacc.vv, vf8wimmacc.vv

Note: microscaling individual extension names (like Zvvxi*mm, Zvvxni*mm) are not implemented yet in this PR, so everything is currently gated by +experimental-zvvfmm flag.


Patch is 23.75 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/196486.diff

14 Files Affected:

  • (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1)
  • (modified) llvm/docs/RISCVUsage.rst (+4-1)
  • (modified) llvm/docs/ReleaseNotes.md (+1)
  • (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+59)
  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp (+11)
  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h (+2)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+9-1)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.td (+1-1)
  • (added) llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td (+109)
  • (removed) llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td (-37)
  • (modified) llvm/test/CodeGen/RISCV/features-info.ll (+1)
  • (added) llvm/test/MC/RISCV/rvv/zvvfmm-invalid.s (+94)
  • (added) llvm/test/MC/RISCV/rvv/zvvfmm.s (+57)
  • (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 83920246d5dad..393b07edb0c99 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -253,6 +253,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 2c8805f5fe796..9612f239c516d 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -362,8 +362,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 424e67b8b4235..fce48e0395c2f 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -202,6 +202,7 @@ Makes programs 10x faster by doing Special New Thing.
 * `-mcpu=sifive-x160` and `-mcpu=sifive-x180` were added.
 * 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.
 
 ### 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 b905870a482ff..72735dfce0867 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -893,6 +893,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()">,
@@ -2072,4 +2081,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/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 3295d18a2d352..541bf302bf8e5 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2356,7 +2356,7 @@ include "RISCVInstrInfoZvk.td"
 include "RISCVInstrInfoZvdot4a8i.td"
 include "RISCVInstrInfoZvfofp8min.td"
 include "RISCVInstrInfoZvzip.td"
-include "RISCVInstrInfoZvvmm.td"
+include "RISCVInstrInfoZvvm.td"
 
 // Packed SIMD
 include "RISCVInstrInfoP.td"
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
new file mode 100644
index 0000000000000..5425ce391e8aa
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// 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,
+               "$vd, $vs1, $vs2"> {
+  let mayLoad = 0;
+  let mayStore = 0;
+  let hasSideEffects = 0;
+  let Constraints = "$vd = $vd_wb";
+  let vm = 1;
+  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">;
+  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/lib/Target/RISCV/RISCVInstrInfoZvvmm.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td
deleted file mode 100644
index d7620bf072ac3..0000000000000
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td
+++ /dev/null
@@ -1,37 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Instructions
-//===----------------------------------------------------------------------===//
-
-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 Constraints = "$vd = $vd_wb";
-  let vm = 1;
-  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]
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 92e033cb90dc9..486eaec0cba30 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.s b/llvm/test/MC/RISCV/rvv/zvvfmm-invalid.s
new file mode 100644
index 0000000000000..8f5f10ef2d6bd
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvvfmm-invalid.s
@@ -0,0 +1,94 @@
+# 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
+
+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
+# C...
[truncated]

@imkiva imkiva added the mc label May 8, 2026
@imkiva imkiva requested review from topperc and wangpc-pp May 8, 2026 08:33
Comment thread llvm/lib/Target/RISCV/RISCVFeatures.td
Comment thread llvm/lib/Target/RISCV/RISCVInstrInfoZvvm.td
imkiva added a commit that referenced this pull request May 9, 2026
Renames `RISCVInstrInfoZvvmm.td` to `RISCVInstrInfoZvvm.td` so `Zvvmm`
and `Zvvfmm` share the same IME instruction file according to the spec.
And all future instructions from the `Zvvm family` will be placed here
too.

This PR is required for reviewing #196486 in order to make GitHub show
the diff correcrly.
@imkiva
Copy link
Copy Markdown
Member Author

imkiva commented May 12, 2026

ping~

Copy link
Copy Markdown
Contributor

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@imkiva imkiva requested a review from wangpc-pp May 13, 2026 06:38
Copy link
Copy Markdown
Contributor

@wangpc-pp wangpc-pp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with one nit.

Comment thread llvm/docs/ReleaseNotes.md
@imkiva imkiva enabled auto-merge (squash) May 13, 2026 07:11
@imkiva imkiva merged commit 6608431 into llvm:main May 13, 2026
9 of 11 checks passed
lialan pushed a commit to lialan/llvm-project that referenced this pull request May 13, 2026
This PR adds experimental MC layer support for the RISC-V `Zvvfmm` from
Integrated Matrix Extension based on the
[riscv-isa-release-fa55752-2026-05-04 spec
release](https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-fa55752-2026-05-04).
As a follow up of `Zvvmm` in llvm#193956

This PR:
- Renames `RISCVInstrInfoZvvmm.td` to `RISCVInstrInfoZvvm.td` so `Zvvmm`
and `Zvvfmm` share the same IME instruction file according to the spec.
And all future instructions from the `Zvvm family` will be placed here
too.
- Adds a new `VScaleReg` asm operand to support the `v0.scale` assembly
syntax.
- Adds assembler support for floating-point matrix instructions:
`vfmmacc.vv`, `vfwmmacc.vv`, `vfqmmacc.vv`, `vf8wmmacc.vv`
- Adds integer-input floating-point accumulate scaled instructions:
`vfwimmacc.vv`, `vfqimmacc.vv`, `vf8wimmacc.vv`

Note: microscaling individual extension names (like `Zvvxi*mm`,
`Zvvxni*mm`) are not implemented yet in this PR, so everything is
currently gated by `+experimental-zvvfmm` flag.
EuphoricThinking pushed a commit to EuphoricThinking/llvm-project that referenced this pull request May 14, 2026
Renames `RISCVInstrInfoZvvmm.td` to `RISCVInstrInfoZvvm.td` so `Zvvmm`
and `Zvvfmm` share the same IME instruction file according to the spec.
And all future instructions from the `Zvvm family` will be placed here
too.

This PR is required for reviewing llvm#196486 in order to make GitHub show
the diff correcrly.
EuphoricThinking pushed a commit to EuphoricThinking/llvm-project that referenced this pull request May 14, 2026
This PR adds experimental MC layer support for the RISC-V `Zvvfmm` from
Integrated Matrix Extension based on the
[riscv-isa-release-fa55752-2026-05-04 spec
release](https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-fa55752-2026-05-04).
As a follow up of `Zvvmm` in llvm#193956

This PR:
- Renames `RISCVInstrInfoZvvmm.td` to `RISCVInstrInfoZvvm.td` so `Zvvmm`
and `Zvvfmm` share the same IME instruction file according to the spec.
And all future instructions from the `Zvvm family` will be placed here
too.
- Adds a new `VScaleReg` asm operand to support the `v0.scale` assembly
syntax.
- Adds assembler support for floating-point matrix instructions:
`vfmmacc.vv`, `vfwmmacc.vv`, `vfqmmacc.vv`, `vf8wmmacc.vv`
- Adds integer-input floating-point accumulate scaled instructions:
`vfwimmacc.vv`, `vfqimmacc.vv`, `vf8wimmacc.vv`

Note: microscaling individual extension names (like `Zvvxi*mm`,
`Zvvxni*mm`) are not implemented yet in this PR, so everything is
currently gated by `+experimental-zvvfmm` flag.
pedroMVicente pushed a commit to pedroMVicente/llvm-project that referenced this pull request May 19, 2026
This PR adds experimental MC layer support for the RISC-V `Zvvfmm` from
Integrated Matrix Extension based on the
[riscv-isa-release-fa55752-2026-05-04 spec
release](https://github.com/riscv/integrated-matrix-extension/releases/tag/riscv-isa-release-fa55752-2026-05-04).
As a follow up of `Zvvmm` in llvm#193956

This PR:
- Renames `RISCVInstrInfoZvvmm.td` to `RISCVInstrInfoZvvm.td` so `Zvvmm`
and `Zvvfmm` share the same IME instruction file according to the spec.
And all future instructions from the `Zvvm family` will be placed here
too.
- Adds a new `VScaleReg` asm operand to support the `v0.scale` assembly
syntax.
- Adds assembler support for floating-point matrix instructions:
`vfmmacc.vv`, `vfwmmacc.vv`, `vfqmmacc.vv`, `vf8wmmacc.vv`
- Adds integer-input floating-point accumulate scaled instructions:
`vfwimmacc.vv`, `vfqimmacc.vv`, `vf8wimmacc.vv`

Note: microscaling individual extension names (like `Zvvxi*mm`,
`Zvvxni*mm`) are not implemented yet in this PR, so everything is
currently gated by `+experimental-zvvfmm` flag.
pedroMVicente pushed a commit to pedroMVicente/llvm-project that referenced this pull request May 19, 2026
Renames `RISCVInstrInfoZvvmm.td` to `RISCVInstrInfoZvvm.td` so `Zvvmm`
and `Zvvfmm` share the same IME instruction file according to the spec.
And all future instructions from the `Zvvm family` will be placed here
too.

This PR is required for reviewing llvm#196486 in order to make GitHub show
the diff correcrly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' mc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants