[Mlir-commits] [mlir] 8d61e15 - [MLIR][Bufferization] Fix out-of-bounds access in setInPlaceOpOperand (#186280)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Mar 13 04:04:54 PDT 2026


Author: Mehdi Amini
Date: 2026-03-13T12:04:49+01:00
New Revision: 8d61e156753331f26b1834cf930499e5194c64ec

URL: https://github.com/llvm/llvm-project/commit/8d61e156753331f26b1834cf930499e5194c64ec
DIFF: https://github.com/llvm/llvm-project/commit/8d61e156753331f26b1834cf930499e5194c64ec.diff

LOG: [MLIR][Bufferization] Fix out-of-bounds access in setInPlaceOpOperand (#186280)

When annotating operations with bufferization markers during analysis,
setInPlaceOpOperand reads the existing __inplace_operands_attr__ and
then sets one entry. If the attribute was provided by the user with
fewer entries than the op has operands (e.g. a return with two tensor
operands but only one entry in the annotation), the function would crash
with an out-of-bounds vector access.

Fix by resizing the vector to the actual operand count before setting
the entry when the existing annotation is too short.

Fixes #128316

Assisted-by: Claude Code

Added: 
    

Modified: 
    mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp
    mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-analysis.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp b/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp
index 5dfe3e632b340..b57811868a725 100644
--- a/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp
+++ b/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp
@@ -92,6 +92,11 @@ static void setInPlaceOpOperand(OpOperand &opOperand, bool inPlace) {
   if (auto attr = op->getAttr(kInPlaceOperandsAttrName)) {
     inPlaceVector = SmallVector<StringRef>(llvm::to_vector<4>(
         cast<ArrayAttr>(attr).getAsValueRange<StringAttr>()));
+    // The existing attribute may have fewer entries than the current operand
+    // count (e.g., when user-provided annotations are inconsistent with the
+    // op's actual operand count). Resize to avoid an out-of-bounds access.
+    if (inPlaceVector.size() < op->getNumOperands())
+      inPlaceVector.resize(op->getNumOperands(), "none");
   } else {
     inPlaceVector = SmallVector<StringRef>(op->getNumOperands(), "none");
     for (OpOperand &opOperand : op->getOpOperands())

diff  --git a/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-analysis.mlir b/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-analysis.mlir
index 454c17aef4d8a..4bbe75e1fe8ac 100644
--- a/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-analysis.mlir
+++ b/mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-analysis.mlir
@@ -186,3 +186,18 @@ func.func @materialize_in_destination(%t: tensor<?xf32>, %sz: index) -> tensor<?
   %r = bufferization.materialize_in_destination %buffer in %buffer : (tensor<?xf32>, tensor<?xf32>) -> tensor<?xf32>
   return %r : tensor<?xf32>
 }
+
+// -----
+
+// Regression test for https://github.com/llvm/llvm-project/issues/128316.
+// When an op has a user-provided __inplace_operands_attr__ with fewer entries
+// than the op's operand count, setInPlaceOpOperand must not crash.
+
+// CHECK-LABEL: func @shorter_inplace_attr
+// CHECK: return
+// CHECK-SAME: __inplace_operands_attr__ = ["false", "false"]
+func.func @shorter_inplace_attr(%arg0: tensor<4xi32>) -> (tensor<4xi32>, tensor<4xi32>) {
+  // The __inplace_operands_attr__ has only one entry but the return has two
+  // tensor operands.  The analysis must expand the annotation without crashing.
+  return {__inplace_operands_attr__ = ["false"]} %arg0, %arg0 : tensor<4xi32>, tensor<4xi32>
+}


        


More information about the Mlir-commits mailing list