[clang] [llvm] [RISCV][MC] Add experimental `Zvvmm` MC support (PR #193956)

via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 27 03:42:31 PDT 2026


https://github.com/imkiva updated https://github.com/llvm/llvm-project/pull/193956

>From 6ed33e6ddee6cbdef724fc0e6e682cecd1034dcd Mon Sep 17 00:00:00 2001
From: imkiva <zengtao at iscas.ac.cn>
Date: Fri, 24 Apr 2026 20:25:30 +0800
Subject: [PATCH 1/5] [RISCV][Zvvmm] Define experimental zvvmm extension

---
 .../llvm/TargetParser/RISCVTargetParser.h     | 29 ++++++
 llvm/lib/Target/RISCV/RISCVFeatures.td        |  8 ++
 llvm/lib/Target/RISCV/RISCVInstrInfo.td       |  1 +
 llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td  | 49 +++++++++++
 llvm/lib/TargetParser/RISCVTargetParser.cpp   | 88 +++++++++++++++++++
 .../TargetParser/RISCVISAInfoTest.cpp         |  1 +
 .../TargetParser/RISCVTargetParserTest.cpp    | 51 +++++++++++
 7 files changed, 227 insertions(+)
 create mode 100644 llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td

diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
index 110b71a6341a6..d0f4bc0795793 100644
--- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h
+++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
@@ -19,6 +19,7 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
+#include <optional>
 
 namespace llvm {
 
@@ -128,6 +129,34 @@ LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic,
 
 LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt);
 
+inline static bool isValidIMELambda(unsigned Lambda) {
+  return Lambda == 0 || (isPowerOf2_32(Lambda) && Lambda <= 64);
+}
+
+LLVM_ABI unsigned encodeIMELambda(unsigned Lambda);
+
+LLVM_ABI std::optional<unsigned> decodeIMELambda(unsigned Encoding);
+
+LLVM_ABI uint64_t getIMEVTypeFieldsMask(unsigned XLen);
+
+LLVM_ABI uint64_t encodeIMEVTypeFields(unsigned XLen, unsigned Lambda,
+                                       bool AltFmtA, bool AltFmtB,
+                                       bool BlockSize16);
+
+LLVM_ABI uint64_t addIMEVTypeFields(uint64_t VType, unsigned XLen,
+                                    unsigned Lambda, bool AltFmtA, bool AltFmtB,
+                                    bool BlockSize16);
+
+LLVM_ABI unsigned getIMELambdaEncoding(uint64_t VType, unsigned XLen);
+
+LLVM_ABI std::optional<unsigned> getIMELambda(uint64_t VType, unsigned XLen);
+
+LLVM_ABI bool isIMEAltFmtA(uint64_t VType, unsigned XLen);
+
+LLVM_ABI bool isIMEAltFmtB(uint64_t VType, unsigned XLen);
+
+LLVM_ABI bool isIMEBlockSize16(uint64_t VType, unsigned XLen);
+
 inline static VLMUL getVLMUL(unsigned VType) {
   unsigned VLMul = VType & 0x7;
   return static_cast<VLMUL>(VLMul);
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 825c78509519d..b905870a482ff 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -885,6 +885,14 @@ def HasStdExtZvzip : Predicate<"Subtarget->hasStdExtZvzip()">,
                      AssemblerPredicate<(all_of FeatureStdExtZvzip),
                          "'Zvzip' (Vector Reordering Structured Data)">;
 
+// Integrated Matrix Extension integer matrix multiply-accumulate
+def FeatureStdExtZvvmm
+    : RISCVExperimentalExtension<0, 1, "Integer Matrix Multiply-Accumulate",
+                                 [FeatureStdExtZve32x]>;
+def HasStdExtZvvmm : Predicate<"Subtarget->hasStdExtZvvmm()">,
+                     AssemblerPredicate<(all_of FeatureStdExtZvvmm),
+                         "'Zvvmm' (Integer Matrix Multiply-Accumulate)">;
+
 // Vector instruction predicates
 
 def HasVInstructions    : Predicate<"Subtarget->hasVInstructions()">,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index b2488435cf81e..b08164c088f58 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2358,6 +2358,7 @@ include "RISCVInstrInfoZvk.td"
 include "RISCVInstrInfoZvdot4a8i.td"
 include "RISCVInstrInfoZvfofp8min.td"
 include "RISCVInstrInfoZvzip.td"
+include "RISCVInstrInfoZvvmm.td"
 
 // Packed SIMD
 include "RISCVInstrInfoP.td"
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td
new file mode 100644
index 0000000000000..c4dd6267daa19
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td
@@ -0,0 +1,49 @@
+//===---- RISCVInstrInfoZvvmm.td - 'Zvvmm' instructions -*- tablegen -*-===//
+//
+// 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">,
+        SchedTernaryMC<"WriteVIMulAddV", "ReadVIMulAddV", "ReadVIMulAddV",
+                       "ReadVIMulAddV", forceMasked=0>;
+  def VWMMACC_VV
+      : VIMEMACVV<0b111001, "vwmmacc.vv">,
+        SchedTernaryMC<"WriteVIWMulAddV", "ReadVIWMulAddV", "ReadVIWMulAddV",
+                       "ReadVIWMulAddV", forceMasked=0>;
+  def VQMMACC_VV
+      : VIMEMACVV<0b111010, "vqmmacc.vv">,
+        SchedTernaryMC<"WriteVIWMulAddV", "ReadVIWMulAddV", "ReadVIWMulAddV",
+                       "ReadVIWMulAddV", forceMasked=0>;
+  def V8WMMACC_VV
+      : VIMEMACVV<0b111011, "v8wmmacc.vv">,
+        SchedTernaryMC<"WriteVIWMulAddV", "ReadVIWMulAddV", "ReadVIWMulAddV",
+                       "ReadVIWMulAddV", forceMasked=0>;
+} // Predicates = [HasStdExtZvvmm]
diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp
index eef426d7c9aee..7fc1b7e38da45 100644
--- a/llvm/lib/TargetParser/RISCVTargetParser.cpp
+++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp
@@ -388,6 +388,94 @@ unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt) {
   return VTypeI;
 }
 
