[Mlir-commits] [mlir] [MLIR][NVVM] Support sp{de}compress MLIR Ops (PR #232731)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Oct 16 06:04:15 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-llvm
Author: Kirill Vedernikov (kvederni)
<details>
<summary>Changes</summary>
This change adds support for `spcompress` and `spdecompress` MLIR Ops.
---
Patch is 184.24 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/232731.diff
14 Files Affected:
- (modified) mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td (+276)
- (modified) mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp (+145)
- (added) mlir/test/Target/LLVMIR/nvvm/spcompress-invalid.mlir (+80)
- (added) mlir/test/Target/LLVMIR/nvvm/spcompress-sp2to4.mlir (+449)
- (added) mlir/test/Target/LLVMIR/nvvm/spdecompress-invalid.mlir (+110)
- (added) mlir/test/Target/LLVMIR/nvvm/spdecompress-sp1to16.mlir (+158)
- (added) mlir/test/Target/LLVMIR/nvvm/spdecompress-sp1to2.mlir (+369)
- (added) mlir/test/Target/LLVMIR/nvvm/spdecompress-sp1to4.mlir (+399)
- (added) mlir/test/Target/LLVMIR/nvvm/spdecompress-sp1to8.mlir (+186)
- (added) mlir/test/Target/LLVMIR/nvvm/spdecompress-sp2to16.mlir (+156)
- (added) mlir/test/Target/LLVMIR/nvvm/spdecompress-sp2to4.mlir (+395)
- (added) mlir/test/Target/LLVMIR/nvvm/spdecompress-sp2to8.mlir (+184)
- (added) mlir/test/Target/LLVMIR/nvvm/spdecompress-sp4to16.mlir (+85)
- (added) mlir/test/Target/LLVMIR/nvvm/spdecompress-sp4to8.mlir (+99)
``````````diff
diff --git a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
index 79eda3fee335cc..230cdd18fc8eb9 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
@@ -7200,6 +7200,282 @@ def NVVM_Tcgen05MMABlockScaleDecompressBOp :
}];
}
+//===----------------------------------------------------------------------===//
+// NVVM spcompress and spdecompress Ops
+//===----------------------------------------------------------------------===//
+
+// Structured sparsity factor: spXtoY keeps X out of every Y elements.
+def SPFactor1To2 : I32EnumAttrCase<"SP1TO2", 0, "sp1to2">;
+def SPFactor1To4 : I32EnumAttrCase<"SP1TO4", 1, "sp1to4">;
+def SPFactor1To8 : I32EnumAttrCase<"SP1TO8", 2, "sp1to8">;
+def SPFactor1To16 : I32EnumAttrCase<"SP1TO16", 3, "sp1to16">;
+def SPFactor2To4 : I32EnumAttrCase<"SP2TO4", 4, "sp2to4">;
+def SPFactor2To8 : I32EnumAttrCase<"SP2TO8", 5, "sp2to8">;
+def SPFactor2To16 : I32EnumAttrCase<"SP2TO16", 6, "sp2to16">;
+def SPFactor4To8 : I32EnumAttrCase<"SP4TO8", 7, "sp4to8">;
+def SPFactor4To16 : I32EnumAttrCase<"SP4TO16", 8, "sp4to16">;
+def SPFactor : I32EnumAttr<"SPFactor", "Structured sparsity factor", [
+ SPFactor1To2,
+ SPFactor1To4,
+ SPFactor1To8,
+ SPFactor1To16,
+ SPFactor2To4,
+ SPFactor2To8,
+ SPFactor2To16,
+ SPFactor4To8,
+ SPFactor4To16,
+ ]> {
+ let genSpecializedAttr = 0;
+ let cppNamespace = "::mlir::NVVM";
+}
+def SPFactorAttr : EnumAttr<NVVM_Dialect, SPFactor, "sp_factor">;
+
+// Structured sparsity metadata index size
+def SPIndexSizeB2 : I32EnumAttrCase<"B2", 2, "b2">;
+def SPIndexSizeB4 : I32EnumAttrCase<"B4", 4, "b4">;
+def SPIndexSize : I32EnumAttr<"SPIndexSize",
+ "Structured sparsity metadata index size", [
+ SPIndexSizeB2,
+ SPIndexSizeB4,
+ ]> {
+ let genSpecializedAttr = 0;
+ let cppNamespace = "::mlir::NVVM";
+}
+def SPIndexSizeAttr : EnumAttr<NVVM_Dialect, SPIndexSize, "sp_index_size">;
+
+// Structured sparsity element size
+def SPElemSizeB8 : I32EnumAttrCase<"B8", 8, "b8">;
+def SPElemSizeB16 : I32EnumAttrCase<"B16", 16, "b16">;
+def SPElemSize : I32EnumAttr<"SPElemSize", "Structured sparsity element size", [
+ SPElemSizeB8,
+ SPElemSizeB16,
+ ]> {
+ let genSpecializedAttr = 0;
+ let cppNamespace = "::mlir::NVVM";
+}
+def SPElemSizeAttr : EnumAttr<NVVM_Dialect, SPElemSize, "sp_elem_size">;
+
+// Structured sparsity repetition factor
+def SPRepFactorX1 : I32EnumAttrCase<"X1", 1, "x1">;
+def SPRepFactorX2 : I32EnumAttrCase<"X2", 2, "x2">;
+def SPRepFactorX4 : I32EnumAttrCase<"X4", 4, "x4">;
+def SPRepFactorX8 : I32EnumAttrCase<"X8", 8, "x8">;
+def SPRepFactorX16 : I32EnumAttrCase<"X16", 16, "x16">;
+def SPRepFactorX32 : I32EnumAttrCase<"X32", 32, "x32">;
+def SPRepFactorX64 : I32EnumAttrCase<"X64", 64, "x64">;
+def SPRepFactor : I32EnumAttr<"SPRepFactor",
+ "Structured sparsity repetition factor",
+ [SPRepFactorX1, SPRepFactorX2, SPRepFactorX4, SPRepFactorX8,
+ SPRepFactorX16, SPRepFactorX32, SPRepFactorX64]> {
+ let genSpecializedAttr = 0;
+ let cppNamespace = "::mlir::NVVM";
+}
+def SPRepFactorAttr : EnumAttr<NVVM_Dialect, SPRepFactor, "sp_rep_factor">;
+
+// spcompress only supports the 2:4 sparsity factor.
+def SPCompressFactorAttr : ConfinedAttr<SPFactorAttr, [
+ EnumAttrIsOneOf<SPFactorAttr, [
+ SPFactor2To4,
+ ]>
+ ]>;
+
+// Register bundles are i32 or fixed-length, rank-1 vectors of i32.
+defvar SPDataType = FixedVectorOfRankAndLengthAndType<[1],
+ [2, 4, 8, 16, 32, 64, 128], [I32]>;
+defvar SPRegType = AnyTypeOf<[I32,
+ FixedVectorOfRankAndLengthAndType<[1], [2, 4, 8, 16, 32, 64], [I32]>]>;
+
+def NVVM_SPCompressOp : NVVM_Op<"spcompress",
+ [Pure, NVVMRequiresSMa<[107]>]> {
+ let summary = "Compress dense vector to structured sparse vector";
+ let description = [{
+ Compresses elements from a dense vector `data` into a structured sparse
+ vector `compressed_data`. The indices of the selected elements are
+ returned in `metadata`.
+
+ All vectors are bundles of 32-bit registers. The elements are packed into
+ these registers according to `elemSize`.
+
+ Arguments:
+ - `spDesc`: Sparsity descriptor specifying the selection operation and the
+ element data type.
+ - `data`: Input dense vector of `2 * repFactor` registers containing the
+ elements to be compressed.
+ - `compFactor`: Compression factor. Only `sp2to4` is supported.
+ - `indexSize`: Size in bits of each metadata index (`b2` or `b4`).
+ - `elemSize`: Size in bits of each element in `data` (`b8` or `b16`).
+ - `repFactor`: Repeat factor of the operation (`x1` to `x64`).
+
+ Results:
+ - `metadata`: Indices of the selected elements, stored in
+ `ceil(repFactor * indexSize / elemSize)` registers.
+ - `compressed_data`: Selected elements, stored in `repFactor` registers.
+
+ Examples:
+ ```mlir
+ // 8-bit elements, 2-bit indices, repeat factor of 1.
+ %metadata, %compressed_data = nvvm.spcompress %spdesc, %data
+ comp_factor = sp2to4 index_size = b2 elem_size = b8 rep_factor = x1
+ : i32, vector<2xi32> -> i32, i32
+
+ // 8-bit elements, 4-bit indices, repeat factor of 2.
+ %metadata, %compressed_data = nvvm.spcompress %spdesc, %data
+ comp_factor = sp2to4 index_size = b4 elem_size = b8 rep_factor = x2
+ : i32, vector<4xi32> -> i32, vector<2xi32>
+
+ // 16-bit elements, 4-bit indices, repeat factor of 8.
+ %metadata, %compressed_data = nvvm.spcompress %spdesc, %data
+ comp_factor = sp2to4 index_size = b4 elem_size = b16 rep_factor = x8
+ : i32, vector<16xi32> -> vector<2xi32>, vector<8xi32>
+ ```
+
+ [For more information, see PTX ISA](https://docs.nvidia.com/cuda/parallel-thread-execution/#data-movement-and-conversion-instructions-spcompress)
+ }];
+
+ let arguments = (ins
+ I32:$spDesc,
+ SPDataType:$data,
+ SPCompressFactorAttr:$compFactor,
+ SPIndexSizeAttr:$indexSize,
+ SPElemSizeAttr:$elemSize,
+ SPRepFactorAttr:$repFactor);
+
+ let results = (outs
+ SPRegType:$metadata,
+ SPRegType:$compressed_data);
+
+ let assemblyFormat = [{
+ $spDesc `,` $data
+ `comp_factor` `=` enum($compFactor)
+ `index_size` `=` enum($indexSize)
+ `elem_size` `=` enum($elemSize)
+ `rep_factor` `=` enum($repFactor)
+ attr-dict `:` type(operands) `->` type($metadata) `,` type($compressed_data)
+ }];
+
+ let extraClassDeclaration = [{
+ static NVVM::IDArgPair getIntrinsicIDAndArgs(Operation &op,
+ LLVM::ModuleTranslation &mt,
+ llvm::IRBuilderBase &builder);
+ }];
+
+ let hasVerifier = 1;
+
+ string llvmBuilder = [{
+ auto [id, args] = NVVM::SPCompressOp::getIntrinsicIDAndArgs(
+ *op, moduleTranslation, builder);
+ // The intrinsic returns the compressed data with one lane per element.
+ auto *dataTy = llvm::cast<llvm::FixedVectorType>(args[0]->getType());
+ llvm::Type *compressedTy = llvm::FixedVectorType::get(
+ dataTy->getElementType(), dataTy->getNumElements() / 2);
+ llvm::Type *metadataTy = moduleTranslation.convertType(
+ op.getMetadata().getType());
+ llvm::Type *resultTy = llvm::StructType::get(
+ builder.getContext(), {metadataTy, compressedTy});
+ llvm::CallInst *result = createIntrinsicCall(builder, id, resultTy, args);
+ $metadata = builder.CreateExtractValue(result, 0);
+ $compressed_data = builder.CreateBitCast(
+ builder.CreateExtractValue(result, 1),
+ moduleTranslation.convertType(op.getCompressedData().getType()));
+ }];
+}
+
+def NVVM_SPDecompressOp : NVVM_Op<"spdecompress",
+ [Pure, NVVMRequiresSMa<[107]>]> {
+ let summary = "Decompress structured sparse vector to dense vector";
+ let description = [{
+ Decompresses elements from a structured sparse vector `compressed_data`
+ into a dense vector `data`, using the indices stored in `metadata`. Dense
+ positions not selected by `metadata` are set to zero.
+
+ All vectors are bundles of 32-bit registers. The elements are packed into
+ these registers according to `elemSize`. For a decompression factor
+ `spXtoY`, the number of registers in each bundle is:
+ - `metadata`: `ceil(X * indexSize * repFactor / 32)`
+ - `compressed_data`: `ceil(X * elemSize * repFactor / 32)`
+ - `data`: `Y * elemSize * repFactor / 32`
+
+ The following conditions must hold:
+ - `Y * elemSize * repFactor` is between 32 and 4096.
+ - `X * elemSize` is at most 32.
+ - `indexSize` is `b2` only if `Y` is at most 4.
+
+ Arguments:
+ - `metadata`: Indices of the selected elements.
+ - `compressed_data`: Compressed vector containing the selected elements.
+ - `compFactor`: Decompression factor (`sp1to2`, `sp1to4`, `sp1to8`,
+ `sp1to16`, `sp2to4`, `sp2to8`, `sp2to16`, `sp4to8`, or `sp4to16`).
+ - `indexSize`: Size in bits of each metadata index (`b2` or `b4`).
+ - `elemSize`: Size in bits of each element (`b8` or `b16`).
+ - `repFactor`: Repeat factor of the operation (`x1` to `x64`).
+
+ Results:
+ - `data`: Output dense vector containing the decompressed elements.
+
+ Examples:
+ ```mlir
+ // 8-bit elements, 2-bit indices, repeat factor of 1.
+ %res = nvvm.spdecompress %metadata, %compdata
+ comp_factor = sp2to4 index_size = b2 elem_size = b8 rep_factor = x1
+ : i32, i32 -> i32
+
+ // 8-bit elements, 4-bit indices, repeat factor of 2.
+ %res = nvvm.spdecompress %metadata, %compdata
+ comp_factor = sp2to4 index_size = b4 elem_size = b8 rep_factor = x2
+ : i32, i32 -> vector<2xi32>
+
+ // 16-bit elements, 4-bit indices, repeat factor of 64.
+ %res = nvvm.spdecompress %metadata, %compdata
+ comp_factor = sp2to4 index_size = b4 elem_size = b16 rep_factor = x64
+ : vector<16xi32>, vector<64xi32> -> vector<128xi32>
+ ```
+
+ [For more information, see PTX ISA](https://docs.nvidia.com/cuda/parallel-thread-execution/#data-movement-and-conversion-instructions-spdecompress)
+ }];
+
+ let arguments = (ins
+ SPRegType:$metadata,
+ SPRegType:$compressed_data,
+ SPFactorAttr:$compFactor,
+ SPIndexSizeAttr:$indexSize,
+ SPElemSizeAttr:$elemSize,
+ SPRepFactorAttr:$repFactor);
+
+ let results = (outs
+ AnyTypeOf<[I32, SPDataType]>:$data);
+
+ let assemblyFormat = [{
+ $metadata `,` $compressed_data
+ `comp_factor` `=` enum($compFactor)
+ `index_size` `=` enum($indexSize)
+ `elem_size` `=` enum($elemSize)
+ `rep_factor` `=` enum($repFactor)
+ attr-dict `:` type($metadata) `,` type($compressed_data) `->` type($data)
+ }];
+
+ let extraClassDeclaration = [{
+ static NVVM::IDArgPair getIntrinsicIDAndArgs(Operation &op,
+ LLVM::ModuleTranslation &mt,
+ llvm::IRBuilderBase &builder);
+ }];
+
+ let hasVerifier = 1;
+
+ string llvmBuilder = [{
+ auto [id, args] = NVVM::SPDecompressOp::getIntrinsicIDAndArgs(
+ *op, moduleTranslation, builder);
+ // The intrinsic returns the dense data with one lane per element.
+ auto *compressedTy = llvm::cast<llvm::FixedVectorType>(args[1]->getType());
+ unsigned numTgt = llvm::cast<llvm::ConstantInt>(args[3])->getZExtValue();
+ llvm::Type *dataTy = llvm::FixedVectorType::get(
+ compressedTy->getElementType(),
+ numTgt * static_cast<unsigned>($repFactor));
+ llvm::Value *logicalData = createIntrinsicCall(builder, id, dataTy, args);
+ $data = builder.CreateBitCast(
+ logicalData, moduleTranslation.convertType(op.getData().getType()));
+ }];
+}
+
def SIMTFloatType : AnyTypeOf<[F16, BF16, F32, F64,
VectorOfLengthAndType<[2], [F16, BF16, F32, F64]>]>;
diff --git a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
index 1a300b1e7f41c7..f59957cbf08cf7 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
@@ -37,6 +37,7 @@
#include "llvm/IR/NVVMIntrinsicUtils.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/NVPTXAddrSpace.h"
#include "llvm/Support/raw_ostream.h"
#include <array>
@@ -7068,6 +7069,150 @@ LogicalResult Tcgen05LdRedOp::verify() {
return success();
}
+//===----------------------------------------------------------------------===//
+// spcompress and spdecompress Ops
+//===----------------------------------------------------------------------===//
+
+// Returns the number of 32-bit registers in a register bundle, which is either
+// an i32 or a vector of i32.
+static unsigned getNumSPRegisters(Type type) {
+ if (auto vecTy = dyn_cast<VectorType>(type))
+ return vecTy.getNumElements();
+ return 1;
+}
+
+// Returns the {source, target} group sizes of the sparsity factor.
+static std::pair<unsigned, unsigned> getSPFactor(NVVM::SPFactor compFactor) {
+ switch (compFactor) {
+ case NVVM::SPFactor::SP1TO2:
+ return {1, 2};
+ case NVVM::SPFactor::SP1TO4:
+ return {1, 4};
+ case NVVM::SPFactor::SP1TO8:
+ return {1, 8};
+ case NVVM::SPFactor::SP1TO16:
+ return {1, 16};
+ case NVVM::SPFactor::SP2TO4:
+ return {2, 4};
+ case NVVM::SPFactor::SP2TO8:
+ return {2, 8};
+ case NVVM::SPFactor::SP2TO16:
+ return {2, 16};
+ case NVVM::SPFactor::SP4TO8:
+ return {4, 8};
+ case NVVM::SPFactor::SP4TO16:
+ return {4, 16};
+ }
+ llvm_unreachable("Invalid SPFactor");
+}
+
+LogicalResult SPCompressOp::verify() {
+ unsigned repFactor = static_cast<unsigned>(getRepFactor());
+ unsigned indexSize = static_cast<unsigned>(getIndexSize());
+ unsigned elemSize = static_cast<unsigned>(getElemSize());
+
+ if (getNumSPRegisters(getData().getType()) != 2 * repFactor)
+ return emitError(
+ "Operation attributes and provided input data size doesn't match");
+
+ if (getNumSPRegisters(getCompressedData().getType()) != repFactor)
+ return emitError("Operation attributes and provided output compressed data "
+ "size doesn't match");
+
+ if (getNumSPRegisters(getMetadata().getType()) !=
+ llvm::divideCeil(repFactor * indexSize, elemSize))
+ return emitError(
+ "Operation attributes and provided output metadata size doesn't match");
+
+ return success();
+}
+
+LogicalResult SPDecompressOp::verify() {
+ unsigned repFactor = static_cast<unsigned>(getRepFactor());
+ unsigned indexSize = static_cast<unsigned>(getIndexSize());
+ unsigned elemSize = static_cast<unsigned>(getElemSize());
+ auto [numSrc, numTgt] = getSPFactor(getCompFactor());
+
+ unsigned dataBits = numTgt * elemSize * repFactor;
+ if (dataBits < 32 || dataBits > 4096)
+ return emitError(
+ "Invalid compFactor, element size, and repeat factor combination");
+
+ if (numSrc * elemSize > 32)
+ return emitError("Invalid compFactor and element size combination");
+
+ if (indexSize == 2 && numTgt > 4)
+ return emitError("Invalid index size and target combination, target "
+ "should be at most 4 if index size is 2");
+
+ if (getNumSPRegisters(getData().getType()) != dataBits / 32)
+ return emitError(
+ "Operation attributes and provided output data size doesn't match");
+
+ if (getNumSPRegisters(getCompressedData().getType()) !=
+ llvm::divideCeil(numSrc * elemSize * repFactor, 32))
+ return emitError("Operation attributes and provided input compressed data "
+ "size doesn't match");
+
+ if (getNumSPRegisters(getMetadata().getType()) !=
+ llvm::divideCeil(numSrc * indexSize * repFactor, 32))
+ return emitError(
+ "Operation attributes and provided input metadata size doesn't match");
+
+ return success();
+}
+
+NVVM::IDArgPair
+SPCompressOp::getIntrinsicIDAndArgs(Operation &op, LLVM::ModuleTranslation &mt,
+ llvm::IRBuilderBase &builder) {
+ auto thisOp = cast<NVVM::SPCompressOp>(op);
+ unsigned elemSize = static_cast<unsigned>(thisOp.getElemSize());
+ unsigned repFactor = static_cast<unsigned>(thisOp.getRepFactor());
+
+ // The intrinsic takes the dense data with one lane per element. The data
+ // occupies 2 * repFactor 32-bit registers.
+ llvm::Type *dataTy = llvm::FixedVectorType::get(builder.getIntNTy(elemSize),
+ 64 * repFactor / elemSize);
+ llvm::Value *data =
+ builder.CreateBitCast(mt.lookupValue(thisOp.getData()), dataTy);
+
+ llvm::SmallVector<llvm::Value *> args{
+ data,
+ mt.lookupValue(thisOp.getSpDesc()),
+ builder.getInt32(static_cast<unsigned>(thisOp.getIndexSize())),
+ // spcompress only supports the sp2to4 compression factor.
+ builder.getInt32(4),
+ };
+ return {llvm::Intrinsic::nvvm_spcompress, std::move(args)};
+}
+
+NVVM::IDArgPair SPDecompressOp::getIntrinsicIDAndArgs(
+ Operation &op, LLVM::ModuleTranslation &mt, llvm::IRBuilderBase &builder) {
+ auto thisOp = cast<NVVM::SPDecompressOp>(op);
+ auto [numSrc, numTgt] = getSPFactor(thisOp.getCompFactor());
+ unsigned elemSize = static_cast<unsigned>(thisOp.getElemSize());
+ unsigned repFactor = static_cast<unsigned>(thisOp.getRepFactor());
+
+ // The intrinsic takes the compressed data with one lane per element.
+ // Compressed data narrower than 32 bits is carried in the low bits of an i32.
+ llvm::Value *compressedData = mt.lookupValue(thisOp.getCompressedData());
+ unsigned compressedBits = numSrc * elemSize * repFactor;
+ if (compressedBits < 32)
+ compressedData =
+ builder.CreateTrunc(compressedData, builder.getIntNTy(compressedBits));
+ llvm::Type *compressedTy = llvm::FixedVectorType::get(
+ builder.getIntNTy(elemSize), numSrc * repFactor);
+ compressedData = builder.CreateBitCast(compressedData, compressedTy);
+
+ llvm::SmallVector<llvm::Value *> args{
+ mt.lookupValue(thisOp.getMetadata()),
+ compressedData,
+ builder.getInt32(static_cast<unsigned>(thisOp.getIndexSize())),
+ builder.getInt32(numTgt),
+ };
+ return {llvm::Intrinsic::nvvm_spdecompress, std::move(args)};
+}
+
//===----------------------------------------------------------------------===//
// NVVMDialect initialization, type parsing, and registration.
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Target/LLVMIR/nvvm/spcompress-invalid.mlir b/mlir/test/Target/LLVMIR/nvvm/spcompress-invalid.mlir
new file mode 100644
index 00000000000000..3eb906346a33cc
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/spcompress-invalid.mlir
@@ -0,0 +1,80 @@
+// RUN: mlir-translate --mlir-to-llvmir -verify-diagnostics -split-input-file %s
+
+llvm.func @spcompress_invalid_data_size(%spdesc: i32, %data: vector<2xi32>) {
+ // expected-error @below {{Operation attributes and provided input data size doesn't match}}
+ %metadata, %compressed_data = nvvm.spcompress %spdesc, %data
+ comp_factor = sp2to4 index_size = b2 elem_size = b8 rep_factor = x2
+ : i32, vector<2xi32> -> i32, vector<2xi32>
+ llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_invalid_compressed_data_size(%spdesc: i32, %data: vector<4xi32>) {
+ // expected-error @below {{Operation attributes and provided output compressed data size doesn't match}}
+ %metadata, %compressed_data = nvvm.spcompress %spdesc, %data
+ comp_factor = sp2to4 index_size = b2 elem_size = b8 rep_factor = x2
+ : i32, vector<4xi32> -> i32, vector<4xi32>
+ llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_invalid_metadata_size(%spdesc: i32, %data: vector<4xi32>) {
+ // expected-error @below {{Operation attributes and provided output metadata size doesn't match}}
+ %metadata, %compressed_data = nvvm.spcompress %spdesc, %data
+ comp_factor = sp2to4 index_size = b2 elem_size = b8 rep_factor = x2
+ : i32, vector<4xi32> -> vector<2xi32>, vector<2xi32>
+ llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_invalid_elem_size(%spdesc: i32, %data: vector<2xi32>) {
+ %metadata, %compressed_data = nvvm.spcompress %spdesc, %data
+ // expected-error @below {{expected string or keyword containing one of the following enum values for attribute 'elemSize' [b8, b16]}}
+ comp_factor = sp2to4 index_size = b2 elem_size = b32 rep_...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/232731
More information about the Mlir-commits
mailing list