[Mlir-commits] [mlir] [mlir][vector][NFC] Drop 0-d guards in transfer permutation lowering (PR #200703)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sun May 31 17:38:57 PDT 2026
https://github.com/SeongjaeP created https://github.com/llvm/llvm-project/pull/200703
Four patterns registered by
`populateVectorTransferPermutationMapLoweringPatterns` (`TransferReadPermutationLowering`, `TransferWritePermutationLowering`, `TransferWriteNonPermutationLowering`, `TransferOpReduceRank`) each short-circuit with an explicit `if (op.getTransferRank() == 0)` bail-out marked `// TODO: support 0-d corner case.`. The TODOs date back to 2021 and have not been touched since.
0-d transfers are already supported elsewhere in the lowering pipeline: `TransferReadToVectorLoadLowering` / `TransferWriteToVectorStoreLowering` explicitly pass them through ("We let the 0-d corner case pass-through as it is supported."), and `--convert-vector-to-llvm` lowers `vector.transfer_read ... : memref<...>, vector<f32>` to a `llvm.load ... -> vector<1xf32>`.
The four permutation patterns are mid-level rewrites that hoist permutations, transposes, and leading broadcasts out into separate ops. A rank-0 transfer has nothing to permute, transpose, or rank-reduce, so none of these patterns can perform a meaningful rewrite on it. The downstream checks already filter the 0-d case naturally:
- `TransferReadPermutationLowering` -> `map.getNumResults() == 0`.
- `TransferWritePermutationLowering` -> `map.isMinorIdentity()` is vacuously true on a rank-0 map.
- `TransferWriteNonPermutationLowering` -> `map.isPermutationOfMinorIdentityWithBroadcasting(...)` is vacuously true on a rank-0 map.
- `TransferOpReduceRank` -> the loop over `map.getResults()` is empty, so `numLeadingBroadcast == 0`.
Drop the explicit guards and let the existing checks filter 0-d, with a short comment at each site pointing at the path. The only observable difference is the failure diagnostic (e.g. "0 result permutation map" instead of "0-d corner case not supported"), which is more specific about the actual reason the pattern does not apply.
Add a LIT test in `vector-transfer-permutation-lowering.mlir` covering 0-d `transfer_read` and `transfer_write` to lock in that the patterns remain a no-op on rank-0 transfers.
No functional change.
>From f16dc56aec456e5ffdda35a92f1c403a3c3449f0 Mon Sep 17 00:00:00 2001
From: "sjae.park" <dev at opt-ai.kr>
Date: Sun, 31 May 2026 23:45:24 +0000
Subject: [PATCH] [mlir][vector][NFC] Drop 0-d guards in transfer permutation
lowering
Four patterns registered by
`populateVectorTransferPermutationMapLoweringPatterns`
(`TransferReadPermutationLowering`, `TransferWritePermutationLowering`,
`TransferWriteNonPermutationLowering`, `TransferOpReduceRank`) each
short-circuit with an explicit `if (op.getTransferRank() == 0)`
bail-out marked `// TODO: support 0-d corner case.`. The TODOs date
back to 2021 and have not been touched since.
0-d transfers are already supported elsewhere in the lowering pipeline:
`TransferReadToVectorLoadLowering` / `TransferWriteToVectorStoreLowering`
explicitly pass them through ("We let the 0-d corner case pass-through
as it is supported."), and `--convert-vector-to-llvm` lowers
`vector.transfer_read ... : memref<...>, vector<f32>` to a
`llvm.load ... -> vector<1xf32>`.
The four permutation patterns are mid-level rewrites that hoist
permutations, transposes, and leading broadcasts out into separate ops.
A rank-0 transfer has nothing to permute, transpose, or rank-reduce,
so none of these patterns can perform a meaningful rewrite on it. The
downstream checks already filter the 0-d case naturally:
- `TransferReadPermutationLowering` -> `map.getNumResults() == 0`.
- `TransferWritePermutationLowering` -> `map.isMinorIdentity()` is
vacuously true on a rank-0 map.
- `TransferWriteNonPermutationLowering` ->
`map.isPermutationOfMinorIdentityWithBroadcasting(...)` is vacuously
true on a rank-0 map.
- `TransferOpReduceRank` -> the loop over `map.getResults()` is empty,
so `numLeadingBroadcast == 0`.
Drop the explicit guards and let the existing checks filter 0-d, with a
short comment at each site pointing at the path. The only observable
difference is the failure diagnostic (e.g. "0 result permutation map"
instead of "0-d corner case not supported"), which is more specific
about the actual reason the pattern does not apply.
Add a LIT test in `vector-transfer-permutation-lowering.mlir` covering
0-d `transfer_read` and `transfer_write` to lock in that the patterns
remain a no-op on rank-0 transfers.
No functional change.
---
.../Vector/Transforms/LowerVectorTransfer.cpp | 18 ++++--------
.../vector-transfer-permutation-lowering.mlir | 28 +++++++++++++++++++
2 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/mlir/lib/Dialect/Vector/Transforms/LowerVectorTransfer.cpp b/mlir/lib/Dialect/Vector/Transforms/LowerVectorTransfer.cpp
index 2cf8f0beaa4de..7ba9e7c2ade5c 100644
--- a/mlir/lib/Dialect/Vector/Transforms/LowerVectorTransfer.cpp
+++ b/mlir/lib/Dialect/Vector/Transforms/LowerVectorTransfer.cpp
@@ -94,15 +94,13 @@ struct TransferReadPermutationLowering
matchAndRewriteMaskableOp(vector::TransferReadOp op,
MaskingOpInterface maskOp,
PatternRewriter &rewriter) const override {
- // TODO: support 0-d corner case.
- if (op.getTransferRank() == 0)
- return rewriter.notifyMatchFailure(op, "0-d corner case not supported");
// TODO: Support transfer_read inside MaskOp case.
if (maskOp)
return rewriter.notifyMatchFailure(op, "Masked case not supported");
SmallVector<unsigned> permutation;
AffineMap map = op.getPermutationMap();
+ // 0-d transfers have a 0-result permutation map and are filtered here.
if (map.getNumResults() == 0)
return rewriter.notifyMatchFailure(op, "0 result permutation map");
if (!map.isPermutationOfMinorIdentityWithBroadcasting(permutation)) {
@@ -172,15 +170,14 @@ struct TransferWritePermutationLowering
matchAndRewriteMaskableOp(vector::TransferWriteOp op,
MaskingOpInterface maskOp,
PatternRewriter &rewriter) const override {
- // TODO: support 0-d corner case.
- if (op.getTransferRank() == 0)
- return rewriter.notifyMatchFailure(op, "0-d corner case not supported");
// TODO: Support transfer_write inside MaskOp case.
if (maskOp)
return rewriter.notifyMatchFailure(op, "Masked case not supported");
SmallVector<unsigned> permutation;
AffineMap map = op.getPermutationMap();
+ // 0-d transfers have a vacuously minor-identity permutation map and are
+ // filtered here.
if (map.isMinorIdentity())
return rewriter.notifyMatchFailure(op, "map is already minor identity");
@@ -244,15 +241,14 @@ struct TransferWriteNonPermutationLowering
matchAndRewriteMaskableOp(vector::TransferWriteOp op,
MaskingOpInterface maskOp,
PatternRewriter &rewriter) const override {
- // TODO: support 0-d corner case.
- if (op.getTransferRank() == 0)
- return rewriter.notifyMatchFailure(op, "0-d corner case not supported");
// TODO: Support transfer_write inside MaskOp case.
if (maskOp)
return rewriter.notifyMatchFailure(op, "Masked case not supported");
SmallVector<unsigned> permutation;
AffineMap map = op.getPermutationMap();
+ // 0-d transfers vacuously satisfy the minor-identity-with-broadcasting
+ // check and are filtered here.
if (map.isPermutationOfMinorIdentityWithBroadcasting(permutation)) {
return rewriter.notifyMatchFailure(
op,
@@ -323,9 +319,6 @@ struct TransferOpReduceRank
matchAndRewriteMaskableOp(vector::TransferReadOp op,
MaskingOpInterface maskOp,
PatternRewriter &rewriter) const override {
- // TODO: support 0-d corner case.
- if (op.getTransferRank() == 0)
- return rewriter.notifyMatchFailure(op, "0-d corner case not supported");
// TODO: support masked case.
if (maskOp)
return rewriter.notifyMatchFailure(op, "Masked case not supported");
@@ -338,6 +331,7 @@ struct TransferOpReduceRank
break;
numLeadingBroadcast++;
}
+ // 0-d transfers iterate the empty result list and hit this `0` check.
// If there are no leading zeros in the map there is nothing to do.
if (numLeadingBroadcast == 0)
return rewriter.notifyMatchFailure(op, "no leading broadcasts in map");
diff --git a/mlir/test/Dialect/Vector/vector-transfer-permutation-lowering.mlir b/mlir/test/Dialect/Vector/vector-transfer-permutation-lowering.mlir
index 3ae18835c8367..91a5762529a50 100644
--- a/mlir/test/Dialect/Vector/vector-transfer-permutation-lowering.mlir
+++ b/mlir/test/Dialect/Vector/vector-transfer-permutation-lowering.mlir
@@ -478,6 +478,34 @@ func.func @xfer_read_minor_identitiy_bcast_dims_masked(
return %res : vector<8x4x2x3xf32>
}
+///----------------------------------------------------------------------------------------
+/// [0-d corner case: no pattern applies]
+///
+/// 0-d transfers have a rank-0 result vector. There is no permutation,
+/// transpose, or leading broadcast to lower, so none of the patterns above
+/// should match. The downstream checks in each pattern filter these out:
+/// - TransferReadPermutationLowering: 0-result permutation map.
+/// - TransferWritePermutationLowering: vacuously minor identity.
+/// - TransferWriteNonPermutationLowering: vacuously projected permutation.
+/// - TransferOpReduceRank: no leading broadcast in an empty result map.
+///----------------------------------------------------------------------------------------
+
+// CHECK-LABEL: func @xfer_read_0d_unchanged
+// CHECK: %[[V:.+]] = vector.transfer_read %{{.*}}, %{{.*}} : memref<?x?xf32>, vector<f32>
+// CHECK: return %[[V]] : vector<f32>
+func.func @xfer_read_0d_unchanged(%mem: memref<?x?xf32>, %idx: index) -> vector<f32> {
+ %pad = arith.constant 0.0 : f32
+ %v = vector.transfer_read %mem[%idx, %idx], %pad : memref<?x?xf32>, vector<f32>
+ return %v : vector<f32>
+}
+
+// CHECK-LABEL: func @xfer_write_0d_unchanged
+// CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] : vector<f32>, memref<?x?xf32>
+func.func @xfer_write_0d_unchanged(%val: vector<f32>, %mem: memref<?x?xf32>, %idx: index) {
+ vector.transfer_write %val, %mem[%idx, %idx] : vector<f32>, memref<?x?xf32>
+ return
+}
+
///----------------------------------------------------------------------------------------
// TD sequence
///----------------------------------------------------------------------------------------
More information about the Mlir-commits
mailing list