+static void assertValidXLenForIMEVType(unsigned XLen) {
+  assert((XLen == 32 || XLen == 64) && "Invalid XLEN");
+}
+
+static unsigned getIMELambdaShift(unsigned XLen) {
+  assertValidXLenForIMEVType(XLen);
+  return XLen - 4;
+}
+
+static unsigned getIMEAltFmtAShift(unsigned XLen) {
+  assertValidXLenForIMEVType(XLen);
+  return XLen - 5;
+}
+
+static unsigned getIMEAltFmtBShift(unsigned XLen) {
+  assertValidXLenForIMEVType(XLen);
+  return XLen - 6;
+}
+
+static unsigned getIMEBSShift(unsigned XLen) {
+  assertValidXLenForIMEVType(XLen);
+  return XLen - 7;
+}
+
+unsigned encodeIMELambda(unsigned Lambda) {
+  assert(isValidIMELambda(Lambda) && "Invalid IME lambda");
+  if (Lambda == 0)
+    return 0;
+  return Log2_32(Lambda) + 1;
+}
+
+std::optional<unsigned> decodeIMELambda(unsigned Encoding) {
+  assert(Encoding < 8 && "Invalid IME lambda encoding");
+  if (Encoding == 0)
+    return std::nullopt;
+  return 1U << (Encoding - 1);
+}
+
+uint64_t getIMEVTypeFieldsMask(unsigned XLen) {
+  assertValidXLenForIMEVType(XLen);
+  return (0x7ULL << getIMELambdaShift(XLen)) |
+         (1ULL << getIMEAltFmtAShift(XLen)) |
+         (1ULL << getIMEAltFmtBShift(XLen)) | (1ULL << getIMEBSShift(XLen));
+}
+
+uint64_t encodeIMEVTypeFields(unsigned XLen, unsigned Lambda, bool AltFmtA,
+                              bool AltFmtB, bool BlockSize16) {
+  assertValidXLenForIMEVType(XLen);
+  uint64_t VType = uint64_t(encodeIMELambda(Lambda)) << getIMELambdaShift(XLen);
+  if (AltFmtA)
+    VType |= 1ULL << getIMEAltFmtAShift(XLen);
+  if (AltFmtB)
+    VType |= 1ULL << getIMEAltFmtBShift(XLen);
+  if (BlockSize16)
+    VType |= 1ULL << getIMEBSShift(XLen);
+  return VType;
+}
+
+uint64_t addIMEVTypeFields(uint64_t VType, unsigned XLen, unsigned Lambda,
+                           bool AltFmtA, bool AltFmtB, bool BlockSize16) {
+  return (VType & ~getIMEVTypeFieldsMask(XLen)) |
+         encodeIMEVTypeFields(XLen, Lambda, AltFmtA, AltFmtB, BlockSize16);
+}
+
+unsigned getIMELambdaEncoding(uint64_t VType, unsigned XLen) {
+  assertValidXLenForIMEVType(XLen);
+  return (VType >> getIMELambdaShift(XLen)) & 0x7;
+}
+
+std::optional<unsigned> getIMELambda(uint64_t VType, unsigned XLen) {
+  return decodeIMELambda(getIMELambdaEncoding(VType, XLen));
+}
+
+bool isIMEAltFmtA(uint64_t VType, unsigned XLen) {
+  assertValidXLenForIMEVType(XLen);
+  return VType & (1ULL << getIMEAltFmtAShift(XLen));
+}
+
+bool isIMEAltFmtB(uint64_t VType, unsigned XLen) {
+  assertValidXLenForIMEVType(XLen);
+  return VType & (1ULL << getIMEAltFmtBShift(XLen));
+}
+
+bool isIMEBlockSize16(uint64_t VType, unsigned XLen) {
+  assertValidXLenForIMEVType(XLen);
+  return VType & (1ULL << getIMEBSShift(XLen));
+}
+
 std::pair<unsigned, bool> decodeVLMUL(VLMUL VLMul) {
   switch (VLMul) {
   default:
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index ca2c28c30a30f..e96e2d9d462dc 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1384,6 +1384,7 @@ Experimental extensions
     zvfbfa               0.1
     zvfofp8min           0.2
     zvkgs                0.7
+    zvvmm                0.1
     zvzip                0.1
     smpmpmt              0.6
     svukte               0.3
diff --git a/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp b/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp
index 0302d56e3e3fa..8e0bd36345e70 100644
--- a/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp
@@ -39,6 +39,57 @@ TEST(RISCVVType, CheckSameRatioLMUL) {
                 RISCVVType::getSEWLMULRatio(8, RISCVVType::LMUL_F4), 16));
 }
 
