[Mlir-commits] [mlir] [mlir][VectorToSCF] Decline transfer ops with no automatic allocation scope (PR #216947)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Aug 18 00:56:15 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: Alessandro Potenza (alepot55)

<details>
<summary>Changes</summary>

Fixes #<!-- -->216225.

Lowering a `vector.transfer_*` whose rank exceeds the target rank allocates a
temporary buffer with `memref.alloca`, whose verifier requires an ancestor
carrying `AutomaticAllocationScope`. The pattern never checked for one, so a
transfer op sitting directly in `builtin.module` asserts in
`getAutomaticAllocationScope` instead of being left alone:

```mlir
%c0 = arith.constant 0 : index
%cst = arith.constant dense<0.0> : vector<2x3xf32>
%m = memref.alloc() : memref<2x3xf32>
vector.transfer_write %cst, %m[%c0, %c0] : vector<2x3xf32>, memref<2x3xf32>
```

Declining is the only option: there is no legal IR the pattern could emit here.
The check goes in `checkPrepareXferOp`, which both the read and the write
conversion already call.

Verified by execution: the input above aborts on `d4e78d7f5`, the new test fails
without the patch and passes with it, and `Conversion/VectorToSCF` plus
`Dialect/Vector` stay green (107 tests).

Assisted-by: Claude (Anthropic)

AI-assisted, disclosed per the LLVM AI Tool Use Policy.


---
Full diff: https://github.com/llvm/llvm-project/pull/216947.diff


2 Files Affected:

- (modified) mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp (+6) 
- (added) mlir/test/Conversion/VectorToSCF/no-alloc-scope.mlir (+12) 


``````````diff
diff --git a/mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp b/mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp
index c9eba6962e6a4..1778fc2493c91 100644
--- a/mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp
+++ b/mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp
@@ -567,6 +567,12 @@ static LogicalResult checkPrepareXferOp(OpTy xferOp, PatternRewriter &rewriter,
       xferOp.getShapedType().getElementType())
     return rewriter.notifyMatchFailure(
         xferOp, "Mismatching source and destination element types.");
+  // The lowering allocates a temporary buffer, which `memref.alloca` only
+  // allows inside an automatic allocation scope.
+  Operation *op = xferOp.getOperation();
+  if (!op->getParentWithTrait<OpTrait::AutomaticAllocationScope>())
+    return rewriter.notifyMatchFailure(
+        xferOp, "xferOp is not inside an automatic allocation scope");
 
   return success();
 }
diff --git a/mlir/test/Conversion/VectorToSCF/no-alloc-scope.mlir b/mlir/test/Conversion/VectorToSCF/no-alloc-scope.mlir
new file mode 100644
index 0000000000000..6b817b933aa86
--- /dev/null
+++ b/mlir/test/Conversion/VectorToSCF/no-alloc-scope.mlir
@@ -0,0 +1,12 @@
+// RUN: mlir-opt %s -convert-vector-to-scf | FileCheck %s
+
+// The lowering of a transfer op whose rank exceeds the target rank allocates a
+// temporary buffer, so it needs an enclosing automatic allocation scope. These
+// ops sit directly in the implicit `builtin.module`, which is not one, so the
+// pattern has to decline instead of building an invalid `memref.alloca`.
+
+// CHECK: vector.transfer_write
+%c0 = arith.constant 0 : index
+%cst = arith.constant dense<0.0> : vector<2x3xf32>
+%m = memref.alloc() : memref<2x3xf32>
+vector.transfer_write %cst, %m[%c0, %c0] : vector<2x3xf32>, memref<2x3xf32>

``````````

</details>


https://github.com/llvm/llvm-project/pull/216947


More information about the Mlir-commits mailing list