[Mlir-commits] [mlir] [mlir][sparse] Implement missing BufferizableOpInterface methods for NewOp (PR #178423)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Jan 28 05:51:14 PST 2026


https://github.com/mugiwaraluffy56 created https://github.com/llvm/llvm-project/pull/178423

## Summary
Fixes crash when running `--eliminate-empty-tensors` on MLIR modules containing `sparse_tensor.new` with a tensor input.

## Problem
The `sparse_tensor.new` operation was missing the `bufferizesToMemoryRead`, `bufferizesToMemoryWrite`, and `getAliasingValues` methods in its `BufferizableOpInterface` implementation. This caused an `UNREACHABLE` crash with message "bufferizesToMemoryRead not implemented".

## Solution
Implemented the missing methods in `NewOpInterface`:
- `bufferizesToMemoryRead`: returns `true` (reads from source tensor)
- `bufferizesToMemoryWrite`: returns `false` (doesn't write to source)  
- `getAliasingValues`: returns empty (result is new allocation, not an alias)

Also added a test case for `sparse_tensor.new` with tensor input.

Fixes #178419

>From 0c85fea16db67bbde3d25debd1b89b502a5b847a Mon Sep 17 00:00:00 2001
From: mugiwaraluffy56 <myakampuneeth at gmail.com>
Date: Wed, 28 Jan 2026 19:19:51 +0530
Subject: [PATCH] [mlir][sparse] Implement missing BufferizableOpInterface
 methods for NewOp

The sparse_tensor.new operation was missing the bufferizesToMemoryRead,
bufferizesToMemoryWrite, and getAliasingValues methods in its
BufferizableOpInterface implementation. This caused crashes when running
passes like --eliminate-empty-tensors on MLIR modules containing
sparse_tensor.new with a tensor input.

The fix implements these methods:
- bufferizesToMemoryRead: returns true (reads from source tensor)
- bufferizesToMemoryWrite: returns false (doesn't write to source)
- getAliasingValues: returns empty (result is new allocation, not alias)

Also adds a test case for sparse_tensor.new with tensor input.

Fixes #178419

Co-Authored-By: Claude Opus 4.5 <noreply at anthropic.com>
---
 .../Transforms/BufferizableOpInterfaceImpl.cpp | 18 ++++++++++++++++++
 ...e_shot_bufferize_tensor_copy_insertion.mlir |  9 +++++++++
 2 files changed, 27 insertions(+)

diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/BufferizableOpInterfaceImpl.cpp
index c65781b4804db..3fc8a2313f3c2 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/BufferizableOpInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/BufferizableOpInterfaceImpl.cpp
@@ -112,6 +112,24 @@ struct LoadOpInterface
 struct NewOpInterface
     : public SparseBufferizableOpInterfaceExternalModel<NewOpInterface,
                                                         sparse_tensor::NewOp> {
+  bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand,
+                              const AnalysisState &state) const {
+    // The source tensor is read to create the sparse tensor.
+    return true;
+  }
+
+  bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand,
+                               const AnalysisState &state) const {
+    // NewOp does not write to the source.
+    return false;
+  }
+
+  AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand,
+                                      const AnalysisState &state) const {
+    // The result is a newly allocated sparse tensor, not an alias of the input.
+    return {};
+  }
+
   bool resultBufferizesToMemoryWrite(Operation *op, OpResult opResult,
                                      const AnalysisState &state) const {
     // NewOps allocate but do not write.
diff --git a/mlir/test/Dialect/SparseTensor/one_shot_bufferize_tensor_copy_insertion.mlir b/mlir/test/Dialect/SparseTensor/one_shot_bufferize_tensor_copy_insertion.mlir
index b769acdc7825c..b0a23302e0eda 100644
--- a/mlir/test/Dialect/SparseTensor/one_shot_bufferize_tensor_copy_insertion.mlir
+++ b/mlir/test/Dialect/SparseTensor/one_shot_bufferize_tensor_copy_insertion.mlir
@@ -25,6 +25,15 @@ func.func @sparse_tensor_new(%file: !Filename) -> tensor<20x40xf32, #DCSR> {
   return %0 : tensor<20x40xf32, #DCSR>
 }
 
+// CHECK-LABEL: func @sparse_tensor_new_from_tensor
+// CHECK-FUNC-LABEL: func @sparse_tensor_new_from_tensor
+func.func @sparse_tensor_new_from_tensor(%arg0: tensor<20x40xf32>) -> tensor<20x40xf32, #DCSR> {
+  // CHECK: sparse_tensor.new {{.*}}
+  // CHECK-FUNC: sparse_tensor.new {{.*}}
+  %0 = sparse_tensor.new %arg0 : tensor<20x40xf32> to tensor<20x40xf32, #DCSR>
+  return %0 : tensor<20x40xf32, #DCSR>
+}
+
 // CHECK-LABEL: func @sparse_tensor_convert
 // CHECK-FUNC-LABEL: func @sparse_tensor_convert
 func.func @sparse_tensor_convert() -> tensor<20x40xf32> {



More information about the Mlir-commits mailing list