+TEST(RISCVVType, IMEVTypeFields) {
+  EXPECT_TRUE(RISCVVType::isValidIMELambda(0));
+  EXPECT_TRUE(RISCVVType::isValidIMELambda(1));
+  EXPECT_TRUE(RISCVVType::isValidIMELambda(64));
+  EXPECT_FALSE(RISCVVType::isValidIMELambda(3));
+  EXPECT_FALSE(RISCVVType::isValidIMELambda(128));
+
+  EXPECT_EQ(0U, RISCVVType::encodeIMELambda(0));
+  EXPECT_EQ(1U, RISCVVType::encodeIMELambda(1));
+  EXPECT_EQ(3U, RISCVVType::encodeIMELambda(4));
+  EXPECT_EQ(7U, RISCVVType::encodeIMELambda(64));
+  EXPECT_EQ(std::nullopt, RISCVVType::decodeIMELambda(0));
+  EXPECT_EQ(std::optional<unsigned>(1), RISCVVType::decodeIMELambda(1));
+  EXPECT_EQ(std::optional<unsigned>(4), RISCVVType::decodeIMELambda(3));
+  EXPECT_EQ(std::optional<unsigned>(64), RISCVVType::decodeIMELambda(7));
+
+  unsigned BaseVType =
+      RISCVVType::encodeVTYPE(RISCVVType::LMUL_1, 32, /*TailAgnostic=*/true,
+                              /*MaskAgnostic=*/true);
+
+  uint64_t RV32VType = RISCVVType::addIMEVTypeFields(
+      BaseVType, /*XLen=*/32, /*Lambda=*/4, /*AltFmtA=*/true,
+      /*AltFmtB=*/false, /*BlockSize16=*/true);
+  EXPECT_EQ(0x3a0000d0ULL, RV32VType);
+  EXPECT_EQ(0x7e000000ULL, RISCVVType::getIMEVTypeFieldsMask(32));
+  EXPECT_EQ(3U, RISCVVType::getIMELambdaEncoding(RV32VType, 32));
+  EXPECT_EQ(std::optional<unsigned>(4),
+            RISCVVType::getIMELambda(RV32VType, 32));
+  EXPECT_TRUE(RISCVVType::isIMEAltFmtA(RV32VType, 32));
+  EXPECT_FALSE(RISCVVType::isIMEAltFmtB(RV32VType, 32));
+  EXPECT_TRUE(RISCVVType::isIMEBlockSize16(RV32VType, 32));
+
+  uint64_t RV64VType = RISCVVType::addIMEVTypeFields(
+      BaseVType, /*XLen=*/64, /*Lambda=*/64, /*AltFmtA=*/true,
+      /*AltFmtB=*/true, /*BlockSize16=*/true);
+  EXPECT_EQ(0x7e000000000000d0ULL, RV64VType);
+  EXPECT_EQ(0x7e00000000000000ULL, RISCVVType::getIMEVTypeFieldsMask(64));
+  EXPECT_EQ(7U, RISCVVType::getIMELambdaEncoding(RV64VType, 64));
+  EXPECT_EQ(std::optional<unsigned>(64),
+            RISCVVType::getIMELambda(RV64VType, 64));
+  EXPECT_TRUE(RISCVVType::isIMEAltFmtA(RV64VType, 64));
+  EXPECT_TRUE(RISCVVType::isIMEAltFmtB(RV64VType, 64));
+  EXPECT_TRUE(RISCVVType::isIMEBlockSize16(RV64VType, 64));
+
+  uint64_t DynamicLambda = RISCVVType::addIMEVTypeFields(
+      BaseVType, /*XLen=*/64, /*Lambda=*/0, /*AltFmtA=*/false,
+      /*AltFmtB=*/false, /*BlockSize16=*/false);
+  EXPECT_EQ(std::nullopt, RISCVVType::getIMELambda(DynamicLambda, 64));
+  EXPECT_EQ(BaseVType, DynamicLambda);
+}
+
 TEST(RISCVTuneFeature, AllTuneFeatures) {
   SmallVector<StringRef> AllTuneFeatures;
   RISCV::getAllTuneFeatures(AllTuneFeatures);

>From e50e1986c4baa97f36b0b70916b08a70d36f663c Mon Sep 17 00:00:00 2001
From: imkiva <zengtao at iscas.ac.cn>
Date: Fri, 24 Apr 2026 20:25:39 +0800
Subject: [PATCH 2/5] [RISCV][Zvvmm] add Zvvmm MC tests

---
 llvm/test/MC/RISCV/rvv/zvvmm-invalid.s    | 18 +++++++++++++++
 llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv32.s | 11 +++++++++
 llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv64.s | 11 +++++++++
 llvm/test/MC/RISCV/rvv/zvvmm.s            | 27 +++++++++++++++++++++++
 4 files changed, 67 insertions(+)
 create mode 100644 llvm/test/MC/RISCV/rvv/zvvmm-invalid.s
 create mode 100644 llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv32.s
 create mode 100644 llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv64.s
 create mode 100644 llvm/test/MC/RISCV/rvv/zvvmm.s

diff --git a/llvm/test/MC/RISCV/rvv/zvvmm-invalid.s b/llvm/test/MC/RISCV/rvv/zvvmm-invalid.s
new file mode 100644
index 0000000000000..7cccf11b8d1ea
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvvmm-invalid.s
@@ -0,0 +1,18 @@
+# RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-zvvmm %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+vmmacc.vv v8, v4, v20, v0.t
+# CHECK-ERROR: invalid operand for instruction
+# CHECK-ERROR-LABEL: vmmacc.vv v8, v4, v20, v0.t
+
+vwmmacc.vv v8, v4, v20, v0.t
+# CHECK-ERROR: invalid operand for instruction
+# CHECK-ERROR-LABEL: vwmmacc.vv v8, v4, v20, v0.t
+
+vqmmacc.vv v8, v4, v20, v0.t
+# CHECK-ERROR: invalid operand for instruction
+# CHECK-ERROR-LABEL: vqmmacc.vv v8, v4, v20, v0.t
+
+v8wmmacc.vv v8, v4, v20, v0.t
+# CHECK-ERROR: invalid operand for instruction
+# CHECK-ERROR-LABEL: v8wmmacc.vv v8, v4, v20, v0.t
diff --git a/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv32.s b/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv32.s
new file mode 100644
index 0000000000000..c284695ffbee8
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv32.s
@@ -0,0 +1,11 @@
+# RUN: llvm-mc -triple=riscv32 -show-encoding --mattr=+experimental-zvvmm %s \
+# RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+# SEW=32, LMUL=1, ta, ma, lambda=4, altfmt_A=1, altfmt_B=1.
+li t1, 0x3c0000d0
+vsetvl t0, a0, t1
+# CHECK-INST: vsetvl t0, a0, t1
+# CHECK-ENCODING: [0xd7,0x72,0x65,0x80]
+vmmacc.vv v8, v4, v20
+# CHECK-INST-NEXT: vmmacc.vv v8, v4, v20
+# CHECK-ENCODING: [0x57,0x04,0x42,0xe3]
diff --git a/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv64.s b/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv64.s
new file mode 100644
index 0000000000000..87ae2065f43cd
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv64.s
@@ -0,0 +1,11 @@
+# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-zvvmm %s \
+# RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+# SEW=32, LMUL=1, ta, ma, lambda=4, altfmt_A=1, altfmt_B=1.
+li t1, 0x3c000000000000d0
+vsetvl t0, a0, t1
+# CHECK-INST: vsetvl t0, a0, t1
+# CHECK-ENCODING: [0xd7,0x72,0x65,0x80]
+vmmacc.vv v8, v4, v20
+# CHECK-INST-NEXT: vmmacc.vv v8, v4, v20
+# CHECK-ENCODING: [0x57,0x04,0x42,0xe3]
diff --git a/llvm/test/MC/RISCV/rvv/zvvmm.s b/llvm/test/MC/RISCV/rvv/zvvmm.s
new file mode 100644
index 0000000000000..fad5139fca156
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvvmm.s
@@ -0,0 +1,27 @@
+# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-zvvmm %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-zvvmm %s \
+# RUN:        | llvm-objdump -d --mattr=+experimental-zvvmm - \
+# RUN:        | FileCheck %s --check-prefix=CHECK-INST
+
+vmmacc.vv v8, v4, v20
+# CHECK-INST: vmmacc.vv v8, v4, v20
+# CHECK-ENCODING: [0x57,0x04,0x42,0xe3]
+# CHECK-ERROR: instruction requires the following: 'Zvvmm' (Integer Matrix Multiply-Accumulate){{$}}
+
+vwmmacc.vv v8, v4, v20
+# CHECK-INST: vwmmacc.vv v8, v4, v20
+# CHECK-ENCODING: [0x57,0x04,0x42,0xe7]
+# CHECK-ERROR: instruction requires the following: 'Zvvmm' (Integer Matrix Multiply-Accumulate){{$}}
+
+vqmmacc.vv v8, v4, v20
+# CHECK-INST: vqmmacc.vv v8, v4, v20
+# CHECK-ENCODING: [0x57,0x04,0x42,0xeb]
+# CHECK-ERROR: instruction requires the following: 'Zvvmm' (Integer Matrix Multiply-Accumulate){{$}}
+
+v8wmmacc.vv v8, v4, v20
+# CHECK-INST: v8wmmacc.vv v8, v4, v20
+# CHECK-ENCODING: [0x57,0x04,0x42,0xef]
+# CHECK-ERROR: instruction requires the following: 'Zvvmm' (Integer Matrix Multiply-Accumulate){{$}}

>From f400735c446d32e54eade40d78946b098bea6309 Mon Sep 17 00:00:00 2001
From: imkiva <zengtao at iscas.ac.cn>
Date: Fri, 24 Apr 2026 21:44:56 +0800
Subject: [PATCH 3/5] fix tests

---
 clang/test/Driver/print-supported-extensions-riscv.c | 1 +
 llvm/test/CodeGen/RISCV/features-info.ll             | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 1a832451ed7bc..83920246d5dad 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:     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)
 // CHECK-NEXT:     svukte               0.3       'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses)
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 9f3cfb5a181f2..92e033cb90dc9 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -39,7 +39,8 @@
 ; 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-zvzip               - 'Zvzip' (Vector Reordering Structured Data). 
