[Mlir-commits] [mlir] [mlir][linalg] Implement bufferization for UnPackOp. (PR #182837)
Han-Chung Wang
llvmlistbot at llvm.org
Mon Feb 23 04:14:19 PST 2026
https://github.com/hanhanW created https://github.com/llvm/llvm-project/pull/182837
None
>From 3b2fcfe7575c19993ef6a13fe8cdd1575df7722e Mon Sep 17 00:00:00 2001
From: hanhanW <hanhan0912 at gmail.com>
Date: Mon, 23 Feb 2026 04:09:20 -0800
Subject: [PATCH] [mlir][linalg] Implement bufferization for UnPackOp.
Signed-off-by: hanhanW <hanhan0912 at gmail.com>
---
.../BufferizableOpInterfaceImpl.cpp | 39 +++++++++++++++++++
mlir/test/Dialect/Linalg/bufferize.mlir | 16 ++++++++
2 files changed, 55 insertions(+)
diff --git a/mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterfaceImpl.cpp
index aed4fbf12bd43..ca5ee62e5ffeb 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/BufferizableOpInterfaceImpl.cpp
@@ -231,6 +231,44 @@ struct PackOpInterface
return success();
}
};
+
+struct UnPackOpInterface
+ : public DstBufferizableOpInterfaceExternalModel<UnPackOpInterface,
+ linalg::UnPackOp> {
+ bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand,
+ const AnalysisState &state) const {
+ auto unPackOp = cast<linalg::UnPackOp>(op);
+ return !unPackOp.isDpsInit(&opOperand);
+ }
+
+ LogicalResult bufferize(Operation *op, RewriterBase &rewriter,
+ const BufferizationOptions &options,
+ BufferizationState &state) const {
+ auto unPackOp = cast<linalg::UnPackOp>(op);
+ assert(!unPackOp.hasPureBufferSemantics() && "expected op with tensors");
+ if (!unPackOp.hasPureTensorSemantics())
+ return unPackOp.emitError()
+ << "mixed tensor/buffer semantic op not supported yet";
+ FailureOr<Value> sourceBuffer =
+ getBuffer(rewriter, unPackOp.getSource(), options, state);
+ if (failed(sourceBuffer))
+ return failure();
+ FailureOr<Value> destBuffer =
+ getBuffer(rewriter, unPackOp.getDest(), options, state);
+ if (failed(destBuffer))
+ return failure();
+
+ SmallVector<Value> operands;
+ operands.push_back(*sourceBuffer);
+ operands.push_back(*destBuffer);
+ llvm::append_range(operands, unPackOp.getInnerTiles());
+
+ linalg::UnPackOp::create(rewriter, unPackOp.getLoc(), TypeRange{}, operands,
+ op->getAttrs());
+ replaceOpWithBufferizedValues(rewriter, op, *destBuffer);
+ return success();
+ }
+};
} // namespace
void mlir::linalg::registerBufferizableOpInterfaceExternalModels(
@@ -247,5 +285,6 @@ void mlir::linalg::registerBufferizableOpInterfaceExternalModels(
SoftmaxOp::attachInterface<SoftmaxOpInterface>(*ctx);
PackOp::attachInterface<PackOpInterface>(*ctx);
+ UnPackOp::attachInterface<UnPackOpInterface>(*ctx);
});
}
diff --git a/mlir/test/Dialect/Linalg/bufferize.mlir b/mlir/test/Dialect/Linalg/bufferize.mlir
index 6729cc4b76c4d..7b1af139f0f3e 100644
--- a/mlir/test/Dialect/Linalg/bufferize.mlir
+++ b/mlir/test/Dialect/Linalg/bufferize.mlir
@@ -226,3 +226,19 @@ func.func @bufferize_pack(%arg0: tensor<200x127x256xf32>, %arg1: tensor<256x64x2
return %0 : tensor<256x64x200x2xf32>
}
+// -----
+
+// CHECK-LABEL: func @bufferize_unpack(
+// CHECK-SAME: %[[SRC:.*]]: tensor<256x64x200x2xf32>, %[[DST:.*]]: tensor<200x128x256xf32>) -> tensor<200x128x256xf32> {
+// CHECK-DAG: %[[SRC_BUF:.*]] = bufferization.to_buffer %[[SRC]] : tensor<256x64x200x2xf32> to memref<256x64x200x2xf32>
+// CHECK-DAG: %[[DST_BUF:.*]] = memref.alloc() {{.*}} : memref<200x128x256xf32>
+// CHECK-NOT: memref.copy
+// CHECK: linalg.unpack %[[SRC_BUF]] outer_dims_perm = [2, 1, 0] inner_dims_pos = [1] inner_tiles = [2] into %[[DST_BUF]] : memref<256x64x200x2xf32> -> memref<200x128x256xf32>
+// CHECK: %[[RESULT:.*]] = bufferization.to_tensor %[[DST_BUF]] : memref<200x128x256xf32> to tensor<200x128x256xf32>
+// CHECK: return %[[RESULT]] : tensor<200x128x256xf32>
+func.func @bufferize_unpack(%arg0: tensor<256x64x200x2xf32>, %arg1: tensor<200x128x256xf32>) -> tensor<200x128x256xf32> {
+ %0 = linalg.unpack %arg0 outer_dims_perm = [2, 1, 0]
+ inner_dims_pos = [1] inner_tiles = [2] into %arg1
+ : tensor<256x64x200x2xf32> -> tensor<200x128x256xf32>
+ return %0 : tensor<200x128x256xf32>
+}
More information about the Mlir-commits
mailing list