[clang] [llvm] [RISCV] Add SpacemiT XSMTVDot (SpacemiT Vector Dot Product) extension. (PR #151706)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 13 18:52:17 PDT 2025
https://github.com/link-xyq updated https://github.com/llvm/llvm-project/pull/151706
>From bc0277022da5020cf8e4903e4d518bbd844026a5 Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Fri, 1 Aug 2025 22:26:16 +0800
Subject: [PATCH 01/15] [RISCV] Add SpacemiT XSMTVDot (SpacemiT Vector Dot
Product) extension.
The full spec can be found at spacemit-x60 processor support scope: Section 2.1.2.2 (Features):
https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1
This patch only supports assembler.
---
.../Driver/print-supported-extensions-riscv.c | 1 +
llvm/docs/RISCVUsage.rst | 3 +
.../RISCV/Disassembler/RISCVDisassembler.cpp | 14 ++
llvm/lib/Target/RISCV/RISCVFeatures.td | 8 +
llvm/lib/Target/RISCV/RISCVInstrInfo.td | 1 +
.../Target/RISCV/RISCVInstrInfoXSMTVDot.td | 141 ++++++++++++++++++
llvm/test/CodeGen/RISCV/features-info.ll | 1 +
llvm/test/MC/RISCV/rvv/xsmtvdot.s | 114 ++++++++++++++
.../TargetParser/RISCVISAInfoTest.cpp | 1 +
9 files changed, 284 insertions(+)
create mode 100644 llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
create mode 100644 llvm/test/MC/RISCV/rvv/xsmtvdot.s
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 2503f2473d64a..1015ad3c0faa6 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -192,6 +192,7 @@
// CHECK-NEXT: xsfvqmaccqoq 1.0 'XSfvqmaccqoq' (SiFive Int8 Matrix Multiplication Instructions (4-by-8 and 8-by-4))
// CHECK-NEXT: xsifivecdiscarddlone 1.0 'XSiFivecdiscarddlone' (SiFive sf.cdiscard.d.l1 Instruction)
// CHECK-NEXT: xsifivecflushdlone 1.0 'XSiFivecflushdlone' (SiFive sf.cflush.d.l1 Instruction)
+// CHECK-NEXT: xsmtvdot 1.0 'XSMTVDot' (SpacemiT Vector Dot Product Extension)
// CHECK-NEXT: xtheadba 1.0 'XTHeadBa' (T-Head address calculation instructions)
// CHECK-NEXT: xtheadbb 1.0 'XTHeadBb' (T-Head basic bit-manipulation instructions)
// CHECK-NEXT: xtheadbs 1.0 'XTHeadBs' (T-Head single-bit instructions)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index a29e06cdf838d..442e8764b5dbb 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -531,6 +531,9 @@ The current vendor extensions supported are:
``XAndesVDot``
LLVM implements `version 5.0.0 of the Andes Vector Dot Product Extension specification <https://github.com/andestech/andes-v5-isa/releases/download/ast-v5_4_0-release/AndeStar_V5_ISA_Spec_UM165-v1.5.08-20250317.pdf>`__ by Andes Technology. All instructions are prefixed with `nds.` as described in the specification.
+``XSMTVDot``
+ LLVM implements `version 1.0.0 of the SpacemiT Vector Dot Product Extension specification <https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1>`__ by SpacemiT. All instructions are prefixed with `smt.` as described in the specification.
+
Experimental C Intrinsics
=========================
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index e0ac59141695f..cd2eb4a4a6a58 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -344,6 +344,17 @@ static DecodeStatus DecodeVMV0RegisterClass(MCInst &Inst, uint32_t RegNo,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeVREvenRegisterClass(MCInst &Inst, uint32_t RegNo,
+ uint64_t Address,
+ const MCDisassembler *Decoder) {
+ if (RegNo >= 32 || RegNo % 2)
+ return MCDisassembler::Fail;
+
+ MCRegister Reg = RISCV::V0 + RegNo;
+ Inst.addOperand(MCOperand::createReg(Reg));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeTRRegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
@@ -672,6 +683,8 @@ static constexpr FeatureBitset XAndesGroup = {
RISCV::FeatureVendorXAndesVSIntLoad, RISCV::FeatureVendorXAndesVPackFPH,
RISCV::FeatureVendorXAndesVDot};
+static constexpr FeatureBitset XSMTGroup = {RISCV::FeatureVendorXSMTVDot};
+
static constexpr DecoderListEntry DecoderList32[]{
// Vendor Extensions
{DecoderTableXCV32, XCVFeatureGroup, "CORE-V extensions"},
@@ -692,6 +705,7 @@ static constexpr DecoderListEntry DecoderList32[]{
{RISCV::FeatureVendorXMIPSCBOP},
"MIPS mips.pref"},
{DecoderTableXAndes32, XAndesGroup, "Andes extensions"},
+ {DecoderTableXSMT32, XSMTGroup, "SpacemiT extensions"},
// Standard Extensions
{DecoderTable32, {}, "standard 32-bit instructions"},
{DecoderTableRV32Only32, {}, "RV32-only standard 32-bit instructions"},
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index a7329d201f880..28da8191abfad 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1642,6 +1642,14 @@ def HasVendorXAndesVDot
AssemblerPredicate<(all_of FeatureVendorXAndesVDot),
"'XAndesVDot' (Andes Vector Dot Product Extension)">;
+def FeatureVendorXSMTVDot
+ : RISCVExtension<1, 0, "SpacemiT Vector Dot Product Extension",
+ [FeatureStdExtV]>;
+def HasVendorXSMTVDot
+ : Predicate<"Subtarget->hasVendorXSMTVDot()">,
+ AssemblerPredicate<(all_of FeatureVendorXSMTVDot),
+ "'XSMTVDot' (SpacemiT Vector Dot Product Extension)">;
+
//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 8bd383033f11c..ae4f9c338ae81 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2367,6 +2367,7 @@ include "RISCVInstrInfoXqccmp.td"
include "RISCVInstrInfoXMips.td"
include "RISCVInstrInfoXRivos.td"
include "RISCVInstrInfoXAndes.td"
+include "RISCVInstrInfoXSMTVDot.td"
//===----------------------------------------------------------------------===//
// Global ISel
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
new file mode 100644
index 0000000000000..cccb8969da6f0
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
@@ -0,0 +1,141 @@
+//===-- RISCVInstrInfoXSMTVDot.td - SpacemiT Vector Dot Product ----*- 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 xsmtvdot vendor extensions defined by SpacemiT.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Operand definitions.
+//===----------------------------------------------------------------------===//
+
+class SMTVDotOpcode<bits<7> val> {
+ bits<7> Value = val;
+}
+
+class SMTVEncoding2<bits<2> val> {
+ bits<2> Value = val;
+}
+
+def OPMMA : SMTVDotOpcode<0b1110001>;
+def OPMMA_SLIDE : SMTVDotOpcode<0b1110011>;
+
+//===----------------------------------------------------------------------===//
+// Vector Dot-Product Sign Encoding
+// Defines the signed/unsigned mixing modes for vector dot-product operations.
+// Encoding format: [1:0] bits
+// 00: UU (Unsigned x Unsigned)
+// 01: US (Unsigned x Signed)
+// 10: SU (Signed x Unsigned)
+// 11: SS (Signed x Signed)
+//===----------------------------------------------------------------------===//
+def SMT_VDot_UU : SMTVEncoding2<0b00>;
+def SMT_VDot_US : SMTVEncoding2<0b01>;
+def SMT_VDot_SU : SMTVEncoding2<0b10>;
+def SMT_VDot_SS : SMTVEncoding2<0b11>;
+
+//===----------------------------------------------------------------------===//
+// Vector Dot-Product Sliding Window Modes
+// Encoding format: [1:0] bits
+// 00: Slide1 (1-element sliding stride)
+// 01: Slide2 (2-element sliding stride)
+// 10: Slide3 (3-element sliding stride)
+// 11: Reserved
+//
+// Used in sliding-window dot-product operations:
+// vd = vs1 • vs2.slide{1|2|3} // • = dot product
+//===----------------------------------------------------------------------===//
+def SMT_VDot_Slide1 : SMTVEncoding2<0b00>;
+def SMT_VDot_Slide2 : SMTVEncoding2<0b01>;
+def SMT_VDot_Slide3 : SMTVEncoding2<0b10>;
+
+//===----------------------------------------------------------------------===//
+// Instruction formats
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+// Base vector dot product (no slide) format.
+class RVInstVDot<bits<2> sign, string opcodestr, string argstr>
+ : RVInst<(outs VR:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
+ bits<5> vd;
+ bits<5> vs1;
+ bits<5> vs2;
+
+ let Inst{31-25} = OPMMA.Value;
+ let Inst{24-20} = vs2;
+ let Inst{19-15} = vs1;
+ let Inst{14} = 0b0;
+ let Inst{13-12} = sign;
+ let Inst{11-8} = vd{4-1};
+ let Inst{7} = 0b0;
+ let Inst{6-0} = OPC_CUSTOM_1.Value;
+}
+
+// Sliding-window vector dot product format.
+class RVInstVDotSlide<bits<2>funct2, bits<2> sign, string opcodestr, string argstr>
+ : RVInst<(outs VR:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
+ bits<5> vd;
+ bits<5> vs1;
+ bits<5> vs2;
+
+ let Inst{31-25} = OPMMA_SLIDE.Value;
+ let Inst{24-20} = vs2;
+ let Inst{19-16} = vs1{4-1};
+ let Inst{15-14} = funct2;
+ let Inst{13-12} = sign;
+ let Inst{11-8} = vd{4-1};
+ let Inst{7} = 0b0;
+ let Inst{6-0} = OPC_CUSTOM_1.Value;
+}
+}
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+let DecoderNamespace = "XSMT" in {
+
+let Predicates = [HasVendorXSMTVDot] in {
+// Base vector dot product (no slide) instructions
+// NOTE: Destination registers (vd) MUST be even-numbered (v0, v2, ..., v30)
+// due to hardware alignment constraints. Using odd registers may cause undefined behavior.
+// TODO: Enforce even-numbered vd.
+def VMADOT : RVInstVDot<SMT_VDot_SS.Value{1-0}, "smt.vmadot", "$vd, $vs1, $vs2">;
+def VMADOTU : RVInstVDot<SMT_VDot_UU.Value{1-0}, "smt.vmadotu", "$vd, $vs1, $vs2">;
+def VMADOTSU : RVInstVDot<SMT_VDot_SU.Value{1-0}, "smt.vmadotsu", "$vd, $vs1, $vs2">;
+def VMADOTUU : RVInstVDot<SMT_VDot_US.Value{1-0}, "smt.vmadotus", "$vd, $vs1, $vs2">;
+
+//===----------------------------------------------------------------------===//
+// Sliding-window Vector Dot Product Instructions
+//
+// The numeric suffix (1, 2, 3) specifies the stride of the sliding window:
+// 1: Window slides by 1 element per operation
+// 2: Window slides by 2 elements per operation
+// 3: Window slides by 3 elements per operation
+//
+// These instructions compute dot products with overlapping operand windows
+// where the window position increments by <N> elements between computations.
+//===----------------------------------------------------------------------===//
+// NOTE: Destination registers (vd) and first source register (vs1) MUST be
+// even-numbered (v0, v2, ..., v30) due to hardware alignment constraints.
+// Using odd registers may cause undefined behavior.
+// TODO: Enforce even-numbered vd.
+def VMADOT1 : RVInstVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_SS.Value{1-0}, "smt.vmadot1", "$vd, $vs1, $vs2">;
+def VMADOT1U : RVInstVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_UU.Value{1-0}, "smt.vmadot1u", "$vd, $vs1, $vs2">;
+def VMADOT1SU : RVInstVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_SU.Value{1-0}, "smt.vmadot1su", "$vd, $vs1, $vs2">;
+def VMADOT1UU : RVInstVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_US.Value{1-0}, "smt.vmadot1us", "$vd, $vs1, $vs2">;
+def VMADOT2 : RVInstVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_SS.Value{1-0}, "smt.vmadot2", "$vd, $vs1, $vs2">;
+def VMADOT2U : RVInstVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_UU.Value{1-0}, "smt.vmadot2u", "$vd, $vs1, $vs2">;
+def VMADOT2SU : RVInstVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_SU.Value{1-0}, "smt.vmadot2su", "$vd, $vs1, $vs2">;
+def VMADOT2UU : RVInstVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_US.Value{1-0}, "smt.vmadot2us", "$vd, $vs1, $vs2">;
+def VMADOT3 : RVInstVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_SS.Value{1-0}, "smt.vmadot3", "$vd, $vs1, $vs2">;
+def VMADOT3U : RVInstVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_UU.Value{1-0}, "smt.vmadot3u", "$vd, $vs1, $vs2">;
+def VMADOT3SU : RVInstVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_SU.Value{1-0}, "smt.vmadot3su", "$vd, $vs1, $vs2">;
+def VMADOT3UU : RVInstVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_US.Value{1-0}, "smt.vmadot3us", "$vd, $vs1, $vs2">;
+}
+}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index fb539211fcc31..0cd0fb614d25f 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -217,6 +217,7 @@
; CHECK-NEXT: xsfvqmaccqoq - 'XSfvqmaccqoq' (SiFive Int8 Matrix Multiplication Instructions (4-by-8 and 8-by-4)).
; CHECK-NEXT: xsifivecdiscarddlone - 'XSiFivecdiscarddlone' (SiFive sf.cdiscard.d.l1 Instruction).
; CHECK-NEXT: xsifivecflushdlone - 'XSiFivecflushdlone' (SiFive sf.cflush.d.l1 Instruction).
+; CHECK-NEXT: xsmtvdot - 'XSMTVDot' (SpacemiT Vector Dot Product Extension).
; CHECK-NEXT: xtheadba - 'XTHeadBa' (T-Head address calculation instructions).
; CHECK-NEXT: xtheadbb - 'XTHeadBb' (T-Head basic bit-manipulation instructions).
; CHECK-NEXT: xtheadbs - 'XTHeadBs' (T-Head single-bit instructions).
diff --git a/llvm/test/MC/RISCV/rvv/xsmtvdot.s b/llvm/test/MC/RISCV/rvv/xsmtvdot.s
new file mode 100644
index 0000000000000..b1f943b9170be
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/xsmtvdot.s
@@ -0,0 +1,114 @@
+# RUN: llvm-mc -triple=riscv32 -show-encoding --mattr=+xsmtvdot %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+xsmtvdot %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: not llvm-mc -triple=riscv32 -show-encoding %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: not llvm-mc -triple=riscv64 -show-encoding %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+xsmtvdot %s \
+# RUN: | llvm-objdump -d --mattr=+xsmtvdot --no-print-imm-hex - \
+# RUN: | FileCheck %s --check-prefix=CHECK-INST
+# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+xsmtvdot %s \
+# RUN: | llvm-objdump -d --mattr=+xsmtvdot --no-print-imm-hex - \
+# RUN: | FileCheck %s --check-prefix=CHECK-INST
+# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+xsmtvdot %s \
+# RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+xsmtvdot %s \
+# RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+
+# CHECK-INST: smt.vmadot v16, v0, v8
+# CHECK-ENCODING: [0x2b,0x38,0x80,0xe2]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e280382b <unknown>
+smt.vmadot v16, v0, v8
+
+# CHECK-INST: smt.vmadotu v18, v1, v9
+# CHECK-ENCODING: [0x2b,0x89,0x90,0xe2]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e290892b <unknown>
+smt.vmadotu v18, v1, v9
+
+# CHECK-INST: smt.vmadotsu v20, v2, v10
+# CHECK-ENCODING: [0x2b,0x2a,0xa1,0xe2]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e2a12a2b <unknown>
+smt.vmadotsu v20, v2, v10
+
+# CHECK-INST: smt.vmadotus v22, v3, v11
+# CHECK-ENCODING: [0x2b,0x9b,0xb1,0xe2]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e2b19b2b <unknown>
+smt.vmadotus v22, v3, v11
+
+# CHECK-INST: smt.vmadot1 v24, v16, v12
+# CHECK-ENCODING: [0x2b,0x3c,0xc8,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e6c83c2b <unknown>
+smt.vmadot1 v24, v16, v12
+
+# CHECK-INST: smt.vmadot1u v26, v18, v13
+# CHECK-ENCODING: [0x2b,0x0d,0xd9,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e6d90d2b <unknown>
+smt.vmadot1u v26, v18, v13
+
+# CHECK-INST: smt.vmadot1su v28, v20, v14
+# CHECK-ENCODING: [0x2b,0x2e,0xea,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e6ea2e2b <unknown>
+smt.vmadot1su v28, v20, v14
+
+# CHECK-INST: smt.vmadot1us v30, v22, v15
+# CHECK-ENCODING: [0x2b,0x1f,0xfb,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e6fb1f2b <unknown>
+smt.vmadot1us v30, v22, v15
+
+# CHECK-INST: smt.vmadot2 v0, v24, v4
+# CHECK-ENCODING: [0x2b,0x70,0x4c,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e64c702b <unknown>
+smt.vmadot2 v0, v24, v4
+
+# CHECK-INST: smt.vmadot2u v2, v26, v5
+# CHECK-ENCODING: [0x2b,0x41,0x5d,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e65d412b <unknown>
+smt.vmadot2u v2, v26, v5
+
+# CHECK-INST: smt.vmadot2su v4, v28, v6
+# CHECK-ENCODING: [0x2b,0x62,0x6e,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e66e622b <unknown>
+smt.vmadot2su v4, v28, v6
+
+# CHECK-INST: smt.vmadot2us v6, v30, v7
+# CHECK-ENCODING: [0x2b,0x53,0x7f,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e67f532b <unknown>
+smt.vmadot2us v6, v30, v7
+
+# CHECK-INST: smt.vmadot3 v8, v0, v8
+# CHECK-ENCODING: [0x2b,0xb4,0x80,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e680b42b <unknown>
+smt.vmadot3 v8, v0, v8
+
+# CHECK-INST: smt.vmadot3u v10, v2, v9
+# CHECK-ENCODING: [0x2b,0x85,0x91,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e691852b <unknown>
+smt.vmadot3u v10, v2, v9
+
+# CHECK-INST: smt.vmadot3su v12, v4, v10
+# CHECK-ENCODING: [0x2b,0xa6,0xa2,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e6a2a62b <unknown>
+smt.vmadot3su v12, v4, v10
+
+# CHECK-INST: smt.vmadot3us v14, v6, v11
+# CHECK-ENCODING: [0x2b,0x97,0xb3,0xe6]
+# CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+# CHECK-UNKNOWN: e6b3972b <unknown>
+smt.vmadot3us v14, v6, v11
\ No newline at end of file
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 319538eaea135..8d828d346832e 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1163,6 +1163,7 @@ R"(All available -march extensions for RISC-V
xsfvqmaccqoq 1.0
xsifivecdiscarddlone 1.0
xsifivecflushdlone 1.0
+ xsmtvdot 1.0
xtheadba 1.0
xtheadbb 1.0
xtheadbs 1.0
>From fad4292cc23e55a9ed3d94e94323cc43af9e9ea0 Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Fri, 1 Aug 2025 23:51:39 +0800
Subject: [PATCH 02/15] [RISCV] Add xsmtvdot extension support for SPACEMIT_X60
target.
---
clang/test/Driver/riscv-cpus.c | 61 ++++++++++++------------
llvm/lib/Target/RISCV/RISCVProcessors.td | 1 +
2 files changed, 32 insertions(+), 30 deletions(-)
diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
index 2a9c4e7021feb..d330e2bf92169 100644
--- a/clang/test/Driver/riscv-cpus.c
+++ b/clang/test/Driver/riscv-cpus.c
@@ -41,38 +41,38 @@
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+b"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+v"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+h"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zic64b"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicbom"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicbop"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicboz"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccamoa"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccif"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicclsm"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccrse"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicntr"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicond"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicsr"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zihintntl"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zacas"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zawrs"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zfa"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zfh"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zca"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zcb"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zcmop"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zba"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbb"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zic64b"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicbom"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicbop"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicboz"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccamoa"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccif"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicclsm"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccrse"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicntr"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicond"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicsr"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zihintntl"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zacas"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zawrs"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zfa"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zfh"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zca"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zcb"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zcmop"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zba"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbb"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbc"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkb"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkc"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkx"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkb"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkc"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkx"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbs"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zkn"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zks"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zvbb"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64d"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64f"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64x"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zkn"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zks"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zvbb"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64d"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64f"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64x"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zvfh"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zvkb"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zvkt"
@@ -157,6 +157,7 @@
// MCPU-SPACEMIT-X60-SAME: "-target-feature" "+svinval"
// MCPU-SPACEMIT-X60-SAME: "-target-feature" "+svnapot"
// MCPU-SPACEMIT-X60-SAME: "-target-feature" "+svpbmt"
+// MCPU-SPACEMIT-X60-SAME: "-target-feature" "+xsmtvdot"
// MCPU-SPACEMIT-X60-SAME: "-target-abi" "lp64d"
// We cannot check much for -mcpu=native, but it should be replaced by a valid CPU string.
diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td b/llvm/lib/Target/RISCV/RISCVProcessors.td
index 31d2b3a10db53..f89d94f41b69f 100644
--- a/llvm/lib/Target/RISCV/RISCVProcessors.td
+++ b/llvm/lib/Target/RISCV/RISCVProcessors.td
@@ -673,6 +673,7 @@ def SPACEMIT_X60 : RISCVProcessorModel<"spacemit-x60",
FeatureStdExtZvfh,
FeatureStdExtZvkt,
FeatureStdExtZvl256b,
+ FeatureVendorXSMTVDot,
FeatureUnalignedScalarMem]),
[TuneDLenFactor2,
TuneOptimizedNF2SegmentLoadStore,
>From db1c9042e724cbe45e5ea3039452094b24219851 Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Mon, 4 Aug 2025 15:43:03 +0800
Subject: [PATCH 03/15] [Fix] code review.
---
.../RISCV/Disassembler/RISCVDisassembler.cpp | 11 ------
.../Target/RISCV/RISCVInstrInfoXSMTVDot.td | 38 +++++++++----------
2 files changed, 19 insertions(+), 30 deletions(-)
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index cd2eb4a4a6a58..78be55b3a51d3 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -344,17 +344,6 @@ static DecodeStatus DecodeVMV0RegisterClass(MCInst &Inst, uint32_t RegNo,
return MCDisassembler::Success;
}
-static DecodeStatus DecodeVREvenRegisterClass(MCInst &Inst, uint32_t RegNo,
- uint64_t Address,
- const MCDisassembler *Decoder) {
- if (RegNo >= 32 || RegNo % 2)
- return MCDisassembler::Fail;
-
- MCRegister Reg = RISCV::V0 + RegNo;
- Inst.addOperand(MCOperand::createReg(Reg));
- return MCDisassembler::Success;
-}
-
static DecodeStatus DecodeTRRegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
index cccb8969da6f0..721c2e2e83200 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
@@ -1,4 +1,4 @@
-//===-- RISCVInstrInfoXSMTVDot.td - SpacemiT Vector Dot Product ----*- tablegen -*-===//
+//===-- RISCVInstrInfoXSMTVDot.td --------------------------*- tablegen -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -60,7 +60,7 @@ def SMT_VDot_Slide3 : SMTVEncoding2<0b10>;
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
// Base vector dot product (no slide) format.
-class RVInstVDot<bits<2> sign, string opcodestr, string argstr>
+class RVInstSMTVDot<bits<2> sign, string opcodestr, string argstr>
: RVInst<(outs VR:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
@@ -77,7 +77,7 @@ class RVInstVDot<bits<2> sign, string opcodestr, string argstr>
}
// Sliding-window vector dot product format.
-class RVInstVDotSlide<bits<2>funct2, bits<2> sign, string opcodestr, string argstr>
+class RVInstSMTVDotSlide<bits<2>funct2, bits<2> sign, string opcodestr, string argstr>
: RVInst<(outs VR:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
@@ -105,10 +105,10 @@ let Predicates = [HasVendorXSMTVDot] in {
// NOTE: Destination registers (vd) MUST be even-numbered (v0, v2, ..., v30)
// due to hardware alignment constraints. Using odd registers may cause undefined behavior.
// TODO: Enforce even-numbered vd.
-def VMADOT : RVInstVDot<SMT_VDot_SS.Value{1-0}, "smt.vmadot", "$vd, $vs1, $vs2">;
-def VMADOTU : RVInstVDot<SMT_VDot_UU.Value{1-0}, "smt.vmadotu", "$vd, $vs1, $vs2">;
-def VMADOTSU : RVInstVDot<SMT_VDot_SU.Value{1-0}, "smt.vmadotsu", "$vd, $vs1, $vs2">;
-def VMADOTUU : RVInstVDot<SMT_VDot_US.Value{1-0}, "smt.vmadotus", "$vd, $vs1, $vs2">;
+def VMADOT : RVInstSMTVDot<SMT_VDot_SS.Value, "smt.vmadot", "$vd, $vs1, $vs2">;
+def VMADOTU : RVInstSMTVDot<SMT_VDot_UU.Value, "smt.vmadotu", "$vd, $vs1, $vs2">;
+def VMADOTSU : RVInstSMTVDot<SMT_VDot_SU.Value, "smt.vmadotsu", "$vd, $vs1, $vs2">;
+def VMADOTUU : RVInstSMTVDot<SMT_VDot_US.Value, "smt.vmadotus", "$vd, $vs1, $vs2">;
//===----------------------------------------------------------------------===//
// Sliding-window Vector Dot Product Instructions
@@ -125,17 +125,17 @@ def VMADOTUU : RVInstVDot<SMT_VDot_US.Value{1-0}, "smt.vmadotus", "$vd, $vs1, $v
// even-numbered (v0, v2, ..., v30) due to hardware alignment constraints.
// Using odd registers may cause undefined behavior.
// TODO: Enforce even-numbered vd.
-def VMADOT1 : RVInstVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_SS.Value{1-0}, "smt.vmadot1", "$vd, $vs1, $vs2">;
-def VMADOT1U : RVInstVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_UU.Value{1-0}, "smt.vmadot1u", "$vd, $vs1, $vs2">;
-def VMADOT1SU : RVInstVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_SU.Value{1-0}, "smt.vmadot1su", "$vd, $vs1, $vs2">;
-def VMADOT1UU : RVInstVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_US.Value{1-0}, "smt.vmadot1us", "$vd, $vs1, $vs2">;
-def VMADOT2 : RVInstVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_SS.Value{1-0}, "smt.vmadot2", "$vd, $vs1, $vs2">;
-def VMADOT2U : RVInstVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_UU.Value{1-0}, "smt.vmadot2u", "$vd, $vs1, $vs2">;
-def VMADOT2SU : RVInstVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_SU.Value{1-0}, "smt.vmadot2su", "$vd, $vs1, $vs2">;
-def VMADOT2UU : RVInstVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_US.Value{1-0}, "smt.vmadot2us", "$vd, $vs1, $vs2">;
-def VMADOT3 : RVInstVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_SS.Value{1-0}, "smt.vmadot3", "$vd, $vs1, $vs2">;
-def VMADOT3U : RVInstVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_UU.Value{1-0}, "smt.vmadot3u", "$vd, $vs1, $vs2">;
-def VMADOT3SU : RVInstVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_SU.Value{1-0}, "smt.vmadot3su", "$vd, $vs1, $vs2">;
-def VMADOT3UU : RVInstVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_US.Value{1-0}, "smt.vmadot3us", "$vd, $vs1, $vs2">;
+def VMADOT1 : RVInstSMTVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_SS.Value, "smt.vmadot1", "$vd, $vs1, $vs2">;
+def VMADOT1U : RVInstSMTVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_UU.Value, "smt.vmadot1u", "$vd, $vs1, $vs2">;
+def VMADOT1SU : RVInstSMTVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_SU.Value, "smt.vmadot1su", "$vd, $vs1, $vs2">;
+def VMADOT1UU : RVInstSMTVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_US.Value, "smt.vmadot1us", "$vd, $vs1, $vs2">;
+def VMADOT2 : RVInstSMTVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_SS.Value, "smt.vmadot2", "$vd, $vs1, $vs2">;
+def VMADOT2U : RVInstSMTVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_UU.Value, "smt.vmadot2u", "$vd, $vs1, $vs2">;
+def VMADOT2SU : RVInstSMTVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_SU.Value, "smt.vmadot2su", "$vd, $vs1, $vs2">;
+def VMADOT2UU : RVInstSMTVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_US.Value, "smt.vmadot2us", "$vd, $vs1, $vs2">;
+def VMADOT3 : RVInstSMTVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_SS.Value, "smt.vmadot3", "$vd, $vs1, $vs2">;
+def VMADOT3U : RVInstSMTVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_UU.Value, "smt.vmadot3u", "$vd, $vs1, $vs2">;
+def VMADOT3SU : RVInstSMTVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_SU.Value, "smt.vmadot3su", "$vd, $vs1, $vs2">;
+def VMADOT3UU : RVInstSMTVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_US.Value, "smt.vmadot3us", "$vd, $vs1, $vs2">;
}
}
\ No newline at end of file
>From 350d560f4992351b0bbb188eae46f4343bdf5abd Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Mon, 4 Aug 2025 18:40:07 +0800
Subject: [PATCH 04/15] [Fix] code review.
---
clang/test/Driver/riscv-cpus.c | 60 +++++++++++++++++-----------------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
index d330e2bf92169..ea0821cc39c45 100644
--- a/clang/test/Driver/riscv-cpus.c
+++ b/clang/test/Driver/riscv-cpus.c
@@ -41,38 +41,38 @@
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+b"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+v"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+h"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zic64b"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicbom"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicbop"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicboz"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccamoa"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccif"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicclsm"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccrse"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicntr"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicond"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicsr"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zihintntl"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zacas"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zawrs"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zfa"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zfh"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zca"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zcb"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zcmop"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zba"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbb"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zic64b"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicbom"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicbop"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicboz"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccamoa"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccif"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicclsm"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+ziccrse"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicntr"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicond"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zicsr"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zihintntl"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zacas"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zawrs"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zfa"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zfh"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zca"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zcb"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zcmop"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zba"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbb"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbc"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkb"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkc"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkx"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkb"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkc"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbkx"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zbs"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zkn"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zks"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zvbb"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64d"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64f"
-// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64x"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zkn"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zks"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zvbb"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64d"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64f"
+// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zve64x"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zvfh"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zvkb"
// MCPU-XIANGSHAN-KUNMINGHU-SAME: "-target-feature" "+zvkt"
>From 691f8854e3a7b48c1e49f46b451d96551ee62c5c Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Wed, 6 Aug 2025 10:51:52 +0800
Subject: [PATCH 05/15] [Fix] code review.
---
llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td | 2 +-
llvm/test/MC/RISCV/{rvv/xsmtvdot.s => xsmtvdot-valid.s} | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
rename llvm/test/MC/RISCV/{rvv/xsmtvdot.s => xsmtvdot-valid.s} (97%)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
index 721c2e2e83200..dcdd8f37c0969 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
@@ -77,7 +77,7 @@ class RVInstSMTVDot<bits<2> sign, string opcodestr, string argstr>
}
// Sliding-window vector dot product format.
-class RVInstSMTVDotSlide<bits<2>funct2, bits<2> sign, string opcodestr, string argstr>
+class RVInstSMTVDotSlide<bits<2> funct2, bits<2> sign, string opcodestr, string argstr>
: RVInst<(outs VR:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
diff --git a/llvm/test/MC/RISCV/rvv/xsmtvdot.s b/llvm/test/MC/RISCV/xsmtvdot-valid.s
similarity index 97%
rename from llvm/test/MC/RISCV/rvv/xsmtvdot.s
rename to llvm/test/MC/RISCV/xsmtvdot-valid.s
index b1f943b9170be..9e66419b10e16 100644
--- a/llvm/test/MC/RISCV/rvv/xsmtvdot.s
+++ b/llvm/test/MC/RISCV/xsmtvdot-valid.s
@@ -7,10 +7,10 @@
# RUN: not llvm-mc -triple=riscv64 -show-encoding %s 2>&1 \
# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+xsmtvdot %s \
-# RUN: | llvm-objdump -d --mattr=+xsmtvdot --no-print-imm-hex - \
+# RUN: | llvm-objdump -d --mattr=+xsmtvdot - \
# RUN: | FileCheck %s --check-prefix=CHECK-INST
# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+xsmtvdot %s \
-# RUN: | llvm-objdump -d --mattr=+xsmtvdot --no-print-imm-hex - \
+# RUN: | llvm-objdump -d --mattr=+xsmtvdot - \
# RUN: | FileCheck %s --check-prefix=CHECK-INST
# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+xsmtvdot %s \
# RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
>From ded591db639a4d54ded29a81d96bcb341c5a1026 Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Wed, 6 Aug 2025 16:09:52 +0800
Subject: [PATCH 06/15] [Refactor] Replace explicit .Value with type-safe
SMTVEncoding2 param.
---
.../Target/RISCV/RISCVInstrInfoXSMTVDot.td | 42 +++++++++----------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
index dcdd8f37c0969..1098686d6f2b1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
@@ -60,7 +60,7 @@ def SMT_VDot_Slide3 : SMTVEncoding2<0b10>;
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
// Base vector dot product (no slide) format.
-class RVInstSMTVDot<bits<2> sign, string opcodestr, string argstr>
+class RVInstSMTVDot<SMTVEncoding2 sign, string opcodestr, string argstr>
: RVInst<(outs VR:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
@@ -70,14 +70,14 @@ class RVInstSMTVDot<bits<2> sign, string opcodestr, string argstr>
let Inst{24-20} = vs2;
let Inst{19-15} = vs1;
let Inst{14} = 0b0;
- let Inst{13-12} = sign;
+ let Inst{13-12} = sign.Value;
let Inst{11-8} = vd{4-1};
let Inst{7} = 0b0;
let Inst{6-0} = OPC_CUSTOM_1.Value;
}
// Sliding-window vector dot product format.
-class RVInstSMTVDotSlide<bits<2> funct2, bits<2> sign, string opcodestr, string argstr>
+class RVInstSMTVDotSlide<SMTVEncoding2 funct2, SMTVEncoding2 sign, string opcodestr, string argstr>
: RVInst<(outs VR:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
@@ -86,8 +86,8 @@ class RVInstSMTVDotSlide<bits<2> funct2, bits<2> sign, string opcodestr, string
let Inst{31-25} = OPMMA_SLIDE.Value;
let Inst{24-20} = vs2;
let Inst{19-16} = vs1{4-1};
- let Inst{15-14} = funct2;
- let Inst{13-12} = sign;
+ let Inst{15-14} = funct2.Value;
+ let Inst{13-12} = sign.Value;
let Inst{11-8} = vd{4-1};
let Inst{7} = 0b0;
let Inst{6-0} = OPC_CUSTOM_1.Value;
@@ -105,10 +105,10 @@ let Predicates = [HasVendorXSMTVDot] in {
// NOTE: Destination registers (vd) MUST be even-numbered (v0, v2, ..., v30)
// due to hardware alignment constraints. Using odd registers may cause undefined behavior.
// TODO: Enforce even-numbered vd.
-def VMADOT : RVInstSMTVDot<SMT_VDot_SS.Value, "smt.vmadot", "$vd, $vs1, $vs2">;
-def VMADOTU : RVInstSMTVDot<SMT_VDot_UU.Value, "smt.vmadotu", "$vd, $vs1, $vs2">;
-def VMADOTSU : RVInstSMTVDot<SMT_VDot_SU.Value, "smt.vmadotsu", "$vd, $vs1, $vs2">;
-def VMADOTUU : RVInstSMTVDot<SMT_VDot_US.Value, "smt.vmadotus", "$vd, $vs1, $vs2">;
+def VMADOT : RVInstSMTVDot<SMT_VDot_SS, "smt.vmadot", "$vd, $vs1, $vs2">;
+def VMADOTU : RVInstSMTVDot<SMT_VDot_UU, "smt.vmadotu", "$vd, $vs1, $vs2">;
+def VMADOTSU : RVInstSMTVDot<SMT_VDot_SU, "smt.vmadotsu", "$vd, $vs1, $vs2">;
+def VMADOTUU : RVInstSMTVDot<SMT_VDot_US, "smt.vmadotus", "$vd, $vs1, $vs2">;
//===----------------------------------------------------------------------===//
// Sliding-window Vector Dot Product Instructions
@@ -125,17 +125,17 @@ def VMADOTUU : RVInstSMTVDot<SMT_VDot_US.Value, "smt.vmadotus", "$vd, $vs1, $vs2
// even-numbered (v0, v2, ..., v30) due to hardware alignment constraints.
// Using odd registers may cause undefined behavior.
// TODO: Enforce even-numbered vd.
-def VMADOT1 : RVInstSMTVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_SS.Value, "smt.vmadot1", "$vd, $vs1, $vs2">;
-def VMADOT1U : RVInstSMTVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_UU.Value, "smt.vmadot1u", "$vd, $vs1, $vs2">;
-def VMADOT1SU : RVInstSMTVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_SU.Value, "smt.vmadot1su", "$vd, $vs1, $vs2">;
-def VMADOT1UU : RVInstSMTVDotSlide<SMT_VDot_Slide1.Value, SMT_VDot_US.Value, "smt.vmadot1us", "$vd, $vs1, $vs2">;
-def VMADOT2 : RVInstSMTVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_SS.Value, "smt.vmadot2", "$vd, $vs1, $vs2">;
-def VMADOT2U : RVInstSMTVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_UU.Value, "smt.vmadot2u", "$vd, $vs1, $vs2">;
-def VMADOT2SU : RVInstSMTVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_SU.Value, "smt.vmadot2su", "$vd, $vs1, $vs2">;
-def VMADOT2UU : RVInstSMTVDotSlide<SMT_VDot_Slide2.Value, SMT_VDot_US.Value, "smt.vmadot2us", "$vd, $vs1, $vs2">;
-def VMADOT3 : RVInstSMTVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_SS.Value, "smt.vmadot3", "$vd, $vs1, $vs2">;
-def VMADOT3U : RVInstSMTVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_UU.Value, "smt.vmadot3u", "$vd, $vs1, $vs2">;
-def VMADOT3SU : RVInstSMTVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_SU.Value, "smt.vmadot3su", "$vd, $vs1, $vs2">;
-def VMADOT3UU : RVInstSMTVDotSlide<SMT_VDot_Slide3.Value, SMT_VDot_US.Value, "smt.vmadot3us", "$vd, $vs1, $vs2">;
+def VMADOT1 : RVInstSMTVDotSlide<SMT_VDot_Slide1, SMT_VDot_SS, "smt.vmadot1", "$vd, $vs1, $vs2">;
+def VMADOT1U : RVInstSMTVDotSlide<SMT_VDot_Slide1, SMT_VDot_UU, "smt.vmadot1u", "$vd, $vs1, $vs2">;
+def VMADOT1SU : RVInstSMTVDotSlide<SMT_VDot_Slide1, SMT_VDot_SU, "smt.vmadot1su", "$vd, $vs1, $vs2">;
+def VMADOT1UU : RVInstSMTVDotSlide<SMT_VDot_Slide1, SMT_VDot_US, "smt.vmadot1us", "$vd, $vs1, $vs2">;
+def VMADOT2 : RVInstSMTVDotSlide<SMT_VDot_Slide2, SMT_VDot_SS, "smt.vmadot2", "$vd, $vs1, $vs2">;
+def VMADOT2U : RVInstSMTVDotSlide<SMT_VDot_Slide2, SMT_VDot_UU, "smt.vmadot2u", "$vd, $vs1, $vs2">;
+def VMADOT2SU : RVInstSMTVDotSlide<SMT_VDot_Slide2, SMT_VDot_SU, "smt.vmadot2su", "$vd, $vs1, $vs2">;
+def VMADOT2UU : RVInstSMTVDotSlide<SMT_VDot_Slide2, SMT_VDot_US, "smt.vmadot2us", "$vd, $vs1, $vs2">;
+def VMADOT3 : RVInstSMTVDotSlide<SMT_VDot_Slide3, SMT_VDot_SS, "smt.vmadot3", "$vd, $vs1, $vs2">;
+def VMADOT3U : RVInstSMTVDotSlide<SMT_VDot_Slide3, SMT_VDot_UU, "smt.vmadot3u", "$vd, $vs1, $vs2">;
+def VMADOT3SU : RVInstSMTVDotSlide<SMT_VDot_Slide3, SMT_VDot_SU, "smt.vmadot3su", "$vd, $vs1, $vs2">;
+def VMADOT3UU : RVInstSMTVDotSlide<SMT_VDot_Slide3, SMT_VDot_US, "smt.vmadot3us", "$vd, $vs1, $vs2">;
}
}
\ No newline at end of file
>From 578a84b3aac5c3bfcda16e31c935447b1e1ad83e Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Thu, 7 Aug 2025 11:52:58 +0800
Subject: [PATCH 07/15] [RISCV] Enforce even-numbered vd for xsmtvdot.
---
.../RISCV/Disassembler/RISCVDisassembler.cpp | 11 ++++
.../Target/RISCV/RISCVInstrInfoXSMTVDot.td | 6 +--
llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 2 +
llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll | 4 +-
.../rvv/subregister-undef-early-clobber.mir | 12 ++---
llvm/test/MC/RISCV/xsmtvdot-invalid.s | 52 +++++++++++++++++++
6 files changed, 75 insertions(+), 12 deletions(-)
create mode 100644 llvm/test/MC/RISCV/xsmtvdot-invalid.s
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 78be55b3a51d3..85682cdbd0630 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -283,6 +283,17 @@ static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeVREvenRegisterClass(MCInst &Inst, uint32_t RegNo,
+ uint64_t Address,
+ const MCDisassembler *Decoder) {
+ if (RegNo >= 32 || RegNo % 2)
+ return MCDisassembler::Fail;
+
+ MCRegister Reg = RISCV::V0 + RegNo;
+ Inst.addOperand(MCOperand::createReg(Reg));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
index 1098686d6f2b1..5d0ce20590616 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
@@ -61,7 +61,7 @@ def SMT_VDot_Slide3 : SMTVEncoding2<0b10>;
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
// Base vector dot product (no slide) format.
class RVInstSMTVDot<SMTVEncoding2 sign, string opcodestr, string argstr>
- : RVInst<(outs VR:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
+ : RVInst<(outs VREven:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -78,7 +78,7 @@ class RVInstSMTVDot<SMTVEncoding2 sign, string opcodestr, string argstr>
// Sliding-window vector dot product format.
class RVInstSMTVDotSlide<SMTVEncoding2 funct2, SMTVEncoding2 sign, string opcodestr, string argstr>
- : RVInst<(outs VR:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
+ : RVInst<(outs VREven:$vd), (ins VREven:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -104,7 +104,6 @@ let Predicates = [HasVendorXSMTVDot] in {
// Base vector dot product (no slide) instructions
// NOTE: Destination registers (vd) MUST be even-numbered (v0, v2, ..., v30)
// due to hardware alignment constraints. Using odd registers may cause undefined behavior.
-// TODO: Enforce even-numbered vd.
def VMADOT : RVInstSMTVDot<SMT_VDot_SS, "smt.vmadot", "$vd, $vs1, $vs2">;
def VMADOTU : RVInstSMTVDot<SMT_VDot_UU, "smt.vmadotu", "$vd, $vs1, $vs2">;
def VMADOTSU : RVInstSMTVDot<SMT_VDot_SU, "smt.vmadotsu", "$vd, $vs1, $vs2">;
@@ -124,7 +123,6 @@ def VMADOTUU : RVInstSMTVDot<SMT_VDot_US, "smt.vmadotus", "$vd, $vs1, $vs2">;
// NOTE: Destination registers (vd) and first source register (vs1) MUST be
// even-numbered (v0, v2, ..., v30) due to hardware alignment constraints.
// Using odd registers may cause undefined behavior.
-// TODO: Enforce even-numbered vd.
def VMADOT1 : RVInstSMTVDotSlide<SMT_VDot_Slide1, SMT_VDot_SS, "smt.vmadot1", "$vd, $vs1, $vs2">;
def VMADOT1U : RVInstSMTVDotSlide<SMT_VDot_Slide1, SMT_VDot_UU, "smt.vmadot1u", "$vd, $vs1, $vs2">;
def VMADOT1SU : RVInstSMTVDotSlide<SMT_VDot_Slide1, SMT_VDot_SU, "smt.vmadot1su", "$vd, $vs1, $vs2">;
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index ccb39e8f42916..501adc17e7af7 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -787,6 +787,8 @@ def VR : VReg<!listconcat(VM1VTs, VMaskVTs),
def VRNoV0 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0), 1>;
+def VREven : VReg<!listconcat(VM1VTs, VMaskVTs), (add (sequence "V%u", 0, 31, 2)), 1>;
+
def VRM2 : VReg<VM2VTs, (add (sequence "V%uM2", 8, 31, 2),
(sequence "V%uM2", 6, 0, 2)), 2>;
diff --git a/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll
index 3633885bfa7d2..0304afe01092f 100644
--- a/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll
@@ -1220,9 +1220,9 @@ define void @mgather_nxv16i64(<vscale x 8 x ptr> %ptrs0, <vscale x 8 x ptr> %ptr
; RV32-LABEL: mgather_nxv16i64:
; RV32: # %bb.0:
; RV32-NEXT: vl8re64.v v24, (a0)
-; RV32-NEXT: csrr a0, vlenb
-; RV32-NEXT: vsetvli a2, zero, e64, m8, ta, mu
+; RV32-NEXT: vsetvli a0, zero, e64, m8, ta, mu
; RV32-NEXT: vluxei32.v v16, (zero), v8, v0.t
+; RV32-NEXT: csrr a0, vlenb
; RV32-NEXT: srli a2, a0, 3
; RV32-NEXT: vsetvli a3, zero, e8, mf4, ta, ma
; RV32-NEXT: vslidedown.vx v0, v0, a2
diff --git a/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir b/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
index 31d0996852b76..aa0e77c601f2c 100644
--- a/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
@@ -55,7 +55,7 @@ body: |
; CHECK-NEXT: %pt2:vrm4 = IMPLICIT_DEF
; CHECK-NEXT: [[INIT_UNDEF:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm2_1
- ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vr = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vreven = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm1_0
; CHECK-NEXT: early-clobber %6:vrm4 = PseudoVRGATHER_VI_M4 %pt2, killed [[INSERT_SUBREG2]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -131,7 +131,7 @@ body: |
; CHECK-NEXT: %pt2:vrm4 = IMPLICIT_DEF
; CHECK-NEXT: [[INIT_UNDEF:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrnov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vreven_and_vrnov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm1_2
; CHECK-NEXT: early-clobber %6:vrm4 = PseudoVRGATHER_VI_M4 %pt2, killed [[INSERT_SUBREG2]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -284,7 +284,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_1
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_1
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vr = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vreven = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_0
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -364,7 +364,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_1
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vreven_and_vrnov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_2
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -444,7 +444,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_3
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vreven_and_vrnov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_4
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -524,7 +524,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_2
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vreven_and_vrnov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_6
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
diff --git a/llvm/test/MC/RISCV/xsmtvdot-invalid.s b/llvm/test/MC/RISCV/xsmtvdot-invalid.s
new file mode 100644
index 0000000000000..9dce654ecc7f5
--- /dev/null
+++ b/llvm/test/MC/RISCV/xsmtvdot-invalid.s
@@ -0,0 +1,52 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+xsmtvdot < %s 2>&1 \
+# RUN: | FileCheck %s
+# RUN: not llvm-mc -triple riscv64 -mattr=+xsmtvdot < %s 2>&1 \
+# RUN: | FileCheck %s
+
+# NoSlide
+smt.vmadot v1, v2, v2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+smt.vmadotu v1, v2, v2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+smt.vmadotsu v1, v2, v2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+smt.vmadotus v1, v2, v2 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+
+# Slide = 1
+smt.vmadot1 v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot1u v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot1su v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot1us v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot1 v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot1u v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot1su v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot1us v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot1 v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot1u v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot1su v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot1us v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+
+# Slide = 2
+smt.vmadot2 v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot2u v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot2su v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot2us v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot2 v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot2u v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot2su v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot2us v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot2 v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot2u v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot2su v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot2us v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+
+# Slide = 3
+smt.vmadot3 v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot3u v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot3su v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot3us v1, v2, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot3 v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot3u v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot3su v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot3us v2, v1, v2 # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+smt.vmadot3 v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot3u v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot3su v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+smt.vmadot3us v1, v3, v2 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
\ No newline at end of file
>From 12ac7d0a1af9de7613d9d4b9334c2b1646f91208 Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Thu, 7 Aug 2025 15:25:34 +0800
Subject: [PATCH 08/15] [Fix] code review.
---
llvm/lib/Target/RISCV/RISCVFeatures.td | 2 +-
llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td | 2 ++
llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 3 ++-
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 28da8191abfad..6cc29fc841f20 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1644,7 +1644,7 @@ def HasVendorXAndesVDot
def FeatureVendorXSMTVDot
: RISCVExtension<1, 0, "SpacemiT Vector Dot Product Extension",
- [FeatureStdExtV]>;
+ [FeatureStdExtZve32f]>;
def HasVendorXSMTVDot
: Predicate<"Subtarget->hasVendorXSMTVDot()">,
AssemblerPredicate<(all_of FeatureVendorXSMTVDot),
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
index 5d0ce20590616..a0dc8f2f9e416 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
@@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
//
// This file describes the xsmtvdot vendor extensions defined by SpacemiT.
+// NOTE: This extension instructions only support cases where LMUL is less than
+// or equal to 1
//
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index 501adc17e7af7..34f58d5e126b4 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -787,7 +787,8 @@ def VR : VReg<!listconcat(VM1VTs, VMaskVTs),
def VRNoV0 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0), 1>;
-def VREven : VReg<!listconcat(VM1VTs, VMaskVTs), (add (sequence "V%u", 0, 31, 2)), 1>;
+def VREven : VReg<!listconcat(VM1VTs, VMaskVTs),
+ (add (sequence "V%u", 0, 30, 2)), 1>;
def VRM2 : VReg<VM2VTs, (add (sequence "V%uM2", 8, 31, 2),
(sequence "V%uM2", 6, 0, 2)), 2>;
>From 41d3afdfbe136ba5881ae98e7b5d7650b64fd8b5 Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Mon, 11 Aug 2025 12:29:12 +0800
Subject: [PATCH 09/15] [Fix] code review.
---
llvm/docs/RISCVUsage.rst | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 442e8764b5dbb..e13485e3a237a 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -532,7 +532,8 @@ The current vendor extensions supported are:
LLVM implements `version 5.0.0 of the Andes Vector Dot Product Extension specification <https://github.com/andestech/andes-v5-isa/releases/download/ast-v5_4_0-release/AndeStar_V5_ISA_Spec_UM165-v1.5.08-20250317.pdf>`__ by Andes Technology. All instructions are prefixed with `nds.` as described in the specification.
``XSMTVDot``
- LLVM implements `version 1.0.0 of the SpacemiT Vector Dot Product Extension specification <https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1>`__ by SpacemiT. All instructions are prefixed with `smt.` as described in the specification.
+ SpacemiT defines `Intrinsic Matrix Extension (IME) specification <https://github.com/space-mit/riscv-ime-extension-spec/releases/tag/v0429>`__.
+ LLVM implement the hardware-adapted subset for SpacemiT X60, documented at: `<https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1>`__by SpacemiT. All instructions are prefixed with `smt.` as described in the implementation guide. Note that this implemented subset is `version 1.0.0 of the SpacemiT Vector Dot Product Extension specification`__, which is strictly a subset of the full IME specification to reflect the capabilities of SpacemiT X60 hardware correctly.
Experimental C Intrinsics
=========================
>From 25afaa22579920b0d1e959f4a54891eac88b5750 Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Tue, 12 Aug 2025 11:37:42 +0800
Subject: [PATCH 10/15] [Fix] code review.
---
llvm/lib/Target/RISCV/RISCVInstrInfo.td | 2 +-
.../{RISCVInstrInfoXSMTVDot.td => RISCVInstrInfoXSpacemiT.td} | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
rename llvm/lib/Target/RISCV/{RISCVInstrInfoXSMTVDot.td => RISCVInstrInfoXSpacemiT.td} (98%)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index ae4f9c338ae81..5f4d15fcffc03 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2367,7 +2367,7 @@ include "RISCVInstrInfoXqccmp.td"
include "RISCVInstrInfoXMips.td"
include "RISCVInstrInfoXRivos.td"
include "RISCVInstrInfoXAndes.td"
-include "RISCVInstrInfoXSMTVDot.td"
+include "RISCVInstrInfoXSpacemiT.td"
//===----------------------------------------------------------------------===//
// Global ISel
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
similarity index 98%
rename from llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
rename to llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
index a0dc8f2f9e416..61f1e4c6c04b2 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSMTVDot.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
@@ -102,7 +102,7 @@ class RVInstSMTVDotSlide<SMTVEncoding2 funct2, SMTVEncoding2 sign, string opcode
let DecoderNamespace = "XSMT" in {
-let Predicates = [HasVendorXSMTVDot] in {
+let Predicates = [HasVendorXSMTVDot], ElementsDependOn = EltDepsVLMask in {
// Base vector dot product (no slide) instructions
// NOTE: Destination registers (vd) MUST be even-numbered (v0, v2, ..., v30)
// due to hardware alignment constraints. Using odd registers may cause undefined behavior.
>From 548e5ea73e436fe4ad7523e6c5c19ac571b0bf88 Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Tue, 12 Aug 2025 14:38:11 +0800
Subject: [PATCH 11/15] [Fix] Avoid change the register pressure.
---
llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 4 +++-
llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll | 4 ++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index 34f58d5e126b4..8d7051b854dbd 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -788,7 +788,9 @@ def VR : VReg<!listconcat(VM1VTs, VMaskVTs),
def VRNoV0 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0), 1>;
def VREven : VReg<!listconcat(VM1VTs, VMaskVTs),
- (add (sequence "V%u", 0, 30, 2)), 1>;
+ (add (sequence "V%u", 0, 30, 2)), 1>{
+ let GeneratePressureSet = 0;
+}
def VRM2 : VReg<VM2VTs, (add (sequence "V%uM2", 8, 31, 2),
(sequence "V%uM2", 6, 0, 2)), 2>;
diff --git a/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll
index 0304afe01092f..3633885bfa7d2 100644
--- a/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll
@@ -1220,9 +1220,9 @@ define void @mgather_nxv16i64(<vscale x 8 x ptr> %ptrs0, <vscale x 8 x ptr> %ptr
; RV32-LABEL: mgather_nxv16i64:
; RV32: # %bb.0:
; RV32-NEXT: vl8re64.v v24, (a0)
-; RV32-NEXT: vsetvli a0, zero, e64, m8, ta, mu
-; RV32-NEXT: vluxei32.v v16, (zero), v8, v0.t
; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: vsetvli a2, zero, e64, m8, ta, mu
+; RV32-NEXT: vluxei32.v v16, (zero), v8, v0.t
; RV32-NEXT: srli a2, a0, 3
; RV32-NEXT: vsetvli a3, zero, e8, mf4, ta, ma
; RV32-NEXT: vslidedown.vx v0, v0, a2
>From 388a795b40942ce24c15aae586b7103ff7be3e55 Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Tue, 12 Aug 2025 15:36:13 +0800
Subject: [PATCH 12/15] [Fix] Avoid changing the VL operand on these
instructions.
---
llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
index 61f1e4c6c04b2..d68b6a7292b01 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
@@ -102,7 +102,7 @@ class RVInstSMTVDotSlide<SMTVEncoding2 funct2, SMTVEncoding2 sign, string opcode
let DecoderNamespace = "XSMT" in {
-let Predicates = [HasVendorXSMTVDot], ElementsDependOn = EltDepsVLMask in {
+let Predicates = [HasVendorXSMTVDot], ElementsDependOn = EltDepsVL in {
// Base vector dot product (no slide) instructions
// NOTE: Destination registers (vd) MUST be even-numbered (v0, v2, ..., v30)
// due to hardware alignment constraints. Using odd registers may cause undefined behavior.
>From e7200aee8e6aa1adb4fa3b7a314994afacfd143d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9E=97=E5=85=8B?= <xuqian.link at gmail.com>
Date: Tue, 12 Aug 2025 16:21:28 +0800
Subject: [PATCH 13/15] Update llvm/lib/Target/RISCV/RISCVRegisterInfo.td
[Fix] code review.
Co-authored-by: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
---
llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index 8d7051b854dbd..49e24b9a8f42e 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -787,11 +787,9 @@ def VR : VReg<!listconcat(VM1VTs, VMaskVTs),
def VRNoV0 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0), 1>;
+let GeneratePressureSet = false in
def VREven : VReg<!listconcat(VM1VTs, VMaskVTs),
- (add (sequence "V%u", 0, 30, 2)), 1>{
- let GeneratePressureSet = 0;
-}
-
+ (add (sequence "V%u", 0, 30, 2)), 1>;
def VRM2 : VReg<VM2VTs, (add (sequence "V%uM2", 8, 31, 2),
(sequence "V%uM2", 6, 0, 2)), 2>;
>From 728e40b0e7432cfc4808b15135db82a5d5c7e78a Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Wed, 13 Aug 2025 14:00:38 +0800
Subject: [PATCH 14/15] [Fix] code review.
---
llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td | 2 +-
llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
index d68b6a7292b01..2604a793acfdf 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
@@ -1,4 +1,4 @@
-//===-- RISCVInstrInfoXSMTVDot.td --------------------------*- tablegen -*-===//
+//===-- RISCVInstrInfoXSpacemiT.td -------------------------*- tablegen -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index 49e24b9a8f42e..72b68a8317f88 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -788,8 +788,8 @@ def VR : VReg<!listconcat(VM1VTs, VMaskVTs),
def VRNoV0 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0), 1>;
let GeneratePressureSet = false in
-def VREven : VReg<!listconcat(VM1VTs, VMaskVTs),
- (add (sequence "V%u", 0, 30, 2)), 1>;
+def VREven : VReg<VM1VTs, (add (sequence "V%u", 0, 30, 2)), 1>;
+
def VRM2 : VReg<VM2VTs, (add (sequence "V%uM2", 8, 31, 2),
(sequence "V%uM2", 6, 0, 2)), 2>;
>From dc00fe9a6412aabaeb36be58e706f3beed3c0d60 Mon Sep 17 00:00:00 2001
From: xuqian <xuqian at spacemit.com>
Date: Wed, 13 Aug 2025 15:27:18 +0800
Subject: [PATCH 15/15] [Fix] code review.
---
.../Target/RISCV/Disassembler/RISCVDisassembler.cpp | 11 -----------
llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td | 8 +++-----
llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 3 ---
.../RISCV/rvv/subregister-undef-early-clobber.mir | 12 ++++++------
4 files changed, 9 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 85682cdbd0630..78be55b3a51d3 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -283,17 +283,6 @@ static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo,
return MCDisassembler::Success;
}
-static DecodeStatus DecodeVREvenRegisterClass(MCInst &Inst, uint32_t RegNo,
- uint64_t Address,
- const MCDisassembler *Decoder) {
- if (RegNo >= 32 || RegNo % 2)
- return MCDisassembler::Fail;
-
- MCRegister Reg = RISCV::V0 + RegNo;
- Inst.addOperand(MCOperand::createReg(Reg));
- return MCDisassembler::Success;
-}
-
static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
index 2604a793acfdf..95fc5a655ba66 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
@@ -6,9 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file describes the xsmtvdot vendor extensions defined by SpacemiT.
-// NOTE: This extension instructions only support cases where LMUL is less than
-// or equal to 1
+// This file describes the vendor extensions defined by SpacemiT.
//
//===----------------------------------------------------------------------===//
@@ -63,7 +61,7 @@ def SMT_VDot_Slide3 : SMTVEncoding2<0b10>;
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
// Base vector dot product (no slide) format.
class RVInstSMTVDot<SMTVEncoding2 sign, string opcodestr, string argstr>
- : RVInst<(outs VREven:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
+ : RVInst<(outs VRM2:$vd), (ins VR:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -80,7 +78,7 @@ class RVInstSMTVDot<SMTVEncoding2 sign, string opcodestr, string argstr>
// Sliding-window vector dot product format.
class RVInstSMTVDotSlide<SMTVEncoding2 funct2, SMTVEncoding2 sign, string opcodestr, string argstr>
- : RVInst<(outs VREven:$vd), (ins VREven:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
+ : RVInst<(outs VRM2:$vd), (ins VRM2:$vs1, VR:$vs2), opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index 72b68a8317f88..ccb39e8f42916 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -787,9 +787,6 @@ def VR : VReg<!listconcat(VM1VTs, VMaskVTs),
def VRNoV0 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0), 1>;
-let GeneratePressureSet = false in
-def VREven : VReg<VM1VTs, (add (sequence "V%u", 0, 30, 2)), 1>;
-
def VRM2 : VReg<VM2VTs, (add (sequence "V%uM2", 8, 31, 2),
(sequence "V%uM2", 6, 0, 2)), 2>;
diff --git a/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir b/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
index aa0e77c601f2c..31d0996852b76 100644
--- a/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
@@ -55,7 +55,7 @@ body: |
; CHECK-NEXT: %pt2:vrm4 = IMPLICIT_DEF
; CHECK-NEXT: [[INIT_UNDEF:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm2_1
- ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vreven = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vr = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm1_0
; CHECK-NEXT: early-clobber %6:vrm4 = PseudoVRGATHER_VI_M4 %pt2, killed [[INSERT_SUBREG2]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -131,7 +131,7 @@ body: |
; CHECK-NEXT: %pt2:vrm4 = IMPLICIT_DEF
; CHECK-NEXT: [[INIT_UNDEF:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vreven_and_vrnov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrnov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm1_2
; CHECK-NEXT: early-clobber %6:vrm4 = PseudoVRGATHER_VI_M4 %pt2, killed [[INSERT_SUBREG2]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -284,7 +284,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_1
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_1
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vreven = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vr = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_0
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -364,7 +364,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_1
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vreven_and_vrnov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_2
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -444,7 +444,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_3
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vreven_and_vrnov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_4
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -524,7 +524,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_2
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vreven_and_vrnov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_6
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
More information about the cfe-commits
mailing list