+; 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).
 ; CHECK-NEXT:   forced-atomics                   - Assume that lock-free native-width atomics are available.
 ; CHECK-NEXT:   fusion-add-load                  - Enable ADD(.UW) + load macrofusion.

>From 751f100dba380cb19fb1e06d45afad3d4b044ad7 Mon Sep 17 00:00:00 2001
From: imkiva <zengtao at iscas.ac.cn>
Date: Sat, 25 Apr 2026 13:43:46 +0800
Subject: [PATCH 4/5] Address review: - Do not compare std::optional, just
 dereference them - Added experimental-zvvmm notes to RISCVUsage.rst

---
 llvm/docs/RISCVUsage.rst                         |  3 +++
 .../TargetParser/RISCVTargetParserTest.cpp       | 16 +++++++---------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index bfc7d0afa008b..2c8805f5fe796 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -362,6 +362,9 @@ 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-zvvmm``
+  LLVM implements the `0.1 draft specification <https://github.com/riscv/integrated-matrix-extension/blob/d2e64b4922f5c2c416761f3c7c997d4f0cf814d9/src/integrated-matrix.adoc>`__.
+
 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`.
 
 Vendor Extensions
diff --git a/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp b/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp
index 8e0bd36345e70..86d6fee28ea24 100644
--- a/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp
@@ -50,10 +50,10 @@ TEST(RISCVVType, IMEVTypeFields) {
   EXPECT_EQ(1U, RISCVVType::encodeIMELambda(1));
   EXPECT_EQ(3U, RISCVVType::encodeIMELambda(4));
   EXPECT_EQ(7U, RISCVVType::encodeIMELambda(64));
-  EXPECT_EQ(std::nullopt, RISCVVType::decodeIMELambda(0));
-  EXPECT_EQ(std::optional<unsigned>(1), RISCVVType::decodeIMELambda(1));
-  EXPECT_EQ(std::optional<unsigned>(4), RISCVVType::decodeIMELambda(3));
-  EXPECT_EQ(std::optional<unsigned>(64), RISCVVType::decodeIMELambda(7));
+  EXPECT_FALSE(RISCVVType::decodeIMELambda(0));
+  EXPECT_EQ(1U, *RISCVVType::decodeIMELambda(1));
+  EXPECT_EQ(4U, *RISCVVType::decodeIMELambda(3));
+  EXPECT_EQ(64U, *RISCVVType::decodeIMELambda(7));
 
   unsigned BaseVType =
       RISCVVType::encodeVTYPE(RISCVVType::LMUL_1, 32, /*TailAgnostic=*/true,
@@ -65,8 +65,7 @@ TEST(RISCVVType, IMEVTypeFields) {
   EXPECT_EQ(0x3a0000d0ULL, RV32VType);
   EXPECT_EQ(0x7e000000ULL, RISCVVType::getIMEVTypeFieldsMask(32));
   EXPECT_EQ(3U, RISCVVType::getIMELambdaEncoding(RV32VType, 32));
-  EXPECT_EQ(std::optional<unsigned>(4),
-            RISCVVType::getIMELambda(RV32VType, 32));
+  EXPECT_EQ(4U, *RISCVVType::getIMELambda(RV32VType, 32));
   EXPECT_TRUE(RISCVVType::isIMEAltFmtA(RV32VType, 32));
   EXPECT_FALSE(RISCVVType::isIMEAltFmtB(RV32VType, 32));
   EXPECT_TRUE(RISCVVType::isIMEBlockSize16(RV32VType, 32));
@@ -77,8 +76,7 @@ TEST(RISCVVType, IMEVTypeFields) {
   EXPECT_EQ(0x7e000000000000d0ULL, RV64VType);
   EXPECT_EQ(0x7e00000000000000ULL, RISCVVType::getIMEVTypeFieldsMask(64));
   EXPECT_EQ(7U, RISCVVType::getIMELambdaEncoding(RV64VType, 64));
-  EXPECT_EQ(std::optional<unsigned>(64),
-            RISCVVType::getIMELambda(RV64VType, 64));
+  EXPECT_EQ(64U, *RISCVVType::getIMELambda(RV64VType, 64));
   EXPECT_TRUE(RISCVVType::isIMEAltFmtA(RV64VType, 64));
   EXPECT_TRUE(RISCVVType::isIMEAltFmtB(RV64VType, 64));
   EXPECT_TRUE(RISCVVType::isIMEBlockSize16(RV64VType, 64));
@@ -86,7 +84,7 @@ TEST(RISCVVType, IMEVTypeFields) {
   uint64_t DynamicLambda = RISCVVType::addIMEVTypeFields(
       BaseVType, /*XLen=*/64, /*Lambda=*/0, /*AltFmtA=*/false,
       /*AltFmtB=*/false, /*BlockSize16=*/false);
-  EXPECT_EQ(std::nullopt, RISCVVType::getIMELambda(DynamicLambda, 64));
+  EXPECT_FALSE(RISCVVType::getIMELambda(DynamicLambda, 64));
   EXPECT_EQ(BaseVType, DynamicLambda);
 }
 

>From 90a10cdd3b3fc88b66d67c531468c4945c619018 Mon Sep 17 00:00:00 2001
From: imkiva <zengtao at iscas.ac.cn>
Date: Mon, 27 Apr 2026 18:41:56 +0800
Subject: [PATCH 5/5] Address review: - Remove unneeded tests - Remove Sched
 for Zvvmm instructions for now - Reorganize IME encoding helpers to IME
 namespace

---
 .../llvm/TargetParser/RISCVTargetParser.h     | 31 +++----
 llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td  | 22 ++---
 llvm/lib/TargetParser/RISCVTargetParser.cpp   | 85 ++++++++++---------
 llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv32.s     | 11 ---
 llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv64.s     | 11 ---
 .../TargetParser/RISCVTargetParserTest.cpp    | 64 +++++++-------
 6 files changed, 96 insertions(+), 128 deletions(-)
 delete mode 100644 llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv32.s
 delete mode 100644 llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv64.s

diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
index d0f4bc0795793..404f40ee22fad 100644
--- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h
+++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
@@ -129,33 +129,34 @@ LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic,
 
 LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt);
 
-inline static bool isValidIMELambda(unsigned Lambda) {
+namespace IME {
+inline static bool isValidLambda(unsigned Lambda) {
   return Lambda == 0 || (isPowerOf2_32(Lambda) && Lambda <= 64);
 }
 
-LLVM_ABI unsigned encodeIMELambda(unsigned Lambda);
+LLVM_ABI unsigned encodeLambda(unsigned Lambda);
 
-LLVM_ABI std::optional<unsigned> decodeIMELambda(unsigned Encoding);
+LLVM_ABI std::optional<unsigned> decodeLambda(unsigned Encoding);
 
-LLVM_ABI uint64_t getIMEVTypeFieldsMask(unsigned XLen);
+LLVM_ABI uint64_t getVTypeFieldsMask(unsigned XLen);
 
-LLVM_ABI uint64_t encodeIMEVTypeFields(unsigned XLen, unsigned Lambda,
-                                       bool AltFmtA, bool AltFmtB,
-                                       bool BlockSize16);
-
-LLVM_ABI uint64_t addIMEVTypeFields(uint64_t VType, unsigned XLen,
-                                    unsigned Lambda, bool AltFmtA, bool AltFmtB,
+LLVM_ABI uint64_t encodeVTypeFields(unsigned XLen, unsigned Lambda,
+                                    bool AltFmtA, bool AltFmtB,
                                     bool BlockSize16);
 
-LLVM_ABI unsigned getIMELambdaEncoding(uint64_t VType, unsigned XLen);
+LLVM_ABI uint64_t addVTypeFields(uint64_t VType, unsigned XLen, unsigned Lambda,
+                                 bool AltFmtA, bool AltFmtB, bool BlockSize16);
+
+LLVM_ABI unsigned getLambdaEncoding(uint64_t VType, unsigned XLen);
 
-LLVM_ABI std::optional<unsigned> getIMELambda(uint64_t VType, unsigned XLen);
+LLVM_ABI std::optional<unsigned> getLambda(uint64_t VType, unsigned XLen);
 
-LLVM_ABI bool isIMEAltFmtA(uint64_t VType, unsigned XLen);
+LLVM_ABI bool isAltFmtA(uint64_t VType, unsigned XLen);
 
-LLVM_ABI bool isIMEAltFmtB(uint64_t VType, unsigned XLen);
+LLVM_ABI bool isAltFmtB(uint64_t VType, unsigned XLen);
 
-LLVM_ABI bool isIMEBlockSize16(uint64_t VType, unsigned XLen);
+LLVM_ABI bool isBlockSize16(uint64_t VType, unsigned XLen);
+} // namespace IME
 
 inline static VLMUL getVLMUL(unsigned VType) {
   unsigned VLMul = VType & 0x7;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td
index c4dd6267daa19..d7620bf072ac3 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvvmm.td
@@ -1,4 +1,4 @@
-//===---- RISCVInstrInfoZvvmm.td - 'Zvvmm' instructions -*- tablegen -*-===//
+//===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -30,20 +30,8 @@ class VIMEMACVV<bits<6> funct6, string opcodestr>
 }
 
 let Predicates = [HasStdExtZvvmm] in {
-  def VMMACC_VV
-      : VIMEMACVV<0b111000, "vmmacc.vv">,
-        SchedTernaryMC<"WriteVIMulAddV", "ReadVIMulAddV", "ReadVIMulAddV",
-                       "ReadVIMulAddV", forceMasked=0>;
-  def VWMMACC_VV
-      : VIMEMACVV<0b111001, "vwmmacc.vv">,
-        SchedTernaryMC<"WriteVIWMulAddV", "ReadVIWMulAddV", "ReadVIWMulAddV",
-                       "ReadVIWMulAddV", forceMasked=0>;
-  def VQMMACC_VV
-      : VIMEMACVV<0b111010, "vqmmacc.vv">,
-        SchedTernaryMC<"WriteVIWMulAddV", "ReadVIWMulAddV", "ReadVIWMulAddV",
-                       "ReadVIWMulAddV", forceMasked=0>;
-  def V8WMMACC_VV
-      : VIMEMACVV<0b111011, "v8wmmacc.vv">,
-        SchedTernaryMC<"WriteVIWMulAddV", "ReadVIWMulAddV", "ReadVIWMulAddV",
-                       "ReadVIWMulAddV", forceMasked=0>;
+  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/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp
index 7fc1b7e38da45..959de5af51254 100644
--- a/llvm/lib/TargetParser/RISCVTargetParser.cpp
+++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp
@@ -388,93 +388,94 @@ unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt) {
   return VTypeI;
 }
 
-static void assertValidXLenForIMEVType(unsigned XLen) {
+namespace IME {
+static void assertValidXLenForVType(unsigned XLen) {
   assert((XLen == 32 || XLen == 64) && "Invalid XLEN");
 }
 
-static unsigned getIMELambdaShift(unsigned XLen) {
-  assertValidXLenForIMEVType(XLen);
+static unsigned getLambdaShift(unsigned XLen) {
+  assertValidXLenForVType(XLen);
   return XLen - 4;
 }
 
-static unsigned getIMEAltFmtAShift(unsigned XLen) {
-  assertValidXLenForIMEVType(XLen);
+static unsigned getAltFmtAShift(unsigned XLen) {
+  assertValidXLenForVType(XLen);
   return XLen - 5;
 }
 
-static unsigned getIMEAltFmtBShift(unsigned XLen) {
-  assertValidXLenForIMEVType(XLen);
+static unsigned getAltFmtBShift(unsigned XLen) {
+  assertValidXLenForVType(XLen);
   return XLen - 6;
 }
 
-static unsigned getIMEBSShift(unsigned XLen) {
-  assertValidXLenForIMEVType(XLen);
+static unsigned getBSShift(unsigned XLen) {
+  assertValidXLenForVType(XLen);
   return XLen - 7;
 }
 
-unsigned encodeIMELambda(unsigned Lambda) {
-  assert(isValidIMELambda(Lambda) && "Invalid IME lambda");
+unsigned encodeLambda(unsigned Lambda) {
+  assert(isValidLambda(Lambda) && "Invalid IME lambda");
   if (Lambda == 0)
     return 0;
   return Log2_32(Lambda) + 1;
 }
 
-std::optional<unsigned> decodeIMELambda(unsigned Encoding) {
+std::optional<unsigned> decodeLambda(unsigned Encoding) {
   assert(Encoding < 8 && "Invalid IME lambda encoding");
   if (Encoding == 0)
     return std::nullopt;
   return 1U << (Encoding - 1);
 }
 
-uint64_t getIMEVTypeFieldsMask(unsigned XLen) {
-  assertValidXLenForIMEVType(XLen);
-  return (0x7ULL << getIMELambdaShift(XLen)) |
-         (1ULL << getIMEAltFmtAShift(XLen)) |
-         (1ULL << getIMEAltFmtBShift(XLen)) | (1ULL << getIMEBSShift(XLen));
+uint64_t getVTypeFieldsMask(unsigned XLen) {
+  assertValidXLenForVType(XLen);
+  return (0x7ULL << getLambdaShift(XLen)) | (1ULL << getAltFmtAShift(XLen)) |
+         (1ULL << getAltFmtBShift(XLen)) | (1ULL << getBSShift(XLen));
 }
 
-uint64_t encodeIMEVTypeFields(unsigned XLen, unsigned Lambda, bool AltFmtA,
-                              bool AltFmtB, bool BlockSize16) {
-  assertValidXLenForIMEVType(XLen);
-  uint64_t VType = uint64_t(encodeIMELambda(Lambda)) << getIMELambdaShift(XLen);
+uint64_t encodeVTypeFields(unsigned XLen, unsigned Lambda, bool AltFmtA,
+                           bool AltFmtB, bool BlockSize16) {
+  assertValidXLenForVType(XLen);
+  uint64_t VType = uint64_t(encodeLambda(Lambda)) << getLambdaShift(XLen);
   if (AltFmtA)
-    VType |= 1ULL << getIMEAltFmtAShift(XLen);
+    VType |= 1ULL << getAltFmtAShift(XLen);
   if (AltFmtB)
-    VType |= 1ULL << getIMEAltFmtBShift(XLen);
+    VType |= 1ULL << getAltFmtBShift(XLen);
   if (BlockSize16)
-    VType |= 1ULL << getIMEBSShift(XLen);
+    VType |= 1ULL << getBSShift(XLen);
   return VType;
 }
 
-uint64_t addIMEVTypeFields(uint64_t VType, unsigned XLen, unsigned Lambda,
-                           bool AltFmtA, bool AltFmtB, bool BlockSize16) {
-  return (VType & ~getIMEVTypeFieldsMask(XLen)) |
-         encodeIMEVTypeFields(XLen, Lambda, AltFmtA, AltFmtB, BlockSize16);
+uint64_t addVTypeFields(uint64_t VType, unsigned XLen, unsigned Lambda,
+                        bool AltFmtA, bool AltFmtB, bool BlockSize16) {
+  return (VType & ~getVTypeFieldsMask(XLen)) |
+         encodeVTypeFields(XLen, Lambda, AltFmtA, AltFmtB, BlockSize16);
 }
 
-unsigned getIMELambdaEncoding(uint64_t VType, unsigned XLen) {
-  assertValidXLenForIMEVType(XLen);
-  return (VType >> getIMELambdaShift(XLen)) & 0x7;
+unsigned getLambdaEncoding(uint64_t VType, unsigned XLen) {
+  assertValidXLenForVType(XLen);
+  return (VType >> getLambdaShift(XLen)) & 0x7;
 }
 
-std::optional<unsigned> getIMELambda(uint64_t VType, unsigned XLen) {
-  return decodeIMELambda(getIMELambdaEncoding(VType, XLen));
+std::optional<unsigned> getLambda(uint64_t VType, unsigned XLen) {
+  return decodeLambda(getLambdaEncoding(VType, XLen));
 }
 
-bool isIMEAltFmtA(uint64_t VType, unsigned XLen) {
-  assertValidXLenForIMEVType(XLen);
-  return VType & (1ULL << getIMEAltFmtAShift(XLen));
+bool isAltFmtA(uint64_t VType, unsigned XLen) {
+  assertValidXLenForVType(XLen);
+  return VType & (1ULL << getAltFmtAShift(XLen));
 }
 
-bool isIMEAltFmtB(uint64_t VType, unsigned XLen) {
-  assertValidXLenForIMEVType(XLen);
-  return VType & (1ULL << getIMEAltFmtBShift(XLen));
+bool isAltFmtB(uint64_t VType, unsigned XLen) {
+  assertValidXLenForVType(XLen);
+  return VType & (1ULL << getAltFmtBShift(XLen));
 }
 
-bool isIMEBlockSize16(uint64_t VType, unsigned XLen) {
-  assertValidXLenForIMEVType(XLen);
-  return VType & (1ULL << getIMEBSShift(XLen));
+bool isBlockSize16(uint64_t VType, unsigned XLen) {
+  assertValidXLenForVType(XLen);
+  return VType & (1ULL << getBSShift(XLen));
 }
+} // namespace IME
 
 std::pair<unsigned, bool> decodeVLMUL(VLMUL VLMul) {
   switch (VLMul) {
diff --git a/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv32.s b/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv32.s
deleted file mode 100644
index c284695ffbee8..0000000000000
--- a/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv32.s
+++ /dev/null
@@ -1,11 +0,0 @@
-# RUN: llvm-mc -triple=riscv32 -show-encoding --mattr=+experimental-zvvmm %s \
-# RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
-
-# SEW=32, LMUL=1, ta, ma, lambda=4, altfmt_A=1, altfmt_B=1.
-li t1, 0x3c0000d0
-vsetvl t0, a0, t1
-# CHECK-INST: vsetvl t0, a0, t1
-# CHECK-ENCODING: [0xd7,0x72,0x65,0x80]
-vmmacc.vv v8, v4, v20
-# CHECK-INST-NEXT: vmmacc.vv v8, v4, v20
-# CHECK-ENCODING: [0x57,0x04,0x42,0xe3]
diff --git a/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv64.s b/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv64.s
deleted file mode 100644
index 87ae2065f43cd..0000000000000
--- a/llvm/test/MC/RISCV/rvv/zvvmm-vtype-rv64.s
+++ /dev/null
@@ -1,11 +0,0 @@
-# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-zvvmm %s \
-# RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
-
-# SEW=32, LMUL=1, ta, ma, lambda=4, altfmt_A=1, altfmt_B=1.
-li t1, 0x3c000000000000d0
-vsetvl t0, a0, t1
-# CHECK-INST: vsetvl t0, a0, t1
-# CHECK-ENCODING: [0xd7,0x72,0x65,0x80]
-vmmacc.vv v8, v4, v20
-# CHECK-INST-NEXT: vmmacc.vv v8, v4, v20
-# CHECK-ENCODING: [0x57,0x04,0x42,0xe3]
diff --git a/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp b/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp
index 86d6fee28ea24..7ecdf4300f930 100644
--- a/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVTargetParserTest.cpp
@@ -40,51 +40,51 @@ TEST(RISCVVType, CheckSameRatioLMUL) {
 }
 
 TEST(RISCVVType, IMEVTypeFields) {
-  EXPECT_TRUE(RISCVVType::isValidIMELambda(0));
-  EXPECT_TRUE(RISCVVType::isValidIMELambda(1));
-  EXPECT_TRUE(RISCVVType::isValidIMELambda(64));
-  EXPECT_FALSE(RISCVVType::isValidIMELambda(3));
-  EXPECT_FALSE(RISCVVType::isValidIMELambda(128));
-
-  EXPECT_EQ(0U, RISCVVType::encodeIMELambda(0));
-  EXPECT_EQ(1U, RISCVVType::encodeIMELambda(1));
-  EXPECT_EQ(3U, RISCVVType::encodeIMELambda(4));
-  EXPECT_EQ(7U, RISCVVType::encodeIMELambda(64));
-  EXPECT_FALSE(RISCVVType::decodeIMELambda(0));
-  EXPECT_EQ(1U, *RISCVVType::decodeIMELambda(1));
-  EXPECT_EQ(4U, *RISCVVType::decodeIMELambda(3));
-  EXPECT_EQ(64U, *RISCVVType::decodeIMELambda(7));
+  EXPECT_TRUE(RISCVVType::IME::isValidLambda(0));
+  EXPECT_TRUE(RISCVVType::IME::isValidLambda(1));
+  EXPECT_TRUE(RISCVVType::IME::isValidLambda(64));
+  EXPECT_FALSE(RISCVVType::IME::isValidLambda(3));
+  EXPECT_FALSE(RISCVVType::IME::isValidLambda(128));
+
+  EXPECT_EQ(0U, RISCVVType::IME::encodeLambda(0));
+  EXPECT_EQ(1U, RISCVVType::IME::encodeLambda(1));
+  EXPECT_EQ(3U, RISCVVType::IME::encodeLambda(4));
+  EXPECT_EQ(7U, RISCVVType::IME::encodeLambda(64));
+  EXPECT_FALSE(RISCVVType::IME::decodeLambda(0));
+  EXPECT_EQ(1U, *RISCVVType::IME::decodeLambda(1));
+  EXPECT_EQ(4U, *RISCVVType::IME::decodeLambda(3));
+  EXPECT_EQ(64U, *RISCVVType::IME::decodeLambda(7));
 
   unsigned BaseVType =
       RISCVVType::encodeVTYPE(RISCVVType::LMUL_1, 32, /*TailAgnostic=*/true,
                               /*MaskAgnostic=*/true);
 
-  uint64_t RV32VType = RISCVVType::addIMEVTypeFields(
+  uint64_t RV32VType = RISCVVType::IME::addVTypeFields(
       BaseVType, /*XLen=*/32, /*Lambda=*/4, /*AltFmtA=*/true,
       /*AltFmtB=*/false, /*BlockSize16=*/true);
   EXPECT_EQ(0x3a0000d0ULL, RV32VType);
-  EXPECT_EQ(0x7e000000ULL, RISCVVType::getIMEVTypeFieldsMask(32));
-  EXPECT_EQ(3U, RISCVVType::getIMELambdaEncoding(RV32VType, 32));
-  EXPECT_EQ(4U, *RISCVVType::getIMELambda(RV32VType, 32));
-  EXPECT_TRUE(RISCVVType::isIMEAltFmtA(RV32VType, 32));
-  EXPECT_FALSE(RISCVVType::isIMEAltFmtB(RV32VType, 32));
-  EXPECT_TRUE(RISCVVType::isIMEBlockSize16(RV32VType, 32));
-
-  uint64_t RV64VType = RISCVVType::addIMEVTypeFields(
+  EXPECT_EQ(0x7e000000ULL, RISCVVType::IME::getVTypeFieldsMask(32));
+  EXPECT_EQ(3U, RISCVVType::IME::getLambdaEncoding(RV32VType, 32));
+  EXPECT_EQ(4U, *RISCVVType::IME::getLambda(RV32VType, 32));
+  EXPECT_TRUE(RISCVVType::IME::isAltFmtA(RV32VType, 32));
+  EXPECT_FALSE(RISCVVType::IME::isAltFmtB(RV32VType, 32));
+  EXPECT_TRUE(RISCVVType::IME::isBlockSize16(RV32VType, 32));
+
+  uint64_t RV64VType = RISCVVType::IME::addVTypeFields(
       BaseVType, /*XLen=*/64, /*Lambda=*/64, /*AltFmtA=*/true,
       /*AltFmtB=*/true, /*BlockSize16=*/true);
   EXPECT_EQ(0x7e000000000000d0ULL, RV64VType);
-  EXPECT_EQ(0x7e00000000000000ULL, RISCVVType::getIMEVTypeFieldsMask(64));
-  EXPECT_EQ(7U, RISCVVType::getIMELambdaEncoding(RV64VType, 64));
-  EXPECT_EQ(64U, *RISCVVType::getIMELambda(RV64VType, 64));
-  EXPECT_TRUE(RISCVVType::isIMEAltFmtA(RV64VType, 64));
-  EXPECT_TRUE(RISCVVType::isIMEAltFmtB(RV64VType, 64));
-  EXPECT_TRUE(RISCVVType::isIMEBlockSize16(RV64VType, 64));
-
-  uint64_t DynamicLambda = RISCVVType::addIMEVTypeFields(
+  EXPECT_EQ(0x7e00000000000000ULL, RISCVVType::IME::getVTypeFieldsMask(64));
+  EXPECT_EQ(7U, RISCVVType::IME::getLambdaEncoding(RV64VType, 64));
+  EXPECT_EQ(64U, *RISCVVType::IME::getLambda(RV64VType, 64));
+  EXPECT_TRUE(RISCVVType::IME::isAltFmtA(RV64VType, 64));
+  EXPECT_TRUE(RISCVVType::IME::isAltFmtB(RV64VType, 64));
+  EXPECT_TRUE(RISCVVType::IME::isBlockSize16(RV64VType, 64));
+
+  uint64_t DynamicLambda = RISCVVType::IME::addVTypeFields(
       BaseVType, /*XLen=*/64, /*Lambda=*/0, /*AltFmtA=*/false,
       /*AltFmtB=*/false, /*BlockSize16=*/false);
-  EXPECT_FALSE(RISCVVType::getIMELambda(DynamicLambda, 64));
+  EXPECT_FALSE(RISCVVType::IME::getLambda(DynamicLambda, 64));
   EXPECT_EQ(BaseVType, DynamicLambda);
 }
 



More information about the cfe-commits mailing list