[clang] [llvm] [llvm][RISCV] Support batched dot product extensions MC layer (PR #196467)
Brandon Wu via cfe-commits
cfe-commits at lists.llvm.org
Thu May 7 22:23:29 PDT 2026
https://github.com/4vtomat updated https://github.com/llvm/llvm-project/pull/196467
>From c6aac76806158be49e7d723cc54b61a2ce3e9ae3 Mon Sep 17 00:00:00 2001
From: Brandon Wu <songwu0813 at gmail.com>
Date: Sat, 25 Oct 2025 03:16:01 +0800
Subject: [PATCH 1/3] [llvm][RISCV] Support batched dot product extensions MC
layer
spec:
https://github.com/aswaterman/riscv-misc/blob/main/isa/ldot-bdot/ldot-bdot.adoc#zvbdot-family-of-batched-dot-product-extensions-version-01
---
.../Driver/print-supported-extensions-riscv.c | 5 ++
.../test/Preprocessor/riscv-target-features.c | 40 +++++++++
llvm/docs/RISCVUsage.rst | 3 +
.../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 6 +-
.../RISCV/MCTargetDesc/RISCVInstPrinter.cpp | 6 +-
llvm/lib/Target/RISCV/RISCVFeatures.td | 39 +++++++++
llvm/lib/Target/RISCV/RISCVInstrInfo.td | 1 +
.../lib/Target/RISCV/RISCVInstrInfoZvbdota.td | 68 +++++++++++++++
llvm/test/CodeGen/RISCV/attributes.ll | 20 +++++
llvm/test/CodeGen/RISCV/features-info.ll | 5 ++
llvm/test/MC/RISCV/attribute-arch.s | 16 ++++
llvm/test/MC/RISCV/rvv/zvbdota-invalid.s | 18 ++++
llvm/test/MC/RISCV/rvv/zvbdota.s | 83 +++++++++++++++++++
.../TargetParser/RISCVISAInfoTest.cpp | 5 ++
14 files changed, 313 insertions(+), 2 deletions(-)
create mode 100644 llvm/lib/Target/RISCV/RISCVInstrInfoZvbdota.td
create mode 100644 llvm/test/MC/RISCV/rvv/zvbdota-invalid.s
create mode 100644 llvm/test/MC/RISCV/rvv/zvbdota.s
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 83920246d5dad..f16c8a0d1d46d 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -251,8 +251,13 @@
// CHECK-NEXT: zvbc32e 0.7 'Zvbc32e' (Vector Carryless Multiplication with 32-bits elements)
// CHECK-NEXT: zvdot4a8i 0.1 'Zvdot4a8i' (Vector 4-element Dot Product of packed 8-bit Integers)
// CHECK-NEXT: zvfbfa 0.1 'Zvfbfa' (Additional BF16 vector compute support)
+// CHECK-NEXT: zvfbdota32f 0.2 'Zvfbdota32f' (FP32 batched dot-product extension)
// CHECK-NEXT: zvfofp8min 0.2 'Zvfofp8min' (Vector OFP8 Converts)
+// CHECK-NEXT: zvfqwbdota8f 0.2 'Zvfqwbdota8f' (OCP FP8 batched dot-product extension)
+// CHECK-NEXT: zvfwbdota16bf 0.2 'Zvfwbdota16bf' (BF16 batched dot-product extension)
// CHECK-NEXT: zvkgs 0.7 'Zvkgs' (Vector-Scalar GCM instructions for Cryptography)
+// CHECK-NEXT: zvqwbdota16i 0.2 'Zvqwbdota16i' (16-bit integer batched dot-product extension)
+// CHECK-NEXT: zvqwbdota8i 0.2 'Zvqwbdota8i' (8-bit integer batched dot-product extension)
// CHECK-NEXT: zvvmm 0.1 'Zvvmm' (Integer Matrix Multiply-Accumulate)
// CHECK-NEXT: zvzip 0.1 'Zvzip' (Vector Reordering Structured Data)
// CHECK-NEXT: smpmpmt 0.6 'Smpmpmt' (PMP-based Memory Types Extension)
diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c
index 3882f2889eb59..295b24873ebca 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -1784,3 +1784,43 @@
// RUN: %clang --target=riscv64-unknown-linux-gnu -mcpu=sifive-p450 -E -dM %s \
// RUN: -o - | FileCheck %s --check-prefix=CHECK-MISALIGNED-FAST
// CHECK-MISALIGNED-FAST: __riscv_misaligned_fast 1
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN: -march=rv32i_zvqwbdota8i0p2 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZVQWBDOTA8I-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN: -march=rv64i_zvqwbdota8i0p2 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZVQWBDOTA8I-EXT %s
+// CHECK-ZVQWBDOTA8I-EXT: __riscv_zvqwbdota8i 2000{{$}}
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN: -march=rv32i_zvqwbdota16i0p2 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZVQWBDOTA16I-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN: -march=rv64i_zvqwbdota16i0p2 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZVQWBDOTA16I-EXT %s
+// CHECK-ZVQWBDOTA16I-EXT: __riscv_zvqwbdota16i 2000{{$}}
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN: -march=rv32i_zvfwbdota16bf0p2 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZVFWBDOTA16BF-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN: -march=rv64i_zvfwbdota16bf0p2 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZVFWBDOTA16BF-EXT %s
+// CHECK-ZVFWBDOTA16BF-EXT: __riscv_zvfwbdota16bf 2000{{$}}
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN: -march=rv32i_zvfqwbdota8f0p2 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZVFQWBDOTA8F-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN: -march=rv64i_zvfqwbdota8f0p2 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZVFQWBDOTA8F-EXT %s
+// CHECK-ZVFQWBDOTA8F-EXT: __riscv_zvfqwbdota8f 2000{{$}}
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN: -march=rv32i_zvfbdota32f0p2 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZVFBDOTA32F-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN: -march=rv64i_zvfbdota32f0p2 -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZVFBDOTA32F-EXT %s
+// CHECK-ZVFBDOTA32F-EXT: __riscv_zvfbdota32f 2000{{$}}
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 2c8805f5fe796..97f525cf2eff8 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -365,6 +365,9 @@ The primary goal of experimental support is to assist in the process of ratifica
``experimental-zvvmm``
LLVM implements the `0.1 draft specification <https://github.com/riscv/integrated-matrix-extension/blob/d2e64b4922f5c2c416761f3c7c997d4f0cf814d9/src/integrated-matrix.adoc>`__.
+``experimental-zvqwbdota8i``, ``experimental-zvqwbdota16i``, ``experimental-zvfqwbdota8f``, ``experimental-zvfwbdota16bf``, ``experimental-zvfbdota32f``
+ LLVM implements the `0.2 draft specification <https://github.com/aswaterman/riscv-misc/blob/main/isa/ldot-bdot/ldot-bdot.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/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index cbf3d0f518ac8..dacceab47c11e 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2432,7 +2432,11 @@ ParseStatus RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
if (STI->hasFeature(RISCV::FeatureStdExtZvfbfa) ||
STI->hasFeature(RISCV::FeatureStdExtZvfofp8min) ||
- STI->hasFeature(RISCV::FeatureVendorXSfvfbfexp16e))
+ STI->hasFeature(RISCV::FeatureVendorXSfvfbfexp16e) ||
+ STI->hasFeature(RISCV::FeatureStdExtZvqwbdota8i) ||
+ STI->hasFeature(RISCV::FeatureStdExtZvqwbdota16i) ||
+ STI->hasFeature(RISCV::FeatureStdExtZvfqwbdota8f) ||
+ STI->hasFeature(RISCV::FeatureStdExtZvfwbdota16bf))
return Error(
ErrorLoc,
"operand must be "
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index b381b8f7147fc..4edd9f65fab03 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -227,7 +227,11 @@ void RISCVInstPrinter::printVTypeI(const MCInst *MI, unsigned OpNo,
(RISCVVType::isAltFmt(Imm) &&
!(STI.hasFeature(RISCV::FeatureStdExtZvfbfa) ||
STI.hasFeature(RISCV::FeatureStdExtZvfofp8min) ||
- STI.hasFeature(RISCV::FeatureVendorXSfvfbfexp16e))) ||
+ STI.hasFeature(RISCV::FeatureVendorXSfvfbfexp16e) ||
+ STI.hasFeature(RISCV::FeatureStdExtZvqwbdota8i) ||
+ STI.hasFeature(RISCV::FeatureStdExtZvqwbdota16i) ||
+ STI.hasFeature(RISCV::FeatureStdExtZvfqwbdota8f) ||
+ STI.hasFeature(RISCV::FeatureStdExtZvfwbdota16bf))) ||
(Imm >> 9) != 0) {
O << formatImm(Imm);
return;
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index b905870a482ff..8042ae6372b1d 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -893,6 +893,45 @@ def HasStdExtZvvmm : Predicate<"Subtarget->hasStdExtZvvmm()">,
AssemblerPredicate<(all_of FeatureStdExtZvvmm),
"'Zvvmm' (Integer Matrix Multiply-Accumulate)">;
+// Zvbdota family of batched dot-product extensions
+def FeatureStdExtZvqwbdota8i
+ : RISCVExperimentalExtension<0, 2,
+ "8-bit integer batched dot-product extension",
+ [FeatureStdExtZve32x]>;
+def FeatureStdExtZvqwbdota16i
+ : RISCVExperimentalExtension<0, 2,
+ "16-bit integer batched dot-product extension",
+ [FeatureStdExtZve64x]>;
+def HasStdExtZvqwbdota8iOrZvqwbdota16i
+ : Predicate<"Subtarget->hasStdExtZvqwbdota8i() || Subtarget->hasStdExtZvqwbdota16i()">,
+ AssemblerPredicate<(any_of FeatureStdExtZvqwbdota8i,
+ FeatureStdExtZvqwbdota16i),
+ "'Zvqwbdota8i' or 'Zvqwbdota16i' (8-bit or 16-bit integer batched dot-product extension)">;
+
+def FeatureStdExtZvfwbdota16bf
+ : RISCVExperimentalExtension<0, 2,
+ "BF16 batched dot-product extension",
+ [FeatureStdExtZve32f]>;
+def HasStdExtZvfwbdota16bf : Predicate<"Subtarget->hasStdExtZvfwbdota16bf()">,
+ AssemblerPredicate<(all_of FeatureStdExtZvfwbdota16bf),
+ "'Zvfwbdota16bf' (BF16 batched dot-product extension)">;
+
+def FeatureStdExtZvfqwbdota8f
+ : RISCVExperimentalExtension<0, 2,
+ "OCP FP8 batched dot-product extension",
+ [FeatureStdExtZve32f]>;
+def HasStdExtZvfqwbdota8f: Predicate<"Subtarget->hasStdExtZvfqwbdota8f()">,
+ AssemblerPredicate<(all_of FeatureStdExtZvfqwbdota8f),
+ "'Zvfqwbdota8f' (OCP FP8 batched dot-product extension)">;
+
+def FeatureStdExtZvfbdota32f
+ : RISCVExperimentalExtension<0, 2,
+ "FP32 batched dot-product extension",
+ [FeatureStdExtZve32f]>;
+def HasStdExtZvfbdota32f : Predicate<"Subtarget->hasStdExtZvfbdota32f()">,
+ AssemblerPredicate<(all_of FeatureStdExtZvfbdota32f),
+ "'Zvfbdota32f' (FP32 batched dot-product extension)">;
+
// 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 3295d18a2d352..c0482d1067223 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2357,6 +2357,7 @@ include "RISCVInstrInfoZvdot4a8i.td"
include "RISCVInstrInfoZvfofp8min.td"
include "RISCVInstrInfoZvzip.td"
include "RISCVInstrInfoZvvmm.td"
+include "RISCVInstrInfoZvbdota.td"
// Packed SIMD
include "RISCVInstrInfoP.td"
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvbdota.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZvbdota.td
new file mode 100644
index 0000000000000..4733679385f46
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvbdota.td
@@ -0,0 +1,68 @@
+//===-- RISCVInstrInfoZvbdota.td - 'Zvbdota' 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 'Zvbdota'
+// extension, providing vector batched dot-product instructions.
+// This version is still experimental as the 'Zvbdota' extension hasn't been
+// ratified yet. Version 0.2.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction class definitions
+//===----------------------------------------------------------------------===//
+
+// Base class for Zvbdota integer instructions (uses OPC_OP_VE)
+class ZvbdotaVV<bits<6> funct6, RISCVVFormat opv, string opcodestr>
+ : RVInstVV<funct6, opv, (outs VR:$vd_wb),
+ (ins VR:$vd, VRM8:$vs2, VR:$vs1, uimm3:$ci, VMaskOp:$vm),
+ opcodestr, "$vd, $vs2, $vs1, $ci$vm"> {
+ bits<3> ci;
+ let Inst{24-23} = vs2{4-3};
+ let Inst{22-20} = ci;
+ let Inst{6-0} = OPC_OP_VE.Value;
+ let hasSideEffects = 0;
+ let mayLoad = 0;
+ let mayStore = 0;
+ let VS1VS2Constraint = Vrgather;
+ let Constraints = "@earlyclobber $vd_wb, $vd = $vd_wb";
+}
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+// Integer batched dot-product
+multiclass VBdotVV<string opcodestr, bits<6> funct6> {
+ def _VV : ZvbdotaVV<funct6, OPIVV, opcodestr>;
+}
+
+// Floating-point batched dot-product
+multiclass VBdotFVV<string opcodestr, bits<6> funct6> {
+ def _VV : ZvbdotaVV<funct6, OPFVV, opcodestr>;
+}
+
+// Integer Batched Dot-Product Instructions for 8-bit elements
+let Predicates = [HasStdExtZvqwbdota8iOrZvqwbdota16i] in {
+defm VQWBDOTAU : VBdotVV<"vqwbdotau.vv", 0b101110>; // Unsigned (funct6 = 0x2e)
+defm VQWBDOTAS : VBdotVV<"vqwbdotas.vv", 0b101111>; // Signed (funct6 = 0x2f)
+} // Predicates = [HasStdExtZvqwbdota8iOrZvqwbdota16i]
+
+// BF16 Batched Dot-Product Instructions
+let Predicates = [HasStdExtZvfwbdota16bf] in
+defm VFWBDOTA : VBdotFVV<"vfwbdota.vv", 0b101100>; // funct6 = 0x2c
+
+// OCP FP8 Batched Dot-Product Instructions
+let Predicates = [HasStdExtZvfqwbdota8f] in {
+defm VFQWBDOTA : VBdotFVV<"vfqwbdota.vv", 0b101110>; // E4M3 (funct6 = 0x2e)
+defm VFQWBDOTA_ALT : VBdotFVV<"vfqwbdota.alt.vv", 0b101111>; // E5M2 (funct6 = 0x2f)
+} // Predicates = [HasStdExtZvfqwbdota8f]
+
+// FP32 Batched Dot-Product Instructions
+let Predicates = [HasStdExtZvfbdota32f] in
+defm VFBDOTA : VBdotFVV<"vfbdota.vv", 0b101011>; // funct6 = 0x2b
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index 9da6766692e99..aaba91519a5cd 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -151,6 +151,11 @@
; RUN: llc -mtriple=riscv32 -mattr=+ssctr %s -o - | FileCheck --check-prefix=RV32SSCTR %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-p %s -o - | FileCheck --check-prefix=RV32P %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zibi %s -o - | FileCheck --check-prefix=RV32ZIBI %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvqwbdota8i %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVQWBDOTA8I %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvqwbdota16i %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVQWBDOTA16I %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvfwbdota16bf %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVFWBDOTA16BF %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvfqwbdota8f %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVFQWBDOTA8F %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvfbdota32f %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVFBDOTA32F %s
; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s
; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefixes=CHECK,RV64M %s
@@ -308,6 +313,11 @@
; RUN: llc -mtriple=riscv64 -mattr=+experimental-p %s -o - | FileCheck --check-prefix=RV64P %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-y %s -o - | FileCheck --check-prefix=RV64Y %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zibi %s -o - | FileCheck --check-prefix=RV64ZIBI %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvqwbdota8i %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVQWBDOTA8I %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvqwbdota16i %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVQWBDOTA16I %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvfwbdota16bf %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVFWBDOTA16BF %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvfqwbdota8f %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVFQWBDOTA8F %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvfbdota32f %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVFBDOTA32F %s
; Tests for profile features.
@@ -475,6 +485,11 @@
; RV32SSCTR: .attribute 5, "rv32i2p1_sscsrind1p0_ssctr1p0"
; RV32P: .attribute 5, "rv32i2p1_p0p21_zicsr2p0_zmmul1p0_zba1p0_zbb1p0"
; RV32ZIBI: .attribute 5, "rv32i2p1_zibi0p1"
+; RV32ZVQWBDOTA8I: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvqwbdota8i0p2"
+; RV32ZVQWBDOTA16I: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zve64x1p0_zvl32b1p0_zvl64b1p0_zvqwbdota16i0p2"
+; RV32ZVFWBDOTA16BF: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfwbdota16bf0p2_zvl32b1p0"
+; RV32ZVFQWBDOTA8F: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfqwbdota8f0p2_zvl32b1p0"
+; RV32ZVFBDOTA32F: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbdota32f0p2_zvl32b1p0"
; RV64M: .attribute 5, "rv64i2p1_m2p0_zmmul1p0"
; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0"
@@ -630,6 +645,11 @@
; RV64P: .attribute 5, "rv64i2p1_p0p21_zicsr2p0_zmmul1p0_zba1p0_zbb1p0"
; RV64Y: .attribute 5, "rv64i2p1_y0p96"
; RV64ZIBI: .attribute 5, "rv64i2p1_zibi0p1"
+; RV64ZVQWBDOTA8I: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvqwbdota8i0p2"
+; RV64ZVQWBDOTA16I: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zve64x1p0_zvl32b1p0_zvl64b1p0_zvqwbdota16i0p2"
+; RV64ZVFWBDOTA16BF: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfwbdota16bf0p2_zvl32b1p0"
+; RV64ZVFQWBDOTA8F: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfqwbdota8f0p2_zvl32b1p0"
+; RV64ZVFBDOTA32F: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbdota32f0p2_zvl32b1p0"
; RVI20U32: .attribute 5, "rv32i2p1"
; RVI20U64: .attribute 5, "rv64i2p1"
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 92e033cb90dc9..03c23937a6312 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -36,9 +36,14 @@
; CHECK-NEXT: experimental-zvabd - 'Zvabd' (Vector Absolute Difference).
; CHECK-NEXT: experimental-zvbc32e - 'Zvbc32e' (Vector Carryless Multiplication with 32-bits elements).
; CHECK-NEXT: experimental-zvdot4a8i - 'Zvdot4a8i' (Vector 4-element Dot Product of packed 8-bit Integers).
+; CHECK-NEXT: experimental-zvfbdota32f - 'Zvfbdota32f' (FP32 batched dot-product extension).
; CHECK-NEXT: experimental-zvfbfa - 'Zvfbfa' (Additional BF16 vector compute support).
; CHECK-NEXT: experimental-zvfofp8min - 'Zvfofp8min' (Vector OFP8 Converts).
+; CHECK-NEXT: experimental-zvfqwbdota8f - 'Zvfqwbdota8f' (OCP FP8 batched dot-product extension).
+; CHECK-NEXT: experimental-zvfwbdota16bf - 'Zvfwbdota16bf' (BF16 batched dot-product extension).
; CHECK-NEXT: experimental-zvkgs - 'Zvkgs' (Vector-Scalar GCM instructions for Cryptography).
+; CHECK-NEXT: experimental-zvqwbdota16i - 'Zvqwbdota16i' (16-bit integer batched dot-product extension).
+; CHECK-NEXT: experimental-zvqwbdota8i - 'Zvqwbdota8i' (8-bit integer batched dot-product extension).
; CHECK-NEXT: experimental-zvvmm - 'Zvvmm' (Integer Matrix Multiply-Accumulate).
; CHECK-NEXT: experimental-zvzip - 'Zvzip' (Vector Reordering Structured Data).
; CHECK-NEXT: f - 'F' (Single-Precision Floating-Point).
diff --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s
index 241fac8f2bd17..8032e3f9e1d5e 100644
--- a/llvm/test/MC/RISCV/attribute-arch.s
+++ b/llvm/test/MC/RISCV/attribute-arch.s
@@ -515,3 +515,19 @@
.attribute arch, "rv64i_p0p21"
# CHECK: attribute 5, "rv64i2p1_p0p21_zicsr2p0_zmmul1p0_zba1p0_zbb1p0"
+
+.attribute arch, "rv32iv_zvqwbdota8i0p2"
+# CHECK: attribute 5, "rv32i2p1_f2p2_d2p2_v1p0_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_zvqwbdota8i0p2"
+
+.attribute arch, "rv32iv_zvqwbdota16i0p2"
+# CHECK: attribute 5, "rv32i2p1_f2p2_d2p2_v1p0_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_zvqwbdota16i0p2"
+
+.attribute arch, "rv32iv_zvfwbdota16bf0p2"
+
+# CHECK: attribute 5, "rv32i2p1_f2p2_d2p2_v1p0_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvfwbdota16bf0p2_zvl128b1p0_zvl32b1p0_zvl64b1p0"
+
+.attribute arch, "rv32iv_zvfqwbdota8f0p2"
+# CHECK: attribute 5, "rv32i2p1_f2p2_d2p2_v1p0_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvfqwbdota8f0p2_zvl128b1p0_zvl32b1p0_zvl64b1p0"
+
+.attribute arch, "rv32iv_zvfbdota32f0p2"
+# CHECK: attribute 5, "rv32i2p1_f2p2_d2p2_v1p0_zicsr2p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvfbdota32f0p2_zvl128b1p0_zvl32b1p0_zvl64b1p0"
diff --git a/llvm/test/MC/RISCV/rvv/zvbdota-invalid.s b/llvm/test/MC/RISCV/rvv/zvbdota-invalid.s
new file mode 100644
index 0000000000000..019654375d7ab
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvbdota-invalid.s
@@ -0,0 +1,18 @@
+# RUN: not llvm-mc -triple=riscv64 -mattr=+experimental-zvqwbdota8i,+experimental-zvqwbdota16i,+experimental-zvfwbdota16bf,+experimental-zvfqwbdota8f,+experimental-zvfbdota32f %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+
+# Invalid vsetvli
+# CHECK-ERROR: operand must be e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]{{$}}
+vsetvli a0, zero, e888, m1, ta, ma
+
+# Invalid ci
+# CHECK-ERROR: immediate must be an integer in the range [0, 7]{{$}}
+vqwbdotau.vv v8, v16, v12, 8
+
+# Invalid vs2
+# CHECK-ERROR: invalid operand for instruction{{$}}
+vqwbdotau.vv v8, v17, v12, 1
+
+# Invalid vs2 and ci
+# CHECK-ERROR: invalid operand for instruction{{$}}
+vqwbdotau.vv v8, v17, v12, 8
diff --git a/llvm/test/MC/RISCV/rvv/zvbdota.s b/llvm/test/MC/RISCV/rvv/zvbdota.s
new file mode 100644
index 0000000000000..4e97665215666
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvv/zvbdota.s
@@ -0,0 +1,83 @@
+# RUN: llvm-mc -triple=riscv64 -show-encoding -mattr=+experimental-zvqwbdota8i,+experimental-zvqwbdota16i,+experimental-zvfwbdota16bf,+experimental-zvfqwbdota8f,+experimental-zvfbdota32f %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: not llvm-mc -triple=riscv64 -show-encoding -mattr=+v %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: llvm-mc -triple=riscv64 -filetype=obj -mattr=+experimental-zvqwbdota8i,+experimental-zvqwbdota16i,+experimental-zvfwbdota16bf,+experimental-zvfqwbdota8f,+experimental-zvfbdota32f %s \
+# RUN: | llvm-objdump -d --mattr=+experimental-zvqwbdota8i,+experimental-zvqwbdota16i,+experimental-zvfwbdota16bf,+experimental-zvfqwbdota8f,+experimental-zvfbdota32f --no-print-imm-hex - \
+# RUN: | FileCheck %s --check-prefix=CHECK-INST
+
+# CHECK-INST: vsetvli zero, zero, e8alt, m1, ta, ma
+# CHECK-ENCODING: [0x57,0x70,0x00,0x1c]
+vsetvli zero, zero, e8alt, m1, ta, ma
+
+# CHECK-INST: vsetvli zero, zero, e16alt, m1, ta, ma
+# CHECK-ENCODING: [0x57,0x70,0x80,0x1c]
+vsetvli zero, zero, e16alt, m1, ta, ma
+
+# Integer Batched Dot-Product Instructions
+
+# CHECK-INST: vqwbdotau.vv v8, v16, v12, 1
+# CHECK-ENCODING: [0x77,0x04,0x16,0xbb]
+# CHECK-ERROR: instruction requires the following: 'Zvqwbdota8i' or 'Zvqwbdota16i' (8-bit or 16-bit integer batched dot-product extension){{$}}
+vqwbdotau.vv v8, v16, v12, 1
+
+# CHECK-INST: vqwbdotau.vv v8, v16, v12, 2, v0.t
+# CHECK-ENCODING: [0x77,0x04,0x26,0xb9]
+# CHECK-ERROR: instruction requires the following: 'Zvqwbdota8i' or 'Zvqwbdota16i' (8-bit or 16-bit integer batched dot-product extension){{$}}
+vqwbdotau.vv v8, v16, v12, 2, v0.t
+
+# CHECK-INST: vqwbdotas.vv v8, v16, v12, 1
+# CHECK-ENCODING: [0x77,0x04,0x16,0xbf]
+# CHECK-ERROR: instruction requires the following: 'Zvqwbdota8i' or 'Zvqwbdota16i' (8-bit or 16-bit integer batched dot-product extension){{$}}
+vqwbdotas.vv v8, v16, v12, 1
+
+# CHECK-INST: vqwbdotas.vv v8, v16, v12, 2, v0.t
+# CHECK-ENCODING: [0x77,0x04,0x26,0xbd]
+# CHECK-ERROR: instruction requires the following: 'Zvqwbdota8i' or 'Zvqwbdota16i' (8-bit or 16-bit integer batched dot-product extension){{$}}
+vqwbdotas.vv v8, v16, v12, 2, v0.t
+
+# BF16 Batched Dot-Product Instructions
+
+# CHECK-INST: vfwbdota.vv v8, v16, v12, 1
+# CHECK-ENCODING: [0x77,0x14,0x16,0xb3]
+# CHECK-ERROR: instruction requires the following: 'Zvfwbdota16bf' (BF16 batched dot-product extension){{$}}
+vfwbdota.vv v8, v16, v12, 1
+
+# CHECK-INST: vfwbdota.vv v8, v16, v12, 2, v0.t
+# CHECK-ENCODING: [0x77,0x14,0x26,0xb1]
+# CHECK-ERROR: instruction requires the following: 'Zvfwbdota16bf' (BF16 batched dot-product extension){{$}}
+vfwbdota.vv v8, v16, v12, 2, v0.t
+
+# FP8 Batched Dot-Product Instructions
+
+# CHECK-INST: vfqwbdota.vv v8, v16, v12, 1
+# CHECK-ENCODING: [0x77,0x14,0x16,0xbb]
+# CHECK-ERROR: instruction requires the following: 'Zvfqwbdota8f' (OCP FP8 batched dot-product extension){{$}}
+vfqwbdota.vv v8, v16, v12, 1
+
+# CHECK-INST: vfqwbdota.vv v8, v16, v12, 2, v0.t
+# CHECK-ENCODING: [0x77,0x14,0x26,0xb9]
+# CHECK-ERROR: instruction requires the following: 'Zvfqwbdota8f' (OCP FP8 batched dot-product extension){{$}}
+vfqwbdota.vv v8, v16, v12, 2, v0.t
+
+# CHECK-INST: vfqwbdota.alt.vv v8, v16, v12, 1
+# CHECK-ENCODING: [0x77,0x14,0x16,0xbf]
+# CHECK-ERROR: instruction requires the following: 'Zvfqwbdota8f' (OCP FP8 batched dot-product extension){{$}}
+vfqwbdota.alt.vv v8, v16, v12, 1
+
+# CHECK-INST: vfqwbdota.alt.vv v8, v16, v12, 2, v0.t
+# CHECK-ENCODING: [0x77,0x14,0x26,0xbd]
+# CHECK-ERROR: instruction requires the following: 'Zvfqwbdota8f' (OCP FP8 batched dot-product extension){{$}}
+vfqwbdota.alt.vv v8, v16, v12, 2, v0.t
+
+# FP32 Batched Dot-Product Instructions
+
+# CHECK-INST: vfbdota.vv v8, v16, v12, 1
+# CHECK-ENCODING: [0x77,0x14,0x16,0xaf]
+# CHECK-ERROR: instruction requires the following: 'Zvfbdota32f' (FP32 batched dot-product extension){{$}}
+vfbdota.vv v8, v16, v12, 1
+
+# CHECK-INST: vfbdota.vv v8, v16, v12, 2, v0.t
+# CHECK-ENCODING: [0x77,0x14,0x26,0xad]
+# CHECK-ERROR: instruction requires the following: 'Zvfbdota32f' (FP32 batched dot-product extension){{$}}
+vfbdota.vv v8, v16, v12, 2, v0.t
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index e96e2d9d462dc..86b6086270d2f 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1381,9 +1381,14 @@ Experimental extensions
zvabd 0.7
zvbc32e 0.7
zvdot4a8i 0.1
+ zvfbdota32f 0.2
zvfbfa 0.1
zvfofp8min 0.2
+ zvfqwbdota8f 0.2
+ zvfwbdota16bf 0.2
zvkgs 0.7
+ zvqwbdota16i 0.2
+ zvqwbdota8i 0.2
zvvmm 0.1
zvzip 0.1
smpmpmt 0.6
>From fbbad52fdfca98115b0fa2b9e2ebe5f2b9789dc4 Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Thu, 7 May 2026 22:22:26 -0700
Subject: [PATCH 2/3] fixup! indent
---
llvm/lib/Target/RISCV/RISCVFeatures.td | 28 +++++++++++++++-----------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 8042ae6372b1d..e7073b96d9d49 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -904,33 +904,37 @@ def FeatureStdExtZvqwbdota16i
[FeatureStdExtZve64x]>;
def HasStdExtZvqwbdota8iOrZvqwbdota16i
: Predicate<"Subtarget->hasStdExtZvqwbdota8i() || Subtarget->hasStdExtZvqwbdota16i()">,
- AssemblerPredicate<(any_of FeatureStdExtZvqwbdota8i,
- FeatureStdExtZvqwbdota16i),
- "'Zvqwbdota8i' or 'Zvqwbdota16i' (8-bit or 16-bit integer batched dot-product extension)">;
+ AssemblerPredicate<(any_of FeatureStdExtZvqwbdota8i,
+ FeatureStdExtZvqwbdota16i),
+ "'Zvqwbdota8i' or 'Zvqwbdota16i' (8-bit or 16-bit "
+ "integer batched dot-product extension)">;
def FeatureStdExtZvfwbdota16bf
: RISCVExperimentalExtension<0, 2,
"BF16 batched dot-product extension",
[FeatureStdExtZve32f]>;
-def HasStdExtZvfwbdota16bf : Predicate<"Subtarget->hasStdExtZvfwbdota16bf()">,
- AssemblerPredicate<(all_of FeatureStdExtZvfwbdota16bf),
- "'Zvfwbdota16bf' (BF16 batched dot-product extension)">;
+def HasStdExtZvfwbdota16bf
+ : Predicate<"Subtarget->hasStdExtZvfwbdota16bf()">,
+ AssemblerPredicate<(all_of FeatureStdExtZvfwbdota16bf),
+ "'Zvfwbdota16bf' (BF16 batched dot-product extension)">;
def FeatureStdExtZvfqwbdota8f
: RISCVExperimentalExtension<0, 2,
"OCP FP8 batched dot-product extension",
[FeatureStdExtZve32f]>;
-def HasStdExtZvfqwbdota8f: Predicate<"Subtarget->hasStdExtZvfqwbdota8f()">,
- AssemblerPredicate<(all_of FeatureStdExtZvfqwbdota8f),
- "'Zvfqwbdota8f' (OCP FP8 batched dot-product extension)">;
+def HasStdExtZvfqwbdota8f
+ : Predicate<"Subtarget->hasStdExtZvfqwbdota8f()">,
+ AssemblerPredicate<(all_of FeatureStdExtZvfqwbdota8f),
+ "'Zvfqwbdota8f' (OCP FP8 batched dot-product extension)">;
def FeatureStdExtZvfbdota32f
: RISCVExperimentalExtension<0, 2,
"FP32 batched dot-product extension",
[FeatureStdExtZve32f]>;
-def HasStdExtZvfbdota32f : Predicate<"Subtarget->hasStdExtZvfbdota32f()">,
- AssemblerPredicate<(all_of FeatureStdExtZvfbdota32f),
- "'Zvfbdota32f' (FP32 batched dot-product extension)">;
+def HasStdExtZvfbdota32f
+ : Predicate<"Subtarget->hasStdExtZvfbdota32f()">,
+ AssemblerPredicate<(all_of FeatureStdExtZvfbdota32f),
+ "'Zvfbdota32f' (FP32 batched dot-product extension)">;
// Vector instruction predicates
>From e0a0284450fc7b68fdaac3ed6040633e7f19c214 Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Thu, 7 May 2026 22:23:14 -0700
Subject: [PATCH 3/3] fixup! update test
---
clang/test/Driver/print-supported-extensions-riscv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index f16c8a0d1d46d..ff3542ed71454 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -250,8 +250,8 @@
// CHECK-NEXT: zvabd 0.7 'Zvabd' (Vector Absolute Difference)
// CHECK-NEXT: zvbc32e 0.7 'Zvbc32e' (Vector Carryless Multiplication with 32-bits elements)
// CHECK-NEXT: zvdot4a8i 0.1 'Zvdot4a8i' (Vector 4-element Dot Product of packed 8-bit Integers)
-// CHECK-NEXT: zvfbfa 0.1 'Zvfbfa' (Additional BF16 vector compute support)
// CHECK-NEXT: zvfbdota32f 0.2 'Zvfbdota32f' (FP32 batched dot-product extension)
+// CHECK-NEXT: zvfbfa 0.1 'Zvfbfa' (Additional BF16 vector compute support)
// CHECK-NEXT: zvfofp8min 0.2 'Zvfofp8min' (Vector OFP8 Converts)
// CHECK-NEXT: zvfqwbdota8f 0.2 'Zvfqwbdota8f' (OCP FP8 batched dot-product extension)
// CHECK-NEXT: zvfwbdota16bf 0.2 'Zvfwbdota16bf' (BF16 batched dot-product extension)
More information about the cfe-commits
mailing list