[Mlir-commits] [mlir] [MLIR][Vector] Fix crash in operatesOnSuperVectorsOf on rank-mismatched shaped (PR #183967)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sat Feb 28 15:23:13 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Mehdi Amini (joker-eph)
<details>
<summary>Changes</summary>
The `operatesOnSuperVectorsOf` function in VectorUtils.cpp contained an assertion that fired when a `vector.transfer` operation's vector type had a different rank (or non-divisible shape) from the sub-vector type supplied by the caller:
assert((ratio || \!mustDivide) &&
"vector.transfer operation in which super-vector size is not an"
" integer multiple of sub-vector size");
This assertion was incorrect because the function's callers (e.g., the affine super-vectorizer) legitimately pass transfer ops whose vector type doesn't match the requested sub-vector shape. In those cases the correct answer is simply that the op does not operate on a super-vector of that sub-vector type, so `operatesOnSuperVectorsOf` should return `false`.
Remove the assert return `false` when `computeShapeRatio` produces no result, and remove the now-unused `mustDivide` variable.
Fixes #<!-- -->149327
---
Full diff: https://github.com/llvm/llvm-project/pull/183967.diff
2 Files Affected:
- (modified) mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp (+3-15)
- (modified) mlir/test/Dialect/Affine/SuperVectorize/vector_utils.mlir (+17)
``````````diff
diff --git a/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp b/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp
index e123f9e21bbeb..d1ce0fad2fb56 100644
--- a/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp
+++ b/mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp
@@ -209,12 +209,9 @@ bool matcher::operatesOnSuperVectorsOf(Operation &op,
// explicitly checked for this property.
/// TODO: there should be a single function for all ops to do this so we
/// do not have to special case. Maybe a trait, or just a method, unclear atm.
- bool mustDivide = false;
- (void)mustDivide;
VectorType superVectorType;
if (auto transfer = dyn_cast<VectorTransferOpInterface>(op)) {
superVectorType = transfer.getVectorType();
- mustDivide = true;
} else if (op.getNumResults() == 0) {
if (!isa<func::ReturnOp>(op)) {
op.emitError("NYI: assuming only return operations can have 0 "
@@ -235,20 +232,11 @@ bool matcher::operatesOnSuperVectorsOf(Operation &op,
return false;
}
- // Get the ratio.
+ // Get the ratio. If the shapes are incompatible (e.g., different ranks or
+ // non-integer divisibility), the operation does not operate on a super-vector
+ // of the given sub-vector type.
auto ratio =
computeShapeRatio(superVectorType.getShape(), subVectorType.getShape());
-
- // Sanity check.
- assert((ratio || !mustDivide) &&
- "vector.transfer operation in which super-vector size is not an"
- " integer multiple of sub-vector size");
-
- // This catches cases that are not strictly necessary to have multiplicity but
- // still aren't divisible by the sub-vector shape.
- // This could be useful information if we wanted to reshape at the level of
- // the vector type (but we would have to look at the compute and distinguish
- // between parallel, reduction and possibly other cases.
return ratio.has_value();
}
diff --git a/mlir/test/Dialect/Affine/SuperVectorize/vector_utils.mlir b/mlir/test/Dialect/Affine/SuperVectorize/vector_utils.mlir
index bd71164244c00..fcf31daa987b4 100644
--- a/mlir/test/Dialect/Affine/SuperVectorize/vector_utils.mlir
+++ b/mlir/test/Dialect/Affine/SuperVectorize/vector_utils.mlir
@@ -52,6 +52,23 @@ func.func @double_loop_nest(%a: memref<20x30xf32>, %b: memref<20xf32>) {
return
}
+// Regression test for https://github.com/llvm/llvm-project/issues/149327
+// Verifies no crash when a vector.transfer_read has a 1D vector type but the
+// shape ratio is 2D, causing a rank mismatch in operatesOnSuperVectorsOf.
+// The transfer op should simply not be matched (not crash).
+// CHECK-LABEL: func @transfer_rank_mismatch_no_crash
+func.func @transfer_rank_mismatch_no_crash(%arg0: memref<82x97xf32>) {
+ %0 = ub.poison : f32
+ affine.for %arg1 = 0 to 82 {
+ affine.for %arg2 = 0 to 97 step 128 {
+ // The vector type is 1D but the shape ratio is 2D — no crash.
+ // CHECK-NOT: matched: {{.*}} = vector.transfer_read
+ %1 = vector.transfer_read %arg0[%arg1, %arg2], %0 : memref<82x97xf32>, vector<128xf32>
+ }
+ }
+ return
+}
+
// VECNEST: affine.for %{{.*}} = 0 to 20 step 4 {
// VECNEST: vector.transfer_read
// VECNEST-NEXT: affine.for %{{.*}} = 0 to 30 {
``````````
</details>
https://github.com/llvm/llvm-project/pull/183967
More information about the Mlir-commits
mailing list