[Mlir-commits] [mlir] ecb980e - [mlir][VectorToSCF] Decline transfer ops with no automatic allocation scope (#216947)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Aug 31 10:49:27 PDT 2026
Author: Alessandro Potenza
Date: 2026-08-31T18:49:21+01:00
New Revision: ecb980e51e37d840d098bc3b63be90474014e19d
URL: https://github.com/llvm/llvm-project/commit/ecb980e51e37d840d098bc3b63be90474014e19d
DIFF: https://github.com/llvm/llvm-project/commit/ecb980e51e37d840d098bc3b63be90474014e19d.diff
LOG: [mlir][VectorToSCF] Decline transfer ops with no automatic allocation scope (#216947)
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.
Added:
Modified:
mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp
mlir/test/Conversion/VectorToSCF/vector-to-scf.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp b/mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp
index c9eba6962e6a4..f1085e3c86b36 100644
--- a/mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp
+++ b/mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp
@@ -567,6 +567,10 @@ static LogicalResult checkPrepareXferOp(OpTy xferOp, PatternRewriter &rewriter,
xferOp.getShapedType().getElementType())
return rewriter.notifyMatchFailure(
xferOp, "Mismatching source and destination element types.");
+ 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/vector-to-scf.mlir b/mlir/test/Conversion/VectorToSCF/vector-to-scf.mlir
index 1ed82954398f0..e3a7f57e144ed 100644
--- a/mlir/test/Conversion/VectorToSCF/vector-to-scf.mlir
+++ b/mlir/test/Conversion/VectorToSCF/vector-to-scf.mlir
@@ -1,4 +1,4 @@
-// RUN: mlir-opt %s -pass-pipeline="builtin.module(func.func(convert-vector-to-scf))" -split-input-file -allow-unregistered-dialect | FileCheck %s
+// RUN: mlir-opt %s -convert-vector-to-scf -split-input-file -allow-unregistered-dialect | FileCheck %s
// RUN: mlir-opt %s -pass-pipeline="builtin.module(func.func(convert-vector-to-scf{full-unroll=true lower-scalable=true}))" -split-input-file -allow-unregistered-dialect | FileCheck %s --check-prefix=FULL-UNROLL
// RUN: mlir-opt %s "-convert-vector-to-scf=full-unroll target-rank=0" -split-input-file -allow-unregistered-dialect | FileCheck %s --check-prefix=TARGET-RANK-ZERO
@@ -908,3 +908,18 @@ func.func @negative_scalable_transpose_store_3(%vec: vector<[4]x4xf32>, %dest: m
}
// FULL-UNROLL-LABEL: @negative_scalable_transpose_store_3
// FULL-UNROLL-NOT: scf.for
+
+// -----
+
+// Negative test: lowering a transfer op whose rank exceeds the target rank
+// allocates a temporary buffer, which requires an enclosing automatic
+// allocation scope.
+
+// CHECK-LABEL: @transfer_write_no_alloc_scope
+func.func private @transfer_write_no_alloc_scope()
+// CHECK-NOT: 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>
More information about the Mlir-commits
mailing list