[Mlir-commits] [mlir] 06d86d7 - [MLIR][NVVM] Support sparse.{de}compress MLIR Ops (#232731)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Oct 22 22:53:47 PDT 2026


Author: Kirill Vedernikov
Date: 2026-10-23T07:53:42+02:00
New Revision: 06d86d74ae257c460211fc33e3f055a07d2d3e22

URL: https://github.com/llvm/llvm-project/commit/06d86d74ae257c460211fc33e3f055a07d2d3e22
DIFF: https://github.com/llvm/llvm-project/commit/06d86d74ae257c460211fc33e3f055a07d2d3e22.diff

LOG: [MLIR][NVVM] Support sparse.{de}compress MLIR Ops (#232731)

This change adds support for `sparse.compress` and `sparse.decompress` MLIR Ops.

Added: 
    mlir/test/Target/LLVMIR/nvvm/sparse-compress-invalid.mlir
    mlir/test/Target/LLVMIR/nvvm/sparse-compress-sp2to4.mlir
    mlir/test/Target/LLVMIR/nvvm/sparse-decompress-invalid.mlir
    mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to16.mlir
    mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to2.mlir
    mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to4.mlir
    mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to8.mlir
    mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to16.mlir
    mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to4.mlir
    mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to8.mlir
    mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp4to16.mlir
    mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp4to8.mlir

Modified: 
    mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
    mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
    mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
index 79eda3fee335cc..ccc7805dd6ae19 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td
@@ -7200,6 +7200,167 @@ def NVVM_Tcgen05MMABlockScaleDecompressBOp :
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// NVVM sparse.compress and sparse.decompress Ops
+//===----------------------------------------------------------------------===//
+
+// Size in bits of each structured sparsity metadata index.
+def SPIdxSizeAttr : ConfinedAttr<I32Attr, [IntIsOneOf<[2, 4]>]>;
+
+// Size of each structured sparsity group in the dense data.
+def SPNumTgtAttr : ConfinedAttr<I32Attr, [IntIsOneOf<[2, 4, 8, 16]>]>;
+
+// Dense and compressed data are vectors of 8-bit or 16-bit elements.
+defvar SPElemVectorType = FixedVectorOfRankAndType<[1], [I8, I16]>;
+
+// Metadata is a bundle of 32-bit registers: i32 or a vector of i32. A
+// single-register bundle may be either i32 or vector<1xi32>.
+defvar SPMetadataType = AnyTypeOf<[I32,
+    FixedVectorOfRankAndLengthAndType<[1], [1, 2, 4, 8, 16, 32], [I32]>]>;
+
+def NVVM_SparseCompressOp : NVVM_Op<"sparse.compress",
+    [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` using the 2:4 sparsity pattern: 2 out of every
+    4 elements of `data` are selected. The indices of the selected elements
+    are returned in `metadata`.
+
+    The element size (8 or 16 bits) is given by the element type of `data`
+    and `compressed_data`. `data` must occupy `2 * repFactor` 32-bit
+    registers, where the repeat factor `repFactor` is a power of two from 1
+    to 64.
+
+    Arguments:
+    - `spDesc`: Sparsity descriptor specifying the selection operation and the
+      element data type.
+    - `data`: Dense vector containing the elements to be compressed.
+    - `idxSize`: Size in bits of each metadata index (2 or 4).
+
+    Results:
+    - `metadata`: Indices of the selected elements, stored in
+      `ceil(repFactor * idxSize / elemSize)` 32-bit registers. A single
+      register may be either `i32` or `vector<1xi32>`.
+    - `compressed_data`: Selected elements; half as many as in `data`.
+
+    Examples:
+    ```mlir
+    // 8-bit elements, 2-bit indices, repeat factor of 1.
+    %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data
+        idx_size = 2
+        : i32, vector<8xi8> -> i32, vector<4xi8>
+
+    // 16-bit elements, 4-bit indices, repeat factor of 8.
+    %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data
+        idx_size = 4
+        : i32, vector<32xi16> -> vector<2xi32>, vector<16xi16>
+    ```
+
+    [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,
+    SPElemVectorType:$data,
+    SPIdxSizeAttr:$idxSize);
+
+  let results = (outs
+    SPMetadataType:$metadata,
+    SPElemVectorType:$compressed_data);
+
+  let assemblyFormat = [{
+    $spDesc `,` $data `idx_size` `=` $idxSize attr-dict
+    `:` type(operands) `->` type($metadata) `,` type($compressed_data)
+  }];
+
+  let extraClassDeclaration = [{
+    static void lowerToLLVMIR(Operation &op, LLVM::ModuleTranslation &mt,
+                              llvm::IRBuilderBase &builder);
+  }];
+
+  let hasVerifier = 1;
+
+  string llvmBuilder = [{
+    NVVM::SparseCompressOp::lowerToLLVMIR(*op, moduleTranslation, builder);
+  }];
+}
+
+def NVVM_SparseDecompressOp : NVVM_Op<"sparse.decompress",
+    [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.
+
+    `data` consists of `repFactor` groups of `numTgt` elements, and
+    `compressed_data` holds `numSrc` elements for each group, i.e. the
+    sparsity factor is `numSrc:numTgt`. Both `numSrc` and the repeat factor
+    `repFactor` are derived from the vector lengths. The element size
+    `elemSize` (8 or 16 bits) is given by the element type of `data` and
+    `compressed_data`.
+
+    The following conditions must hold:
+    - `numSrc:numTgt` is one of 1:2, 1:4, 1:8, 1:16, 2:4, 2:8, 2:16, 4:8, or
+      4:16.
+    - `repFactor` is a power of two from 1 to 64.
+    - `numTgt * elemSize * repFactor` is between 32 and 4096.
+    - `numSrc * elemSize` is at most 32.
+    - `idxSize` is 2 only if `numTgt` is at most 4.
+    - `metadata` occupies `ceil(numSrc * idxSize * repFactor / 32)` 32-bit
+      registers. A single register may be either `i32` or `vector<1xi32>`.
+
+    Arguments:
+    - `metadata`: Indices of the selected elements.
+    - `compressed_data`: Compressed vector containing the selected elements.
+    - `idxSize`: Size in bits of each metadata index (2 or 4).
+    - `numTgt`: Size of each group in `data` (2, 4, 8, or 16).
+
+    Results:
+    - `data`: Dense vector containing the decompressed elements.
+
+    Examples:
+    ```mlir
+    // 2:4 sparsity, 8-bit elements, 2-bit indices, repeat factor of 1.
+    %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+        : i32, vector<2xi8> -> vector<4xi8>
+
+    // 2:4 sparsity, 16-bit elements, 4-bit indices, repeat factor of 64.
+    %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+        : vector<16xi32>, vector<128xi16> -> vector<256xi16>
+    ```
+
+    [For more information, see PTX ISA](https://docs.nvidia.com/cuda/parallel-thread-execution/#data-movement-and-conversion-instructions-spdecompress)
+  }];
+
+  let arguments = (ins
+    SPMetadataType:$metadata,
+    SPElemVectorType:$compressed_data,
+    SPIdxSizeAttr:$idxSize,
+    SPNumTgtAttr:$numTgt);
+
+  let results = (outs
+    SPElemVectorType:$data);
+
+  let assemblyFormat = [{
+    $metadata `,` $compressed_data
+    `idx_size` `=` $idxSize `num_tgt` `=` $numTgt attr-dict
+    `:` type($metadata) `,` type($compressed_data) `->` type($data)
+  }];
+
+  let extraClassDeclaration = [{
+    static void lowerToLLVMIR(Operation &op, LLVM::ModuleTranslation &mt,
+                              llvm::IRBuilderBase &builder);
+  }];
+
+  let hasVerifier = 1;
+
+  string llvmBuilder = [{
+    NVVM::SparseDecompressOp::lowerToLLVMIR(*op, moduleTranslation, builder);
+  }];
+}
+
 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 bb2db355d567f2..d7d0e6f329f138 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
@@ -38,6 +38,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>
@@ -7069,6 +7070,96 @@ LogicalResult Tcgen05LdRedOp::verify() {
   return success();
 }
 
+//===----------------------------------------------------------------------===//
+// sparse.compress and sparse.decompress Ops
+//===----------------------------------------------------------------------===//
+
+// Returns the number of 32-bit registers in a metadata 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;
+}
+
+// The repeat factor of spcompress and spdecompress is a power of two up to 64.
+static bool isValidSPRepFactor(unsigned repFactor) {
+  return llvm::isPowerOf2_32(repFactor) && repFactor <= 64;
+}
+
+LogicalResult SparseCompressOp::verify() {
+  auto dataTy = cast<VectorType>(getData().getType());
+  auto compressedTy = cast<VectorType>(getCompressedData().getType());
+  if (dataTy.getElementType() != compressedTy.getElementType())
+    return emitOpError(
+        "expects data and compressed data to have the same element type");
+
+  // data occupies 2 * repFactor 32-bit registers.
+  unsigned elemSize = dataTy.getElementTypeBitWidth();
+  unsigned dataBits = dataTy.getNumElements() * elemSize;
+  unsigned repFactor = dataBits / 64;
+  if (dataBits % 64 != 0 || !isValidSPRepFactor(repFactor))
+    return emitOpError("expects data to occupy 2 * repFactor 32-bit "
+                       "registers, where repFactor is a power of two up to 64");
+
+  // spcompress only supports the 2:4 sparsity factor.
+  if (2 * compressedTy.getNumElements() != dataTy.getNumElements())
+    return emitOpError(
+        "expects compressed data to have half as many elements as data");
+
+  unsigned numMetadataRegs =
+      llvm::divideCeil(repFactor * getIdxSize(), elemSize);
+  if (getNumSPRegisters(getMetadata().getType()) != numMetadataRegs)
+    return emitOpError("expects metadata to occupy ")
+           << numMetadataRegs << " 32-bit register(s)";
+
+  return success();
+}
+
+LogicalResult SparseDecompressOp::verify() {
+  auto dataTy = cast<VectorType>(getData().getType());
+  auto compressedTy = cast<VectorType>(getCompressedData().getType());
+  if (dataTy.getElementType() != compressedTy.getElementType())
+    return emitOpError(
+        "expects data and compressed data to have the same element type");
+
+  // data holds repFactor groups of numTgt elements, and compressed data holds
+  // numSrc elements for each of those groups.
+  unsigned idxSize = getIdxSize();
+  unsigned numTgt = getNumTgt();
+  unsigned numData = dataTy.getNumElements();
+  unsigned numCompressed = compressedTy.getNumElements();
+  unsigned repFactor = numData / numTgt;
+  if (numData % numTgt != 0 || !isValidSPRepFactor(repFactor))
+    return emitOpError("expects data to have repFactor * num_tgt elements, "
+                       "where repFactor is a power of two up to 64");
+
+  unsigned numSrc = numCompressed / repFactor;
+  if (numCompressed % repFactor != 0 ||
+      !llvm::is_contained({1u, 2u, 4u}, numSrc) || numSrc >= numTgt)
+    return emitOpError("unsupported sparsity factor: compressed data has ")
+           << numCompressed << " elements for " << repFactor << " group(s) of "
+           << numTgt << " elements";
+
+  unsigned elemSize = dataTy.getElementTypeBitWidth();
+  unsigned dataBits = numData * elemSize;
+  if (dataBits < 32 || dataBits > 4096)
+    return emitOpError("expects data to be between 32 and 4096 bits");
+
+  if (numSrc * elemSize > 32)
+    return emitOpError("expects at most 32 bits of compressed data per group");
+
+  if (idxSize == 2 && numTgt > 4)
+    return emitOpError("expects num_tgt to be at most 4 if idx_size is 2");
+
+  unsigned numMetadataRegs = llvm::divideCeil(numSrc * idxSize * repFactor, 32);
+  if (getNumSPRegisters(getMetadata().getType()) != numMetadataRegs)
+    return emitOpError("expects metadata to occupy ")
+           << numMetadataRegs << " 32-bit register(s)";
+
+  return success();
+}
+
 //===----------------------------------------------------------------------===//
 // NVVMDialect initialization, type parsing, and registration.
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp
index f7f2503eee4284..0adf648857fa4e 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp
@@ -634,6 +634,54 @@ void NVVM::FmaOp::lowerFmaToLLVMIR(Operation &op, LLVM::ModuleTranslation &mt,
   }
 }
 
+// Returns the LLVM type the sp{de}compress intrinsics use for metadata: i32 for
+// a single register (including vector<1xi32>) and a vector of i32 otherwise.
+static llvm::Type *getSPMetadataType(Type type, llvm::IRBuilderBase &builder) {
+  auto vecTy = dyn_cast<VectorType>(type);
+  if (!vecTy || vecTy.getNumElements() == 1)
+    return builder.getInt32Ty();
+  return llvm::FixedVectorType::get(builder.getInt32Ty(),
+                                    vecTy.getNumElements());
+}
+
+void NVVM::SparseCompressOp::lowerToLLVMIR(Operation &op,
+                                           LLVM::ModuleTranslation &mt,
+                                           llvm::IRBuilderBase &builder) {
+  auto thisOp = cast<NVVM::SparseCompressOp>(op);
+  Value metadata = thisOp.getMetadata();
+  Value compressedData = thisOp.getCompressedData();
+  llvm::Type *resultTy =
+      llvm::StructType::get(getSPMetadataType(metadata.getType(), builder),
+                            mt.convertType(compressedData.getType()));
+
+  llvm::Value *result = createIntrinsicCall(
+      builder, llvm::Intrinsic::nvvm_spcompress, resultTy,
+      {mt.lookupValue(thisOp.getData()), mt.lookupValue(thisOp.getSpDesc()),
+       builder.getInt32(thisOp.getIdxSize()),
+       // spcompress only supports the 2:4 sparsity factor.
+       builder.getInt32(4)});
+
+  mt.mapValue(metadata) =
+      builder.CreateBitCast(builder.CreateExtractValue(result, 0),
+                            mt.convertType(metadata.getType()));
+  mt.mapValue(compressedData) = builder.CreateExtractValue(result, 1);
+}
+
+void NVVM::SparseDecompressOp::lowerToLLVMIR(Operation &op,
+                                             LLVM::ModuleTranslation &mt,
+                                             llvm::IRBuilderBase &builder) {
+  auto thisOp = cast<NVVM::SparseDecompressOp>(op);
+  Value metadata = thisOp.getMetadata();
+  mt.mapValue(thisOp.getData()) = createIntrinsicCall(
+      builder, llvm::Intrinsic::nvvm_spdecompress,
+      mt.convertType(thisOp.getData().getType()),
+      {builder.CreateBitCast(mt.lookupValue(metadata),
+                             getSPMetadataType(metadata.getType(), builder)),
+       mt.lookupValue(thisOp.getCompressedData()),
+       builder.getInt32(thisOp.getIdxSize()),
+       builder.getInt32(thisOp.getNumTgt())});
+}
+
 namespace {
 /// Implementation of the dialect interface that converts operations belonging
 /// to the NVVM dialect to LLVM IR.

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-compress-invalid.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-compress-invalid.mlir
new file mode 100644
index 00000000000000..958805e80abd3a
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-compress-invalid.mlir
@@ -0,0 +1,99 @@
+// RUN: mlir-translate --mlir-to-llvmir -verify-diagnostics -split-input-file %s
+
+llvm.func @spcompress_elem_type_mismatch(%spdesc: i32, %data: vector<8xi8>) {
+  // expected-error @below {{'nvvm.sparse.compress' op expects data and compressed data to have the same element type}}
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<8xi8> -> i32, vector<4xi16>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_data_too_small(%spdesc: i32, %data: vector<4xi8>) {
+  // expected-error @below {{'nvvm.sparse.compress' op expects data to occupy 2 * repFactor 32-bit registers, where repFactor is a power of two up to 64}}
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<4xi8> -> i32, vector<2xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_rep_factor_not_power_of_2(%spdesc: i32, %data: vector<24xi8>) {
+  // expected-error @below {{'nvvm.sparse.compress' op expects data to occupy 2 * repFactor 32-bit registers, where repFactor is a power of two up to 64}}
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<24xi8> -> i32, vector<12xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_invalid_compressed_data_size(%spdesc: i32, %data: vector<8xi8>) {
+  // expected-error @below {{'nvvm.sparse.compress' op expects compressed data to have half as many elements as data}}
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<8xi8> -> i32, vector<8xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_invalid_metadata_size(%spdesc: i32, %data: vector<16xi8>) {
+  // expected-error @below {{'nvvm.sparse.compress' op expects metadata to occupy 1 32-bit register(s)}}
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<16xi8> -> vector<2xi32>, vector<8xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_invalid_idx_size(%spdesc: i32, %data: vector<8xi8>) {
+  // expected-error @below {{'nvvm.sparse.compress' op attribute 'idxSize' failed to satisfy constraint: 32-bit signless integer attribute whose value is one of {2, 4}}}
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 3
+      : i32, vector<8xi8> -> i32, vector<4xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_invalid_elem_type(%spdesc: i32, %data: vector<2xi32>) {
+  // expected-error @below {{'nvvm.sparse.compress' op operand #1 must be fixed-length vector of 8-bit signless integer or 16-bit signless integer values of ranks 1, but got 'vector<2xi32>'}}
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<2xi32> -> i32, vector<4xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_scalable_data(%spdesc: i32, %data: vector<[8]xi8>) {
+  // expected-error @below {{'nvvm.sparse.compress' op operand #1 must be fixed-length vector of 8-bit signless integer or 16-bit signless integer values of ranks 1, but got 'vector<[8]xi8>'}}
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<[8]xi8> -> i32, vector<4xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_rank2_data(%spdesc: i32, %arg: vector<8xi8>) {
+  %data = builtin.unrealized_conversion_cast %arg : vector<8xi8> to vector<1x8xi8>
+  // expected-error @below {{'nvvm.sparse.compress' op operand #1 must be fixed-length vector of 8-bit signless integer or 16-bit signless integer values of ranks 1, but got 'vector<1x8xi8>'}}
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<1x8xi8> -> i32, vector<4xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_scalable_compressed_data(%spdesc: i32, %data: vector<8xi8>) {
+  // expected-error @below {{'nvvm.sparse.compress' op result #1 must be fixed-length vector of 8-bit signless integer or 16-bit signless integer values of ranks 1, but got 'vector<[4]xi8>'}}
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<8xi8> -> i32, vector<[4]xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spcompress_invalid_metadata_type(%spdesc: i32, %data: vector<8xi8>) {
+  // expected-error @below {{'nvvm.sparse.compress' op result #0 must be 32-bit signless integer or fixed-length vector of 32-bit signless integer values of length 1/2/4/8/16/32 of ranks 1, but got 'i64'}}
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<8xi8> -> i64, vector<4xi8>
+  llvm.return
+}

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-compress-sp2to4.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-compress-sp2to4.mlir
new file mode 100644
index 00000000000000..1d8d9510690fa8
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-compress-sp2to4.mlir
@@ -0,0 +1,379 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b2_rpf_1(%spdesc: i32, %data: vector<8xi8>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b8_idxsz_b2_rpf_1(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <4 x i8> } @llvm.nvvm.spcompress.i32.v4i8.v8i8(<8 x i8> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <4 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <4 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<8xi8> -> i32, vector<4xi8>
+  llvm.return %metadata : i32
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b2_rpf_2(%spdesc: i32, %data: vector<16xi8>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b8_idxsz_b2_rpf_2(i32 %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <8 x i8> } @llvm.nvvm.spcompress.i32.v8i8.v16i8(<16 x i8> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <8 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <8 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<16xi8> -> i32, vector<8xi8>
+  llvm.return %metadata : i32
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b2_rpf_4(%spdesc: i32, %data: vector<32xi8>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b8_idxsz_b2_rpf_4(i32 %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <16 x i8> } @llvm.nvvm.spcompress.i32.v16i8.v32i8(<32 x i8> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <16 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <16 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<32xi8> -> i32, vector<16xi8>
+  llvm.return %metadata : i32
+}
+
+// rpf=8: metadata=2 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b2_rpf_8(%spdesc: i32, %data: vector<64xi8>) -> vector<2xi32> {
+  // CHECK-LABEL: define <2 x i32> @spcompress_elmsz_b8_idxsz_b2_rpf_8(i32 %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <2 x i32>, <32 x i8> } @llvm.nvvm.spcompress.v2i32.v32i8.v64i8(<64 x i8> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <2 x i32>, <32 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <2 x i32>, <32 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret <2 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<64xi8> -> vector<2xi32>, vector<32xi8>
+  llvm.return %metadata : vector<2xi32>
+}
+
+// rpf=16: metadata=4 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b2_rpf_16(%spdesc: i32, %data: vector<128xi8>) -> vector<4xi32> {
+  // CHECK-LABEL: define <4 x i32> @spcompress_elmsz_b8_idxsz_b2_rpf_16(i32 %0, <128 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <4 x i32>, <64 x i8> } @llvm.nvvm.spcompress.v4i32.v64i8.v128i8(<128 x i8> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <4 x i32>, <64 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <4 x i32>, <64 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret <4 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<128xi8> -> vector<4xi32>, vector<64xi8>
+  llvm.return %metadata : vector<4xi32>
+}
+
+// rpf=32: metadata=8 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b2_rpf_32(%spdesc: i32, %data: vector<256xi8>) -> vector<8xi32> {
+  // CHECK-LABEL: define <8 x i32> @spcompress_elmsz_b8_idxsz_b2_rpf_32(i32 %0, <256 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <8 x i32>, <128 x i8> } @llvm.nvvm.spcompress.v8i32.v128i8.v256i8(<256 x i8> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <8 x i32>, <128 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <8 x i32>, <128 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret <8 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<256xi8> -> vector<8xi32>, vector<128xi8>
+  llvm.return %metadata : vector<8xi32>
+}
+
+// rpf=64: metadata=16 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b2_rpf_64(%spdesc: i32, %data: vector<512xi8>) -> vector<16xi32> {
+  // CHECK-LABEL: define <16 x i32> @spcompress_elmsz_b8_idxsz_b2_rpf_64(i32 %0, <512 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <16 x i32>, <256 x i8> } @llvm.nvvm.spcompress.v16i32.v256i8.v512i8(<512 x i8> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <16 x i32>, <256 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <16 x i32>, <256 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret <16 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<512xi8> -> vector<16xi32>, vector<256xi8>
+  llvm.return %metadata : vector<16xi32>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b4_rpf_1(%spdesc: i32, %data: vector<8xi8>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b8_idxsz_b4_rpf_1(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <4 x i8> } @llvm.nvvm.spcompress.i32.v4i8.v8i8(<8 x i8> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <4 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <4 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<8xi8> -> i32, vector<4xi8>
+  llvm.return %metadata : i32
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b4_rpf_2(%spdesc: i32, %data: vector<16xi8>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b8_idxsz_b4_rpf_2(i32 %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <8 x i8> } @llvm.nvvm.spcompress.i32.v8i8.v16i8(<16 x i8> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <8 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <8 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<16xi8> -> i32, vector<8xi8>
+  llvm.return %metadata : i32
+}
+
+// rpf=4: metadata=2 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b4_rpf_4(%spdesc: i32, %data: vector<32xi8>) -> vector<2xi32> {
+  // CHECK-LABEL: define <2 x i32> @spcompress_elmsz_b8_idxsz_b4_rpf_4(i32 %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <2 x i32>, <16 x i8> } @llvm.nvvm.spcompress.v2i32.v16i8.v32i8(<32 x i8> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <2 x i32>, <16 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <2 x i32>, <16 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret <2 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<32xi8> -> vector<2xi32>, vector<16xi8>
+  llvm.return %metadata : vector<2xi32>
+}
+
+// rpf=8: metadata=4 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b4_rpf_8(%spdesc: i32, %data: vector<64xi8>) -> vector<4xi32> {
+  // CHECK-LABEL: define <4 x i32> @spcompress_elmsz_b8_idxsz_b4_rpf_8(i32 %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <4 x i32>, <32 x i8> } @llvm.nvvm.spcompress.v4i32.v32i8.v64i8(<64 x i8> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <4 x i32>, <32 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <4 x i32>, <32 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret <4 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<64xi8> -> vector<4xi32>, vector<32xi8>
+  llvm.return %metadata : vector<4xi32>
+}
+
+// rpf=16: metadata=8 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b4_rpf_16(%spdesc: i32, %data: vector<128xi8>) -> vector<8xi32> {
+  // CHECK-LABEL: define <8 x i32> @spcompress_elmsz_b8_idxsz_b4_rpf_16(i32 %0, <128 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <8 x i32>, <64 x i8> } @llvm.nvvm.spcompress.v8i32.v64i8.v128i8(<128 x i8> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <8 x i32>, <64 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <8 x i32>, <64 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret <8 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<128xi8> -> vector<8xi32>, vector<64xi8>
+  llvm.return %metadata : vector<8xi32>
+}
+
+// rpf=32: metadata=16 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b4_rpf_32(%spdesc: i32, %data: vector<256xi8>) -> vector<16xi32> {
+  // CHECK-LABEL: define <16 x i32> @spcompress_elmsz_b8_idxsz_b4_rpf_32(i32 %0, <256 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <16 x i32>, <128 x i8> } @llvm.nvvm.spcompress.v16i32.v128i8.v256i8(<256 x i8> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <16 x i32>, <128 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <16 x i32>, <128 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret <16 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<256xi8> -> vector<16xi32>, vector<128xi8>
+  llvm.return %metadata : vector<16xi32>
+}
+
+// rpf=64: metadata=32 register(s)
+llvm.func @spcompress_elmsz_b8_idxsz_b4_rpf_64(%spdesc: i32, %data: vector<512xi8>) -> vector<32xi32> {
+  // CHECK-LABEL: define <32 x i32> @spcompress_elmsz_b8_idxsz_b4_rpf_64(i32 %0, <512 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <32 x i32>, <256 x i8> } @llvm.nvvm.spcompress.v32i32.v256i8.v512i8(<512 x i8> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <32 x i32>, <256 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <32 x i32>, <256 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret <32 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<512xi8> -> vector<32xi32>, vector<256xi8>
+  llvm.return %metadata : vector<32xi32>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b2_rpf_1(%spdesc: i32, %data: vector<4xi16>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b16_idxsz_b2_rpf_1(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <2 x i16> } @llvm.nvvm.spcompress.i32.v2i16.v4i16(<4 x i16> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <2 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <2 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<4xi16> -> i32, vector<2xi16>
+  llvm.return %metadata : i32
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b2_rpf_2(%spdesc: i32, %data: vector<8xi16>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b16_idxsz_b2_rpf_2(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <4 x i16> } @llvm.nvvm.spcompress.i32.v4i16.v8i16(<8 x i16> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <4 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <4 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<8xi16> -> i32, vector<4xi16>
+  llvm.return %metadata : i32
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b2_rpf_4(%spdesc: i32, %data: vector<16xi16>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b16_idxsz_b2_rpf_4(i32 %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <8 x i16> } @llvm.nvvm.spcompress.i32.v8i16.v16i16(<16 x i16> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <8 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <8 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<16xi16> -> i32, vector<8xi16>
+  llvm.return %metadata : i32
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b2_rpf_8(%spdesc: i32, %data: vector<32xi16>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b16_idxsz_b2_rpf_8(i32 %0, <32 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <16 x i16> } @llvm.nvvm.spcompress.i32.v16i16.v32i16(<32 x i16> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <16 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <16 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<32xi16> -> i32, vector<16xi16>
+  llvm.return %metadata : i32
+}
+
+// rpf=16: metadata=2 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b2_rpf_16(%spdesc: i32, %data: vector<64xi16>) -> vector<2xi32> {
+  // CHECK-LABEL: define <2 x i32> @spcompress_elmsz_b16_idxsz_b2_rpf_16(i32 %0, <64 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <2 x i32>, <32 x i16> } @llvm.nvvm.spcompress.v2i32.v32i16.v64i16(<64 x i16> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <2 x i32>, <32 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <2 x i32>, <32 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret <2 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<64xi16> -> vector<2xi32>, vector<32xi16>
+  llvm.return %metadata : vector<2xi32>
+}
+
+// rpf=32: metadata=4 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b2_rpf_32(%spdesc: i32, %data: vector<128xi16>) -> vector<4xi32> {
+  // CHECK-LABEL: define <4 x i32> @spcompress_elmsz_b16_idxsz_b2_rpf_32(i32 %0, <128 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <4 x i32>, <64 x i16> } @llvm.nvvm.spcompress.v4i32.v64i16.v128i16(<128 x i16> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <4 x i32>, <64 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <4 x i32>, <64 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret <4 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<128xi16> -> vector<4xi32>, vector<64xi16>
+  llvm.return %metadata : vector<4xi32>
+}
+
+// rpf=64: metadata=8 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b2_rpf_64(%spdesc: i32, %data: vector<256xi16>) -> vector<8xi32> {
+  // CHECK-LABEL: define <8 x i32> @spcompress_elmsz_b16_idxsz_b2_rpf_64(i32 %0, <256 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <8 x i32>, <128 x i16> } @llvm.nvvm.spcompress.v8i32.v128i16.v256i16(<256 x i16> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <8 x i32>, <128 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <8 x i32>, <128 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret <8 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<256xi16> -> vector<8xi32>, vector<128xi16>
+  llvm.return %metadata : vector<8xi32>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b4_rpf_1(%spdesc: i32, %data: vector<4xi16>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b16_idxsz_b4_rpf_1(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <2 x i16> } @llvm.nvvm.spcompress.i32.v2i16.v4i16(<4 x i16> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <2 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <2 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<4xi16> -> i32, vector<2xi16>
+  llvm.return %metadata : i32
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b4_rpf_2(%spdesc: i32, %data: vector<8xi16>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b16_idxsz_b4_rpf_2(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <4 x i16> } @llvm.nvvm.spcompress.i32.v4i16.v8i16(<8 x i16> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <4 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <4 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<8xi16> -> i32, vector<4xi16>
+  llvm.return %metadata : i32
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b4_rpf_4(%spdesc: i32, %data: vector<16xi16>) -> i32 {
+  // CHECK-LABEL: define i32 @spcompress_elmsz_b16_idxsz_b4_rpf_4(i32 %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <8 x i16> } @llvm.nvvm.spcompress.i32.v8i16.v16i16(<16 x i16> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { i32, <8 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <8 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret i32 %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<16xi16> -> i32, vector<8xi16>
+  llvm.return %metadata : i32
+}
+
+// rpf=8: metadata=2 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b4_rpf_8(%spdesc: i32, %data: vector<32xi16>) -> vector<2xi32> {
+  // CHECK-LABEL: define <2 x i32> @spcompress_elmsz_b16_idxsz_b4_rpf_8(i32 %0, <32 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <2 x i32>, <16 x i16> } @llvm.nvvm.spcompress.v2i32.v16i16.v32i16(<32 x i16> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <2 x i32>, <16 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <2 x i32>, <16 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret <2 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<32xi16> -> vector<2xi32>, vector<16xi16>
+  llvm.return %metadata : vector<2xi32>
+}
+
+// rpf=16: metadata=4 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b4_rpf_16(%spdesc: i32, %data: vector<64xi16>) -> vector<4xi32> {
+  // CHECK-LABEL: define <4 x i32> @spcompress_elmsz_b16_idxsz_b4_rpf_16(i32 %0, <64 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <4 x i32>, <32 x i16> } @llvm.nvvm.spcompress.v4i32.v32i16.v64i16(<64 x i16> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <4 x i32>, <32 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <4 x i32>, <32 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret <4 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<64xi16> -> vector<4xi32>, vector<32xi16>
+  llvm.return %metadata : vector<4xi32>
+}
+
+// rpf=32: metadata=8 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b4_rpf_32(%spdesc: i32, %data: vector<128xi16>) -> vector<8xi32> {
+  // CHECK-LABEL: define <8 x i32> @spcompress_elmsz_b16_idxsz_b4_rpf_32(i32 %0, <128 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <8 x i32>, <64 x i16> } @llvm.nvvm.spcompress.v8i32.v64i16.v128i16(<128 x i16> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <8 x i32>, <64 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <8 x i32>, <64 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret <8 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<128xi16> -> vector<8xi32>, vector<64xi16>
+  llvm.return %metadata : vector<8xi32>
+}
+
+// rpf=64: metadata=16 register(s)
+llvm.func @spcompress_elmsz_b16_idxsz_b4_rpf_64(%spdesc: i32, %data: vector<256xi16>) -> vector<16xi32> {
+  // CHECK-LABEL: define <16 x i32> @spcompress_elmsz_b16_idxsz_b4_rpf_64(i32 %0, <256 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { <16 x i32>, <128 x i16> } @llvm.nvvm.spcompress.v16i32.v128i16.v256i16(<256 x i16> %1, i32 %0, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = extractvalue { <16 x i32>, <128 x i16> } %[[RES]], 0
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { <16 x i32>, <128 x i16> } %[[RES]], 1
+  // CHECK-NEXT:    ret <16 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 4
+      : i32, vector<256xi16> -> vector<16xi32>, vector<128xi16>
+  llvm.return %metadata : vector<16xi32>
+}
+
+// rpf=1: metadata=1 register(s), returned as vector<1xi32>
+llvm.func @spcompress_elmsz_b8_idxsz_b2_rpf_1_vec1(%spdesc: i32, %data: vector<8xi8>) -> vector<1xi32> {
+  // CHECK-LABEL: define <1 x i32> @spcompress_elmsz_b8_idxsz_b2_rpf_1_vec1(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call { i32, <4 x i8> } @llvm.nvvm.spcompress.i32.v4i8.v8i8(<8 x i8> %1, i32 %0, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    %[[MDATA_I32:[0-9]+]] = extractvalue { i32, <4 x i8> } %[[RES]], 0
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = bitcast i32 %[[MDATA_I32]] to <1 x i32>
+  // CHECK-NEXT:    %{{[0-9]+}} = extractvalue { i32, <4 x i8> } %[[RES]], 1
+  // CHECK-NEXT:    ret <1 x i32> %[[MDATA]]
+  // CHECK-NEXT:  }
+  %metadata, %compressed_data = nvvm.sparse.compress %spdesc, %data idx_size = 2
+      : i32, vector<8xi8> -> vector<1xi32>, vector<4xi8>
+  llvm.return %metadata : vector<1xi32>
+}

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-invalid.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-invalid.mlir
new file mode 100644
index 00000000000000..d7b888d8dcddd6
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-invalid.mlir
@@ -0,0 +1,135 @@
+// RUN: mlir-translate --mlir-to-llvmir -verify-diagnostics -split-input-file %s
+
+llvm.func @spdecompress_elem_type_mismatch(%metadata: i32, %compdata: vector<2xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op expects data and compressed data to have the same element type}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<2xi8> -> vector<4xi16>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_data_not_multiple_of_num_tgt(%metadata: i32, %compdata: vector<2xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op expects data to have repFactor * num_tgt elements, where repFactor is a power of two up to 64}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<2xi8> -> vector<6xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_rep_factor_not_power_of_2(%metadata: i32, %compdata: vector<6xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op expects data to have repFactor * num_tgt elements, where repFactor is a power of two up to 64}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<6xi8> -> vector<12xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_unsupported_num_src(%metadata: i32, %compdata: vector<3xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op unsupported sparsity factor: compressed data has 3 elements for 1 group(s) of 4 elements}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<3xi8> -> vector<4xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_num_src_equals_num_tgt(%metadata: i32, %compdata: vector<4xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op unsupported sparsity factor: compressed data has 4 elements for 1 group(s) of 4 elements}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<4xi8> -> vector<4xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_data_too_small(%metadata: i32, %compdata: vector<1xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op expects data to be between 32 and 4096 bits}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : i32, vector<1xi8> -> vector<2xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_data_too_large(%metadata: vector<4xi32>, %compdata: vector<32xi16>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op expects data to be between 32 and 4096 bits}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<4xi32>, vector<32xi16> -> vector<512xi16>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_compressed_group_too_large(%metadata: i32, %compdata: vector<4xi16>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op expects at most 32 bits of compressed data per group}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<4xi16> -> vector<8xi16>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_invalid_idx_size_for_num_tgt(%metadata: i32, %compdata: vector<1xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op expects num_tgt to be at most 4 if idx_size is 2}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 8
+      : i32, vector<1xi8> -> vector<8xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_invalid_metadata_size(%metadata: vector<2xi32>, %compdata: vector<4xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op expects metadata to occupy 1 32-bit register(s)}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<2xi32>, vector<4xi8> -> vector<8xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_invalid_idx_size(%metadata: i32, %compdata: vector<2xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op attribute 'idxSize' failed to satisfy constraint: 32-bit signless integer attribute whose value is one of {2, 4}}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 8 num_tgt = 4
+      : i32, vector<2xi8> -> vector<4xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_invalid_num_tgt(%metadata: i32, %compdata: vector<2xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op attribute 'numTgt' failed to satisfy constraint: 32-bit signless integer attribute whose value is one of {2, 4, 8, 16}}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 3
+      : i32, vector<2xi8> -> vector<6xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_scalable_compressed_data(%metadata: i32, %compdata: vector<[2]xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op operand #1 must be fixed-length vector of 8-bit signless integer or 16-bit signless integer values of ranks 1, but got 'vector<[2]xi8>'}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<[2]xi8> -> vector<4xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_rank2_metadata(%arg: vector<2xi32>, %compdata: vector<2xi8>) {
+  %metadata = builtin.unrealized_conversion_cast %arg : vector<2xi32> to vector<1x2xi32>
+  // expected-error @below {{'nvvm.sparse.decompress' op operand #0 must be 32-bit signless integer or fixed-length vector of 32-bit signless integer values of length 1/2/4/8/16/32 of ranks 1, but got 'vector<1x2xi32>'}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : vector<1x2xi32>, vector<2xi8> -> vector<4xi8>
+  llvm.return
+}
+
+// -----
+
+llvm.func @spdecompress_scalable_data(%metadata: i32, %compdata: vector<2xi8>) {
+  // expected-error @below {{'nvvm.sparse.decompress' op result #0 must be fixed-length vector of 8-bit signless integer or 16-bit signless integer values of ranks 1, but got 'vector<[4]xi8>'}}
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<2xi8> -> vector<[4]xi8>
+  llvm.return
+}

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to16.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to16.mlir
new file mode 100644
index 00000000000000..0198417281a0f9
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to16.mlir
@@ -0,0 +1,122 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<1xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_1(i32 %0, <1 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v1i8(i32 %0, <1 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<1xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<2xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_2(i32 %0, <2 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.i32.v2i8(i32 %0, <2 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<2xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<4xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_4(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<4xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_8(%metadata: i32, %compdata: vector<8xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_8(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<8xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=16: metadata=2 register(s)
+llvm.func @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_16(%metadata: vector<2xi32>, %compdata: vector<16xi8>) -> vector<256xi8> {
+  // CHECK-LABEL: define <256 x i8> @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_16(<2 x i32> %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i8> @llvm.nvvm.spdecompress.v256i8.v2i32.v16i8(<2 x i32> %0, <16 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <256 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<2xi32>, vector<16xi8> -> vector<256xi8>
+  llvm.return %res : vector<256xi8>
+}
+
+// rpf=32: metadata=4 register(s)
+llvm.func @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_32(%metadata: vector<4xi32>, %compdata: vector<32xi8>) -> vector<512xi8> {
+  // CHECK-LABEL: define <512 x i8> @spdecompress_sp1to16_elmsz_b8_idxsz_b4_rpf_32(<4 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <512 x i8> @llvm.nvvm.spdecompress.v512i8.v4i32.v32i8(<4 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <512 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<4xi32>, vector<32xi8> -> vector<512xi8>
+  llvm.return %res : vector<512xi8>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp1to16_elmsz_b16_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<1xi16>) -> vector<16xi16> {
+  // CHECK-LABEL: define <16 x i16> @spdecompress_sp1to16_elmsz_b16_idxsz_b4_rpf_1(i32 %0, <1 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i16> @llvm.nvvm.spdecompress.v16i16.i32.v1i16(i32 %0, <1 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <16 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<1xi16> -> vector<16xi16>
+  llvm.return %res : vector<16xi16>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to16_elmsz_b16_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<2xi16>) -> vector<32xi16> {
+  // CHECK-LABEL: define <32 x i16> @spdecompress_sp1to16_elmsz_b16_idxsz_b4_rpf_2(i32 %0, <2 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i16> @llvm.nvvm.spdecompress.v32i16.i32.v2i16(i32 %0, <2 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <32 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<2xi16> -> vector<32xi16>
+  llvm.return %res : vector<32xi16>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to16_elmsz_b16_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<4xi16>) -> vector<64xi16> {
+  // CHECK-LABEL: define <64 x i16> @spdecompress_sp1to16_elmsz_b16_idxsz_b4_rpf_4(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i16> @llvm.nvvm.spdecompress.v64i16.i32.v4i16(i32 %0, <4 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <64 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<4xi16> -> vector<64xi16>
+  llvm.return %res : vector<64xi16>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to16_elmsz_b16_idxsz_b4_rpf_8(%metadata: i32, %compdata: vector<8xi16>) -> vector<128xi16> {
+  // CHECK-LABEL: define <128 x i16> @spdecompress_sp1to16_elmsz_b16_idxsz_b4_rpf_8(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i16> @llvm.nvvm.spdecompress.v128i16.i32.v8i16(i32 %0, <8 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <128 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<8xi16> -> vector<128xi16>
+  llvm.return %res : vector<128xi16>
+}
+
+// rpf=16: metadata=2 register(s)
+llvm.func @spdecompress_sp1to16_elmsz_b16_idxsz_b4_rpf_16(%metadata: vector<2xi32>, %compdata: vector<16xi16>) -> vector<256xi16> {
+  // CHECK-LABEL: define <256 x i16> @spdecompress_sp1to16_elmsz_b16_idxsz_b4_rpf_16(<2 x i32> %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i16> @llvm.nvvm.spdecompress.v256i16.v2i32.v16i16(<2 x i32> %0, <16 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <256 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<2xi32>, vector<16xi16> -> vector<256xi16>
+  llvm.return %res : vector<256xi16>
+}

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to2.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to2.mlir
new file mode 100644
index 00000000000000..204c1e2577f55c
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to2.mlir
@@ -0,0 +1,299 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_2(%metadata: i32, %compdata: vector<2xi8>) -> vector<4xi8> {
+  // CHECK-LABEL: define <4 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_2(i32 %0, <2 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i8> @llvm.nvvm.spdecompress.v4i8.i32.v2i8(i32 %0, <2 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <4 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : i32, vector<2xi8> -> vector<4xi8>
+  llvm.return %res : vector<4xi8>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_4(%metadata: i32, %compdata: vector<4xi8>) -> vector<8xi8> {
+  // CHECK-LABEL: define <8 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_4(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i8> @llvm.nvvm.spdecompress.v8i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <8 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : i32, vector<4xi8> -> vector<8xi8>
+  llvm.return %res : vector<8xi8>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_8(%metadata: i32, %compdata: vector<8xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_8(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : i32, vector<8xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=16: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_16(%metadata: i32, %compdata: vector<16xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_16(i32 %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.i32.v16i8(i32 %0, <16 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : i32, vector<16xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=32: metadata=2 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_32(%metadata: vector<2xi32>, %compdata: vector<32xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_32(<2 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.v2i32.v32i8(<2 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : vector<2xi32>, vector<32xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=64: metadata=4 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_64(%metadata: vector<4xi32>, %compdata: vector<64xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_64(<4 x i32> %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.v4i32.v64i8(<4 x i32> %0, <64 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : vector<4xi32>, vector<64xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<2xi8>) -> vector<4xi8> {
+  // CHECK-LABEL: define <4 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_2(i32 %0, <2 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i8> @llvm.nvvm.spdecompress.v4i8.i32.v2i8(i32 %0, <2 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <4 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : i32, vector<2xi8> -> vector<4xi8>
+  llvm.return %res : vector<4xi8>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<4xi8>) -> vector<8xi8> {
+  // CHECK-LABEL: define <8 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_4(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i8> @llvm.nvvm.spdecompress.v8i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <8 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : i32, vector<4xi8> -> vector<8xi8>
+  llvm.return %res : vector<8xi8>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_8(%metadata: i32, %compdata: vector<8xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_8(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : i32, vector<8xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=16: metadata=2 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_16(%metadata: vector<2xi32>, %compdata: vector<16xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_16(<2 x i32> %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.v2i32.v16i8(<2 x i32> %0, <16 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : vector<2xi32>, vector<16xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=32: metadata=4 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_32(%metadata: vector<4xi32>, %compdata: vector<32xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_32(<4 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.v4i32.v32i8(<4 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : vector<4xi32>, vector<32xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=64: metadata=8 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_64(%metadata: vector<8xi32>, %compdata: vector<64xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b4_rpf_64(<8 x i32> %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.v8i32.v64i8(<8 x i32> %0, <64 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : vector<8xi32>, vector<64xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_1(%metadata: i32, %compdata: vector<1xi16>) -> vector<2xi16> {
+  // CHECK-LABEL: define <2 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_1(i32 %0, <1 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <2 x i16> @llvm.nvvm.spdecompress.v2i16.i32.v1i16(i32 %0, <1 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <2 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : i32, vector<1xi16> -> vector<2xi16>
+  llvm.return %res : vector<2xi16>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_2(%metadata: i32, %compdata: vector<2xi16>) -> vector<4xi16> {
+  // CHECK-LABEL: define <4 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_2(i32 %0, <2 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i16> @llvm.nvvm.spdecompress.v4i16.i32.v2i16(i32 %0, <2 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <4 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : i32, vector<2xi16> -> vector<4xi16>
+  llvm.return %res : vector<4xi16>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_4(%metadata: i32, %compdata: vector<4xi16>) -> vector<8xi16> {
+  // CHECK-LABEL: define <8 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_4(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i16> @llvm.nvvm.spdecompress.v8i16.i32.v4i16(i32 %0, <4 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <8 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : i32, vector<4xi16> -> vector<8xi16>
+  llvm.return %res : vector<8xi16>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_8(%metadata: i32, %compdata: vector<8xi16>) -> vector<16xi16> {
+  // CHECK-LABEL: define <16 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_8(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i16> @llvm.nvvm.spdecompress.v16i16.i32.v8i16(i32 %0, <8 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <16 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : i32, vector<8xi16> -> vector<16xi16>
+  llvm.return %res : vector<16xi16>
+}
+
+// rpf=16: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_16(%metadata: i32, %compdata: vector<16xi16>) -> vector<32xi16> {
+  // CHECK-LABEL: define <32 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_16(i32 %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i16> @llvm.nvvm.spdecompress.v32i16.i32.v16i16(i32 %0, <16 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <32 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : i32, vector<16xi16> -> vector<32xi16>
+  llvm.return %res : vector<32xi16>
+}
+
+// rpf=32: metadata=2 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_32(%metadata: vector<2xi32>, %compdata: vector<32xi16>) -> vector<64xi16> {
+  // CHECK-LABEL: define <64 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_32(<2 x i32> %0, <32 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i16> @llvm.nvvm.spdecompress.v64i16.v2i32.v32i16(<2 x i32> %0, <32 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <64 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : vector<2xi32>, vector<32xi16> -> vector<64xi16>
+  llvm.return %res : vector<64xi16>
+}
+
+// rpf=64: metadata=4 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_64(%metadata: vector<4xi32>, %compdata: vector<64xi16>) -> vector<128xi16> {
+  // CHECK-LABEL: define <128 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b2_rpf_64(<4 x i32> %0, <64 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i16> @llvm.nvvm.spdecompress.v128i16.v4i32.v64i16(<4 x i32> %0, <64 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <128 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : vector<4xi32>, vector<64xi16> -> vector<128xi16>
+  llvm.return %res : vector<128xi16>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<1xi16>) -> vector<2xi16> {
+  // CHECK-LABEL: define <2 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_1(i32 %0, <1 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <2 x i16> @llvm.nvvm.spdecompress.v2i16.i32.v1i16(i32 %0, <1 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <2 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : i32, vector<1xi16> -> vector<2xi16>
+  llvm.return %res : vector<2xi16>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<2xi16>) -> vector<4xi16> {
+  // CHECK-LABEL: define <4 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_2(i32 %0, <2 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i16> @llvm.nvvm.spdecompress.v4i16.i32.v2i16(i32 %0, <2 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <4 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : i32, vector<2xi16> -> vector<4xi16>
+  llvm.return %res : vector<4xi16>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<4xi16>) -> vector<8xi16> {
+  // CHECK-LABEL: define <8 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_4(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i16> @llvm.nvvm.spdecompress.v8i16.i32.v4i16(i32 %0, <4 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <8 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : i32, vector<4xi16> -> vector<8xi16>
+  llvm.return %res : vector<8xi16>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_8(%metadata: i32, %compdata: vector<8xi16>) -> vector<16xi16> {
+  // CHECK-LABEL: define <16 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_8(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i16> @llvm.nvvm.spdecompress.v16i16.i32.v8i16(i32 %0, <8 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <16 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : i32, vector<8xi16> -> vector<16xi16>
+  llvm.return %res : vector<16xi16>
+}
+
+// rpf=16: metadata=2 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_16(%metadata: vector<2xi32>, %compdata: vector<16xi16>) -> vector<32xi16> {
+  // CHECK-LABEL: define <32 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_16(<2 x i32> %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i16> @llvm.nvvm.spdecompress.v32i16.v2i32.v16i16(<2 x i32> %0, <16 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <32 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : vector<2xi32>, vector<16xi16> -> vector<32xi16>
+  llvm.return %res : vector<32xi16>
+}
+
+// rpf=32: metadata=4 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_32(%metadata: vector<4xi32>, %compdata: vector<32xi16>) -> vector<64xi16> {
+  // CHECK-LABEL: define <64 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_32(<4 x i32> %0, <32 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i16> @llvm.nvvm.spdecompress.v64i16.v4i32.v32i16(<4 x i32> %0, <32 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <64 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : vector<4xi32>, vector<32xi16> -> vector<64xi16>
+  llvm.return %res : vector<64xi16>
+}
+
+// rpf=64: metadata=8 register(s)
+llvm.func @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_64(%metadata: vector<8xi32>, %compdata: vector<64xi16>) -> vector<128xi16> {
+  // CHECK-LABEL: define <128 x i16> @spdecompress_sp1to2_elmsz_b16_idxsz_b4_rpf_64(<8 x i32> %0, <64 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i16> @llvm.nvvm.spdecompress.v128i16.v8i32.v64i16(<8 x i32> %0, <64 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <128 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 2
+      : vector<8xi32>, vector<64xi16> -> vector<128xi16>
+  llvm.return %res : vector<128xi16>
+}
+
+// rpf=2: metadata=1 register(s), passed as vector<1xi32>
+llvm.func @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_2_vec1(%metadata: vector<1xi32>, %compdata: vector<2xi8>) -> vector<4xi8> {
+  // CHECK-LABEL: define <4 x i8> @spdecompress_sp1to2_elmsz_b8_idxsz_b2_rpf_2_vec1(<1 x i32> %0, <2 x i8> %1) {
+  // CHECK-NEXT:    %[[MDATA:[0-9]+]] = bitcast <1 x i32> %0 to i32
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i8> @llvm.nvvm.spdecompress.v4i8.i32.v2i8(i32 %[[MDATA]], <2 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 2)
+  // CHECK-NEXT:    ret <4 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 2
+      : vector<1xi32>, vector<2xi8> -> vector<4xi8>
+  llvm.return %res : vector<4xi8>
+}

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to4.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to4.mlir
new file mode 100644
index 00000000000000..fe3eb73f71b65b
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to4.mlir
@@ -0,0 +1,309 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_1(%metadata: i32, %compdata: vector<1xi8>) -> vector<4xi8> {
+  // CHECK-LABEL: define <4 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_1(i32 %0, <1 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i8> @llvm.nvvm.spdecompress.v4i8.i32.v1i8(i32 %0, <1 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <4 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<1xi8> -> vector<4xi8>
+  llvm.return %res : vector<4xi8>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_2(%metadata: i32, %compdata: vector<2xi8>) -> vector<8xi8> {
+  // CHECK-LABEL: define <8 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_2(i32 %0, <2 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i8> @llvm.nvvm.spdecompress.v8i8.i32.v2i8(i32 %0, <2 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <8 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<2xi8> -> vector<8xi8>
+  llvm.return %res : vector<8xi8>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_4(%metadata: i32, %compdata: vector<4xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_4(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<4xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_8(%metadata: i32, %compdata: vector<8xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_8(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<8xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=16: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_16(%metadata: i32, %compdata: vector<16xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_16(i32 %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.i32.v16i8(i32 %0, <16 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<16xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=32: metadata=2 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_32(%metadata: vector<2xi32>, %compdata: vector<32xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_32(<2 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.v2i32.v32i8(<2 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : vector<2xi32>, vector<32xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=64: metadata=4 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_64(%metadata: vector<4xi32>, %compdata: vector<64xi8>) -> vector<256xi8> {
+  // CHECK-LABEL: define <256 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b2_rpf_64(<4 x i32> %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i8> @llvm.nvvm.spdecompress.v256i8.v4i32.v64i8(<4 x i32> %0, <64 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <256 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : vector<4xi32>, vector<64xi8> -> vector<256xi8>
+  llvm.return %res : vector<256xi8>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<1xi8>) -> vector<4xi8> {
+  // CHECK-LABEL: define <4 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_1(i32 %0, <1 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i8> @llvm.nvvm.spdecompress.v4i8.i32.v1i8(i32 %0, <1 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <4 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<1xi8> -> vector<4xi8>
+  llvm.return %res : vector<4xi8>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<2xi8>) -> vector<8xi8> {
+  // CHECK-LABEL: define <8 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_2(i32 %0, <2 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i8> @llvm.nvvm.spdecompress.v8i8.i32.v2i8(i32 %0, <2 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <8 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<2xi8> -> vector<8xi8>
+  llvm.return %res : vector<8xi8>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<4xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_4(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<4xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_8(%metadata: i32, %compdata: vector<8xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_8(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<8xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=16: metadata=2 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_16(%metadata: vector<2xi32>, %compdata: vector<16xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_16(<2 x i32> %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.v2i32.v16i8(<2 x i32> %0, <16 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<2xi32>, vector<16xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=32: metadata=4 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_32(%metadata: vector<4xi32>, %compdata: vector<32xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_32(<4 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.v4i32.v32i8(<4 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<4xi32>, vector<32xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=64: metadata=8 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_64(%metadata: vector<8xi32>, %compdata: vector<64xi8>) -> vector<256xi8> {
+  // CHECK-LABEL: define <256 x i8> @spdecompress_sp1to4_elmsz_b8_idxsz_b4_rpf_64(<8 x i32> %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i8> @llvm.nvvm.spdecompress.v256i8.v8i32.v64i8(<8 x i32> %0, <64 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <256 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<8xi32>, vector<64xi8> -> vector<256xi8>
+  llvm.return %res : vector<256xi8>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_1(%metadata: i32, %compdata: vector<1xi16>) -> vector<4xi16> {
+  // CHECK-LABEL: define <4 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_1(i32 %0, <1 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i16> @llvm.nvvm.spdecompress.v4i16.i32.v1i16(i32 %0, <1 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <4 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<1xi16> -> vector<4xi16>
+  llvm.return %res : vector<4xi16>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_2(%metadata: i32, %compdata: vector<2xi16>) -> vector<8xi16> {
+  // CHECK-LABEL: define <8 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_2(i32 %0, <2 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i16> @llvm.nvvm.spdecompress.v8i16.i32.v2i16(i32 %0, <2 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <8 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<2xi16> -> vector<8xi16>
+  llvm.return %res : vector<8xi16>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_4(%metadata: i32, %compdata: vector<4xi16>) -> vector<16xi16> {
+  // CHECK-LABEL: define <16 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_4(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i16> @llvm.nvvm.spdecompress.v16i16.i32.v4i16(i32 %0, <4 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <16 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<4xi16> -> vector<16xi16>
+  llvm.return %res : vector<16xi16>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_8(%metadata: i32, %compdata: vector<8xi16>) -> vector<32xi16> {
+  // CHECK-LABEL: define <32 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_8(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i16> @llvm.nvvm.spdecompress.v32i16.i32.v8i16(i32 %0, <8 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <32 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<8xi16> -> vector<32xi16>
+  llvm.return %res : vector<32xi16>
+}
+
+// rpf=16: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_16(%metadata: i32, %compdata: vector<16xi16>) -> vector<64xi16> {
+  // CHECK-LABEL: define <64 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_16(i32 %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i16> @llvm.nvvm.spdecompress.v64i16.i32.v16i16(i32 %0, <16 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <64 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<16xi16> -> vector<64xi16>
+  llvm.return %res : vector<64xi16>
+}
+
+// rpf=32: metadata=2 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_32(%metadata: vector<2xi32>, %compdata: vector<32xi16>) -> vector<128xi16> {
+  // CHECK-LABEL: define <128 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_32(<2 x i32> %0, <32 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i16> @llvm.nvvm.spdecompress.v128i16.v2i32.v32i16(<2 x i32> %0, <32 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <128 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : vector<2xi32>, vector<32xi16> -> vector<128xi16>
+  llvm.return %res : vector<128xi16>
+}
+
+// rpf=64: metadata=4 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_64(%metadata: vector<4xi32>, %compdata: vector<64xi16>) -> vector<256xi16> {
+  // CHECK-LABEL: define <256 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b2_rpf_64(<4 x i32> %0, <64 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i16> @llvm.nvvm.spdecompress.v256i16.v4i32.v64i16(<4 x i32> %0, <64 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <256 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : vector<4xi32>, vector<64xi16> -> vector<256xi16>
+  llvm.return %res : vector<256xi16>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<1xi16>) -> vector<4xi16> {
+  // CHECK-LABEL: define <4 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_1(i32 %0, <1 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i16> @llvm.nvvm.spdecompress.v4i16.i32.v1i16(i32 %0, <1 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <4 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<1xi16> -> vector<4xi16>
+  llvm.return %res : vector<4xi16>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<2xi16>) -> vector<8xi16> {
+  // CHECK-LABEL: define <8 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_2(i32 %0, <2 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i16> @llvm.nvvm.spdecompress.v8i16.i32.v2i16(i32 %0, <2 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <8 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<2xi16> -> vector<8xi16>
+  llvm.return %res : vector<8xi16>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<4xi16>) -> vector<16xi16> {
+  // CHECK-LABEL: define <16 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_4(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i16> @llvm.nvvm.spdecompress.v16i16.i32.v4i16(i32 %0, <4 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <16 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<4xi16> -> vector<16xi16>
+  llvm.return %res : vector<16xi16>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_8(%metadata: i32, %compdata: vector<8xi16>) -> vector<32xi16> {
+  // CHECK-LABEL: define <32 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_8(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i16> @llvm.nvvm.spdecompress.v32i16.i32.v8i16(i32 %0, <8 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <32 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<8xi16> -> vector<32xi16>
+  llvm.return %res : vector<32xi16>
+}
+
+// rpf=16: metadata=2 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_16(%metadata: vector<2xi32>, %compdata: vector<16xi16>) -> vector<64xi16> {
+  // CHECK-LABEL: define <64 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_16(<2 x i32> %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i16> @llvm.nvvm.spdecompress.v64i16.v2i32.v16i16(<2 x i32> %0, <16 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <64 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<2xi32>, vector<16xi16> -> vector<64xi16>
+  llvm.return %res : vector<64xi16>
+}
+
+// rpf=32: metadata=4 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_32(%metadata: vector<4xi32>, %compdata: vector<32xi16>) -> vector<128xi16> {
+  // CHECK-LABEL: define <128 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_32(<4 x i32> %0, <32 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i16> @llvm.nvvm.spdecompress.v128i16.v4i32.v32i16(<4 x i32> %0, <32 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <128 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<4xi32>, vector<32xi16> -> vector<128xi16>
+  llvm.return %res : vector<128xi16>
+}
+
+// rpf=64: metadata=8 register(s)
+llvm.func @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_64(%metadata: vector<8xi32>, %compdata: vector<64xi16>) -> vector<256xi16> {
+  // CHECK-LABEL: define <256 x i16> @spdecompress_sp1to4_elmsz_b16_idxsz_b4_rpf_64(<8 x i32> %0, <64 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i16> @llvm.nvvm.spdecompress.v256i16.v8i32.v64i16(<8 x i32> %0, <64 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <256 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<8xi32>, vector<64xi16> -> vector<256xi16>
+  llvm.return %res : vector<256xi16>
+}

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to8.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to8.mlir
new file mode 100644
index 00000000000000..3c87d467d616e8
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp1to8.mlir
@@ -0,0 +1,144 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<1xi8>) -> vector<8xi8> {
+  // CHECK-LABEL: define <8 x i8> @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_1(i32 %0, <1 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i8> @llvm.nvvm.spdecompress.v8i8.i32.v1i8(i32 %0, <1 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <8 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<1xi8> -> vector<8xi8>
+  llvm.return %res : vector<8xi8>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<2xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_2(i32 %0, <2 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v2i8(i32 %0, <2 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<2xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<4xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_4(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<4xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_8(%metadata: i32, %compdata: vector<8xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_8(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<8xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=16: metadata=2 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_16(%metadata: vector<2xi32>, %compdata: vector<16xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_16(<2 x i32> %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.v2i32.v16i8(<2 x i32> %0, <16 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<2xi32>, vector<16xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=32: metadata=4 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_32(%metadata: vector<4xi32>, %compdata: vector<32xi8>) -> vector<256xi8> {
+  // CHECK-LABEL: define <256 x i8> @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_32(<4 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i8> @llvm.nvvm.spdecompress.v256i8.v4i32.v32i8(<4 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <256 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<4xi32>, vector<32xi8> -> vector<256xi8>
+  llvm.return %res : vector<256xi8>
+}
+
+// rpf=64: metadata=8 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_64(%metadata: vector<8xi32>, %compdata: vector<64xi8>) -> vector<512xi8> {
+  // CHECK-LABEL: define <512 x i8> @spdecompress_sp1to8_elmsz_b8_idxsz_b4_rpf_64(<8 x i32> %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <512 x i8> @llvm.nvvm.spdecompress.v512i8.v8i32.v64i8(<8 x i32> %0, <64 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <512 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<8xi32>, vector<64xi8> -> vector<512xi8>
+  llvm.return %res : vector<512xi8>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<1xi16>) -> vector<8xi16> {
+  // CHECK-LABEL: define <8 x i16> @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_1(i32 %0, <1 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i16> @llvm.nvvm.spdecompress.v8i16.i32.v1i16(i32 %0, <1 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <8 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<1xi16> -> vector<8xi16>
+  llvm.return %res : vector<8xi16>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<2xi16>) -> vector<16xi16> {
+  // CHECK-LABEL: define <16 x i16> @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_2(i32 %0, <2 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i16> @llvm.nvvm.spdecompress.v16i16.i32.v2i16(i32 %0, <2 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <16 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<2xi16> -> vector<16xi16>
+  llvm.return %res : vector<16xi16>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<4xi16>) -> vector<32xi16> {
+  // CHECK-LABEL: define <32 x i16> @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_4(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i16> @llvm.nvvm.spdecompress.v32i16.i32.v4i16(i32 %0, <4 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <32 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<4xi16> -> vector<32xi16>
+  llvm.return %res : vector<32xi16>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_8(%metadata: i32, %compdata: vector<8xi16>) -> vector<64xi16> {
+  // CHECK-LABEL: define <64 x i16> @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_8(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i16> @llvm.nvvm.spdecompress.v64i16.i32.v8i16(i32 %0, <8 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <64 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<8xi16> -> vector<64xi16>
+  llvm.return %res : vector<64xi16>
+}
+
+// rpf=16: metadata=2 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_16(%metadata: vector<2xi32>, %compdata: vector<16xi16>) -> vector<128xi16> {
+  // CHECK-LABEL: define <128 x i16> @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_16(<2 x i32> %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i16> @llvm.nvvm.spdecompress.v128i16.v2i32.v16i16(<2 x i32> %0, <16 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <128 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<2xi32>, vector<16xi16> -> vector<128xi16>
+  llvm.return %res : vector<128xi16>
+}
+
+// rpf=32: metadata=4 register(s)
+llvm.func @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_32(%metadata: vector<4xi32>, %compdata: vector<32xi16>) -> vector<256xi16> {
+  // CHECK-LABEL: define <256 x i16> @spdecompress_sp1to8_elmsz_b16_idxsz_b4_rpf_32(<4 x i32> %0, <32 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i16> @llvm.nvvm.spdecompress.v256i16.v4i32.v32i16(<4 x i32> %0, <32 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <256 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<4xi32>, vector<32xi16> -> vector<256xi16>
+  llvm.return %res : vector<256xi16>
+}

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to16.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to16.mlir
new file mode 100644
index 00000000000000..e30156b98fa509
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to16.mlir
@@ -0,0 +1,122 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<2xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_1(i32 %0, <2 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v2i8(i32 %0, <2 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<2xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<4xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_2(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<4xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<8xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_4(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<8xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=8: metadata=2 register(s)
+llvm.func @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_8(%metadata: vector<2xi32>, %compdata: vector<16xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_8(<2 x i32> %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.v2i32.v16i8(<2 x i32> %0, <16 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<2xi32>, vector<16xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=16: metadata=4 register(s)
+llvm.func @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_16(%metadata: vector<4xi32>, %compdata: vector<32xi8>) -> vector<256xi8> {
+  // CHECK-LABEL: define <256 x i8> @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_16(<4 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i8> @llvm.nvvm.spdecompress.v256i8.v4i32.v32i8(<4 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <256 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<4xi32>, vector<32xi8> -> vector<256xi8>
+  llvm.return %res : vector<256xi8>
+}
+
+// rpf=32: metadata=8 register(s)
+llvm.func @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_32(%metadata: vector<8xi32>, %compdata: vector<64xi8>) -> vector<512xi8> {
+  // CHECK-LABEL: define <512 x i8> @spdecompress_sp2to16_elmsz_b8_idxsz_b4_rpf_32(<8 x i32> %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <512 x i8> @llvm.nvvm.spdecompress.v512i8.v8i32.v64i8(<8 x i32> %0, <64 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <512 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<8xi32>, vector<64xi8> -> vector<512xi8>
+  llvm.return %res : vector<512xi8>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp2to16_elmsz_b16_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<2xi16>) -> vector<16xi16> {
+  // CHECK-LABEL: define <16 x i16> @spdecompress_sp2to16_elmsz_b16_idxsz_b4_rpf_1(i32 %0, <2 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i16> @llvm.nvvm.spdecompress.v16i16.i32.v2i16(i32 %0, <2 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <16 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<2xi16> -> vector<16xi16>
+  llvm.return %res : vector<16xi16>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp2to16_elmsz_b16_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<4xi16>) -> vector<32xi16> {
+  // CHECK-LABEL: define <32 x i16> @spdecompress_sp2to16_elmsz_b16_idxsz_b4_rpf_2(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i16> @llvm.nvvm.spdecompress.v32i16.i32.v4i16(i32 %0, <4 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <32 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<4xi16> -> vector<32xi16>
+  llvm.return %res : vector<32xi16>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp2to16_elmsz_b16_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<8xi16>) -> vector<64xi16> {
+  // CHECK-LABEL: define <64 x i16> @spdecompress_sp2to16_elmsz_b16_idxsz_b4_rpf_4(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i16> @llvm.nvvm.spdecompress.v64i16.i32.v8i16(i32 %0, <8 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <64 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<8xi16> -> vector<64xi16>
+  llvm.return %res : vector<64xi16>
+}
+
+// rpf=8: metadata=2 register(s)
+llvm.func @spdecompress_sp2to16_elmsz_b16_idxsz_b4_rpf_8(%metadata: vector<2xi32>, %compdata: vector<16xi16>) -> vector<128xi16> {
+  // CHECK-LABEL: define <128 x i16> @spdecompress_sp2to16_elmsz_b16_idxsz_b4_rpf_8(<2 x i32> %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i16> @llvm.nvvm.spdecompress.v128i16.v2i32.v16i16(<2 x i32> %0, <16 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <128 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<2xi32>, vector<16xi16> -> vector<128xi16>
+  llvm.return %res : vector<128xi16>
+}
+
+// rpf=16: metadata=4 register(s)
+llvm.func @spdecompress_sp2to16_elmsz_b16_idxsz_b4_rpf_16(%metadata: vector<4xi32>, %compdata: vector<32xi16>) -> vector<256xi16> {
+  // CHECK-LABEL: define <256 x i16> @spdecompress_sp2to16_elmsz_b16_idxsz_b4_rpf_16(<4 x i32> %0, <32 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i16> @llvm.nvvm.spdecompress.v256i16.v4i32.v32i16(<4 x i32> %0, <32 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <256 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<4xi32>, vector<32xi16> -> vector<256xi16>
+  llvm.return %res : vector<256xi16>
+}

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to4.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to4.mlir
new file mode 100644
index 00000000000000..366b7429c4dcaa
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to4.mlir
@@ -0,0 +1,309 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_1(%metadata: i32, %compdata: vector<2xi8>) -> vector<4xi8> {
+  // CHECK-LABEL: define <4 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_1(i32 %0, <2 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i8> @llvm.nvvm.spdecompress.v4i8.i32.v2i8(i32 %0, <2 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <4 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<2xi8> -> vector<4xi8>
+  llvm.return %res : vector<4xi8>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_2(%metadata: i32, %compdata: vector<4xi8>) -> vector<8xi8> {
+  // CHECK-LABEL: define <8 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_2(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i8> @llvm.nvvm.spdecompress.v8i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <8 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<4xi8> -> vector<8xi8>
+  llvm.return %res : vector<8xi8>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_4(%metadata: i32, %compdata: vector<8xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_4(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<8xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_8(%metadata: i32, %compdata: vector<16xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_8(i32 %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.i32.v16i8(i32 %0, <16 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<16xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=16: metadata=2 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_16(%metadata: vector<2xi32>, %compdata: vector<32xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_16(<2 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.v2i32.v32i8(<2 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : vector<2xi32>, vector<32xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=32: metadata=4 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_32(%metadata: vector<4xi32>, %compdata: vector<64xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_32(<4 x i32> %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.v4i32.v64i8(<4 x i32> %0, <64 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : vector<4xi32>, vector<64xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=64: metadata=8 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_64(%metadata: vector<8xi32>, %compdata: vector<128xi8>) -> vector<256xi8> {
+  // CHECK-LABEL: define <256 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b2_rpf_64(<8 x i32> %0, <128 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i8> @llvm.nvvm.spdecompress.v256i8.v8i32.v128i8(<8 x i32> %0, <128 x i8> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <256 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : vector<8xi32>, vector<128xi8> -> vector<256xi8>
+  llvm.return %res : vector<256xi8>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<2xi8>) -> vector<4xi8> {
+  // CHECK-LABEL: define <4 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_1(i32 %0, <2 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i8> @llvm.nvvm.spdecompress.v4i8.i32.v2i8(i32 %0, <2 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <4 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<2xi8> -> vector<4xi8>
+  llvm.return %res : vector<4xi8>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<4xi8>) -> vector<8xi8> {
+  // CHECK-LABEL: define <8 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_2(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i8> @llvm.nvvm.spdecompress.v8i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <8 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<4xi8> -> vector<8xi8>
+  llvm.return %res : vector<8xi8>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<8xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_4(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<8xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=8: metadata=2 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_8(%metadata: vector<2xi32>, %compdata: vector<16xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_8(<2 x i32> %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.v2i32.v16i8(<2 x i32> %0, <16 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<2xi32>, vector<16xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=16: metadata=4 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_16(%metadata: vector<4xi32>, %compdata: vector<32xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_16(<4 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.v4i32.v32i8(<4 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<4xi32>, vector<32xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=32: metadata=8 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_32(%metadata: vector<8xi32>, %compdata: vector<64xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_32(<8 x i32> %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.v8i32.v64i8(<8 x i32> %0, <64 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<8xi32>, vector<64xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=64: metadata=16 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_64(%metadata: vector<16xi32>, %compdata: vector<128xi8>) -> vector<256xi8> {
+  // CHECK-LABEL: define <256 x i8> @spdecompress_sp2to4_elmsz_b8_idxsz_b4_rpf_64(<16 x i32> %0, <128 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i8> @llvm.nvvm.spdecompress.v256i8.v16i32.v128i8(<16 x i32> %0, <128 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <256 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<16xi32>, vector<128xi8> -> vector<256xi8>
+  llvm.return %res : vector<256xi8>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_1(%metadata: i32, %compdata: vector<2xi16>) -> vector<4xi16> {
+  // CHECK-LABEL: define <4 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_1(i32 %0, <2 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i16> @llvm.nvvm.spdecompress.v4i16.i32.v2i16(i32 %0, <2 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <4 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<2xi16> -> vector<4xi16>
+  llvm.return %res : vector<4xi16>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_2(%metadata: i32, %compdata: vector<4xi16>) -> vector<8xi16> {
+  // CHECK-LABEL: define <8 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_2(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i16> @llvm.nvvm.spdecompress.v8i16.i32.v4i16(i32 %0, <4 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <8 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<4xi16> -> vector<8xi16>
+  llvm.return %res : vector<8xi16>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_4(%metadata: i32, %compdata: vector<8xi16>) -> vector<16xi16> {
+  // CHECK-LABEL: define <16 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_4(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i16> @llvm.nvvm.spdecompress.v16i16.i32.v8i16(i32 %0, <8 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <16 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<8xi16> -> vector<16xi16>
+  llvm.return %res : vector<16xi16>
+}
+
+// rpf=8: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_8(%metadata: i32, %compdata: vector<16xi16>) -> vector<32xi16> {
+  // CHECK-LABEL: define <32 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_8(i32 %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i16> @llvm.nvvm.spdecompress.v32i16.i32.v16i16(i32 %0, <16 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <32 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : i32, vector<16xi16> -> vector<32xi16>
+  llvm.return %res : vector<32xi16>
+}
+
+// rpf=16: metadata=2 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_16(%metadata: vector<2xi32>, %compdata: vector<32xi16>) -> vector<64xi16> {
+  // CHECK-LABEL: define <64 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_16(<2 x i32> %0, <32 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i16> @llvm.nvvm.spdecompress.v64i16.v2i32.v32i16(<2 x i32> %0, <32 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <64 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : vector<2xi32>, vector<32xi16> -> vector<64xi16>
+  llvm.return %res : vector<64xi16>
+}
+
+// rpf=32: metadata=4 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_32(%metadata: vector<4xi32>, %compdata: vector<64xi16>) -> vector<128xi16> {
+  // CHECK-LABEL: define <128 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_32(<4 x i32> %0, <64 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i16> @llvm.nvvm.spdecompress.v128i16.v4i32.v64i16(<4 x i32> %0, <64 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <128 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : vector<4xi32>, vector<64xi16> -> vector<128xi16>
+  llvm.return %res : vector<128xi16>
+}
+
+// rpf=64: metadata=8 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_64(%metadata: vector<8xi32>, %compdata: vector<128xi16>) -> vector<256xi16> {
+  // CHECK-LABEL: define <256 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b2_rpf_64(<8 x i32> %0, <128 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i16> @llvm.nvvm.spdecompress.v256i16.v8i32.v128i16(<8 x i32> %0, <128 x i16> %1, /* idx_size= */ i32 2, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <256 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 2 num_tgt = 4
+      : vector<8xi32>, vector<128xi16> -> vector<256xi16>
+  llvm.return %res : vector<256xi16>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<2xi16>) -> vector<4xi16> {
+  // CHECK-LABEL: define <4 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_1(i32 %0, <2 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <4 x i16> @llvm.nvvm.spdecompress.v4i16.i32.v2i16(i32 %0, <2 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <4 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<2xi16> -> vector<4xi16>
+  llvm.return %res : vector<4xi16>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<4xi16>) -> vector<8xi16> {
+  // CHECK-LABEL: define <8 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_2(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i16> @llvm.nvvm.spdecompress.v8i16.i32.v4i16(i32 %0, <4 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <8 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<4xi16> -> vector<8xi16>
+  llvm.return %res : vector<8xi16>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<8xi16>) -> vector<16xi16> {
+  // CHECK-LABEL: define <16 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_4(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i16> @llvm.nvvm.spdecompress.v16i16.i32.v8i16(i32 %0, <8 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <16 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : i32, vector<8xi16> -> vector<16xi16>
+  llvm.return %res : vector<16xi16>
+}
+
+// rpf=8: metadata=2 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_8(%metadata: vector<2xi32>, %compdata: vector<16xi16>) -> vector<32xi16> {
+  // CHECK-LABEL: define <32 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_8(<2 x i32> %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i16> @llvm.nvvm.spdecompress.v32i16.v2i32.v16i16(<2 x i32> %0, <16 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <32 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<2xi32>, vector<16xi16> -> vector<32xi16>
+  llvm.return %res : vector<32xi16>
+}
+
+// rpf=16: metadata=4 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_16(%metadata: vector<4xi32>, %compdata: vector<32xi16>) -> vector<64xi16> {
+  // CHECK-LABEL: define <64 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_16(<4 x i32> %0, <32 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i16> @llvm.nvvm.spdecompress.v64i16.v4i32.v32i16(<4 x i32> %0, <32 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <64 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<4xi32>, vector<32xi16> -> vector<64xi16>
+  llvm.return %res : vector<64xi16>
+}
+
+// rpf=32: metadata=8 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_32(%metadata: vector<8xi32>, %compdata: vector<64xi16>) -> vector<128xi16> {
+  // CHECK-LABEL: define <128 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_32(<8 x i32> %0, <64 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i16> @llvm.nvvm.spdecompress.v128i16.v8i32.v64i16(<8 x i32> %0, <64 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <128 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<8xi32>, vector<64xi16> -> vector<128xi16>
+  llvm.return %res : vector<128xi16>
+}
+
+// rpf=64: metadata=16 register(s)
+llvm.func @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_64(%metadata: vector<16xi32>, %compdata: vector<128xi16>) -> vector<256xi16> {
+  // CHECK-LABEL: define <256 x i16> @spdecompress_sp2to4_elmsz_b16_idxsz_b4_rpf_64(<16 x i32> %0, <128 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i16> @llvm.nvvm.spdecompress.v256i16.v16i32.v128i16(<16 x i32> %0, <128 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 4)
+  // CHECK-NEXT:    ret <256 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 4
+      : vector<16xi32>, vector<128xi16> -> vector<256xi16>
+  llvm.return %res : vector<256xi16>
+}

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to8.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to8.mlir
new file mode 100644
index 00000000000000..6ba4d833ff40c1
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp2to8.mlir
@@ -0,0 +1,144 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<2xi8>) -> vector<8xi8> {
+  // CHECK-LABEL: define <8 x i8> @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_1(i32 %0, <2 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i8> @llvm.nvvm.spdecompress.v8i8.i32.v2i8(i32 %0, <2 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <8 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<2xi8> -> vector<8xi8>
+  llvm.return %res : vector<8xi8>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<4xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_2(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<4xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<8xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_4(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<8xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=8: metadata=2 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_8(%metadata: vector<2xi32>, %compdata: vector<16xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_8(<2 x i32> %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.v2i32.v16i8(<2 x i32> %0, <16 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<2xi32>, vector<16xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=16: metadata=4 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_16(%metadata: vector<4xi32>, %compdata: vector<32xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_16(<4 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.v4i32.v32i8(<4 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<4xi32>, vector<32xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=32: metadata=8 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_32(%metadata: vector<8xi32>, %compdata: vector<64xi8>) -> vector<256xi8> {
+  // CHECK-LABEL: define <256 x i8> @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_32(<8 x i32> %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i8> @llvm.nvvm.spdecompress.v256i8.v8i32.v64i8(<8 x i32> %0, <64 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <256 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<8xi32>, vector<64xi8> -> vector<256xi8>
+  llvm.return %res : vector<256xi8>
+}
+
+// rpf=64: metadata=16 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_64(%metadata: vector<16xi32>, %compdata: vector<128xi8>) -> vector<512xi8> {
+  // CHECK-LABEL: define <512 x i8> @spdecompress_sp2to8_elmsz_b8_idxsz_b4_rpf_64(<16 x i32> %0, <128 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <512 x i8> @llvm.nvvm.spdecompress.v512i8.v16i32.v128i8(<16 x i32> %0, <128 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <512 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<16xi32>, vector<128xi8> -> vector<512xi8>
+  llvm.return %res : vector<512xi8>
+}
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<2xi16>) -> vector<8xi16> {
+  // CHECK-LABEL: define <8 x i16> @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_1(i32 %0, <2 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i16> @llvm.nvvm.spdecompress.v8i16.i32.v2i16(i32 %0, <2 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <8 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<2xi16> -> vector<8xi16>
+  llvm.return %res : vector<8xi16>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<4xi16>) -> vector<16xi16> {
+  // CHECK-LABEL: define <16 x i16> @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_2(i32 %0, <4 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i16> @llvm.nvvm.spdecompress.v16i16.i32.v4i16(i32 %0, <4 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <16 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<4xi16> -> vector<16xi16>
+  llvm.return %res : vector<16xi16>
+}
+
+// rpf=4: metadata=1 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_4(%metadata: i32, %compdata: vector<8xi16>) -> vector<32xi16> {
+  // CHECK-LABEL: define <32 x i16> @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_4(i32 %0, <8 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i16> @llvm.nvvm.spdecompress.v32i16.i32.v8i16(i32 %0, <8 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <32 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<8xi16> -> vector<32xi16>
+  llvm.return %res : vector<32xi16>
+}
+
+// rpf=8: metadata=2 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_8(%metadata: vector<2xi32>, %compdata: vector<16xi16>) -> vector<64xi16> {
+  // CHECK-LABEL: define <64 x i16> @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_8(<2 x i32> %0, <16 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i16> @llvm.nvvm.spdecompress.v64i16.v2i32.v16i16(<2 x i32> %0, <16 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <64 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<2xi32>, vector<16xi16> -> vector<64xi16>
+  llvm.return %res : vector<64xi16>
+}
+
+// rpf=16: metadata=4 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_16(%metadata: vector<4xi32>, %compdata: vector<32xi16>) -> vector<128xi16> {
+  // CHECK-LABEL: define <128 x i16> @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_16(<4 x i32> %0, <32 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i16> @llvm.nvvm.spdecompress.v128i16.v4i32.v32i16(<4 x i32> %0, <32 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <128 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<4xi32>, vector<32xi16> -> vector<128xi16>
+  llvm.return %res : vector<128xi16>
+}
+
+// rpf=32: metadata=8 register(s)
+llvm.func @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_32(%metadata: vector<8xi32>, %compdata: vector<64xi16>) -> vector<256xi16> {
+  // CHECK-LABEL: define <256 x i16> @spdecompress_sp2to8_elmsz_b16_idxsz_b4_rpf_32(<8 x i32> %0, <64 x i16> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i16> @llvm.nvvm.spdecompress.v256i16.v8i32.v64i16(<8 x i32> %0, <64 x i16> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <256 x i16> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<8xi32>, vector<64xi16> -> vector<256xi16>
+  llvm.return %res : vector<256xi16>
+}

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp4to16.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp4to16.mlir
new file mode 100644
index 00000000000000..b271d55721e7b8
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp4to16.mlir
@@ -0,0 +1,67 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<4xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_1(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<4xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<8xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_2(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : i32, vector<8xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=4: metadata=2 register(s)
+llvm.func @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_4(%metadata: vector<2xi32>, %compdata: vector<16xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_4(<2 x i32> %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.v2i32.v16i8(<2 x i32> %0, <16 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<2xi32>, vector<16xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=8: metadata=4 register(s)
+llvm.func @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_8(%metadata: vector<4xi32>, %compdata: vector<32xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_8(<4 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.v4i32.v32i8(<4 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<4xi32>, vector<32xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=16: metadata=8 register(s)
+llvm.func @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_16(%metadata: vector<8xi32>, %compdata: vector<64xi8>) -> vector<256xi8> {
+  // CHECK-LABEL: define <256 x i8> @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_16(<8 x i32> %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i8> @llvm.nvvm.spdecompress.v256i8.v8i32.v64i8(<8 x i32> %0, <64 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <256 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<8xi32>, vector<64xi8> -> vector<256xi8>
+  llvm.return %res : vector<256xi8>
+}
+
+// rpf=32: metadata=16 register(s)
+llvm.func @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_32(%metadata: vector<16xi32>, %compdata: vector<128xi8>) -> vector<512xi8> {
+  // CHECK-LABEL: define <512 x i8> @spdecompress_sp4to16_elmsz_b8_idxsz_b4_rpf_32(<16 x i32> %0, <128 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <512 x i8> @llvm.nvvm.spdecompress.v512i8.v16i32.v128i8(<16 x i32> %0, <128 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 16)
+  // CHECK-NEXT:    ret <512 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 16
+      : vector<16xi32>, vector<128xi8> -> vector<512xi8>
+  llvm.return %res : vector<512xi8>
+}

diff  --git a/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp4to8.mlir b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp4to8.mlir
new file mode 100644
index 00000000000000..03a2dabc3485a8
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/nvvm/sparse-decompress-sp4to8.mlir
@@ -0,0 +1,78 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// rpf=1: metadata=1 register(s)
+llvm.func @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_1(%metadata: i32, %compdata: vector<4xi8>) -> vector<8xi8> {
+  // CHECK-LABEL: define <8 x i8> @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_1(i32 %0, <4 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <8 x i8> @llvm.nvvm.spdecompress.v8i8.i32.v4i8(i32 %0, <4 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <8 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<4xi8> -> vector<8xi8>
+  llvm.return %res : vector<8xi8>
+}
+
+// rpf=2: metadata=1 register(s)
+llvm.func @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_2(%metadata: i32, %compdata: vector<8xi8>) -> vector<16xi8> {
+  // CHECK-LABEL: define <16 x i8> @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_2(i32 %0, <8 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <16 x i8> @llvm.nvvm.spdecompress.v16i8.i32.v8i8(i32 %0, <8 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <16 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : i32, vector<8xi8> -> vector<16xi8>
+  llvm.return %res : vector<16xi8>
+}
+
+// rpf=4: metadata=2 register(s)
+llvm.func @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_4(%metadata: vector<2xi32>, %compdata: vector<16xi8>) -> vector<32xi8> {
+  // CHECK-LABEL: define <32 x i8> @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_4(<2 x i32> %0, <16 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <32 x i8> @llvm.nvvm.spdecompress.v32i8.v2i32.v16i8(<2 x i32> %0, <16 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <32 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<2xi32>, vector<16xi8> -> vector<32xi8>
+  llvm.return %res : vector<32xi8>
+}
+
+// rpf=8: metadata=4 register(s)
+llvm.func @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_8(%metadata: vector<4xi32>, %compdata: vector<32xi8>) -> vector<64xi8> {
+  // CHECK-LABEL: define <64 x i8> @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_8(<4 x i32> %0, <32 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <64 x i8> @llvm.nvvm.spdecompress.v64i8.v4i32.v32i8(<4 x i32> %0, <32 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <64 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<4xi32>, vector<32xi8> -> vector<64xi8>
+  llvm.return %res : vector<64xi8>
+}
+
+// rpf=16: metadata=8 register(s)
+llvm.func @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_16(%metadata: vector<8xi32>, %compdata: vector<64xi8>) -> vector<128xi8> {
+  // CHECK-LABEL: define <128 x i8> @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_16(<8 x i32> %0, <64 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <128 x i8> @llvm.nvvm.spdecompress.v128i8.v8i32.v64i8(<8 x i32> %0, <64 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <128 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<8xi32>, vector<64xi8> -> vector<128xi8>
+  llvm.return %res : vector<128xi8>
+}
+
+// rpf=32: metadata=16 register(s)
+llvm.func @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_32(%metadata: vector<16xi32>, %compdata: vector<128xi8>) -> vector<256xi8> {
+  // CHECK-LABEL: define <256 x i8> @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_32(<16 x i32> %0, <128 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <256 x i8> @llvm.nvvm.spdecompress.v256i8.v16i32.v128i8(<16 x i32> %0, <128 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <256 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<16xi32>, vector<128xi8> -> vector<256xi8>
+  llvm.return %res : vector<256xi8>
+}
+
+// rpf=64: metadata=32 register(s)
+llvm.func @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_64(%metadata: vector<32xi32>, %compdata: vector<256xi8>) -> vector<512xi8> {
+  // CHECK-LABEL: define <512 x i8> @spdecompress_sp4to8_elmsz_b8_idxsz_b4_rpf_64(<32 x i32> %0, <256 x i8> %1) {
+  // CHECK-NEXT:    %[[RES:[0-9]+]] = call <512 x i8> @llvm.nvvm.spdecompress.v512i8.v32i32.v256i8(<32 x i32> %0, <256 x i8> %1, /* idx_size= */ i32 4, /* num_tgt= */ i32 8)
+  // CHECK-NEXT:    ret <512 x i8> %[[RES]]
+  // CHECK-NEXT:  }
+  %res = nvvm.sparse.decompress %metadata, %compdata idx_size = 4 num_tgt = 8
+      : vector<32xi32>, vector<256xi8> -> vector<512xi8>
+  llvm.return %res : vector<512xi8>
+}


        


More information about the Mlir-commits mailing list