[Mlir-commits] [mlir] 3482aff - [mlir][vector] drop unit dim from memrefs for xfer_read/write with non-reduced mask (#187076)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Apr 29 05:01:25 PDT 2026


Author: Ege Beysel
Date: 2026-04-29T14:01:20+02:00
New Revision: 3482affb825394d396f064732de19cae54ad236f

URL: https://github.com/llvm/llvm-project/commit/3482affb825394d396f064732de19cae54ad236f
DIFF: https://github.com/llvm/llvm-project/commit/3482affb825394d396f064732de19cae54ad236f.diff

LOG: [mlir][vector] drop unit dim from memrefs for xfer_read/write with non-reduced mask (#187076)

Handles the case where the mask does not need to be trimmed, i.e. it's
already equal to the reduced vector type, for
`XferRead/WriteDropUnitDims` patterns.

Signed-off-by: Ege Beysel <beysel at roofline.ai>

Added: 
    

Modified: 
    mlir/lib/Dialect/Vector/Transforms/VectorTransferOpTransforms.cpp
    mlir/test/Dialect/Vector/vector-transfer-drop-unit-dims-patterns.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Dialect/Vector/Transforms/VectorTransferOpTransforms.cpp b/mlir/lib/Dialect/Vector/Transforms/VectorTransferOpTransforms.cpp
index ac7b84abc4e06..74b1ec98afcca 100644
--- a/mlir/lib/Dialect/Vector/Transforms/VectorTransferOpTransforms.cpp
+++ b/mlir/lib/Dialect/Vector/Transforms/VectorTransferOpTransforms.cpp
@@ -21,13 +21,16 @@
 #include "mlir/Dialect/Vector/Transforms/LoweringPatterns.h"
 #include "mlir/Dialect/Vector/Transforms/VectorTransforms.h"
 #include "mlir/Dialect/Vector/Utils/VectorUtils.h"
+#include "mlir/IR/BuiltinTypes.h"
 #include "mlir/IR/Dominance.h"
 #include "mlir/IR/Matchers.h"
 #include "mlir/IR/Operation.h"
 #include "mlir/Interfaces/SideEffectInterfaces.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
 #include "llvm/Support/DebugLog.h"
+#include "llvm/Support/LogicalResult.h"
 
 #define DEBUG_TYPE "vector-transfer-opt"
 
@@ -526,6 +529,7 @@ class TransferReadDropUnitDimsPattern
     Value maskOp = transferReadOp.getMask();
     if (maskOp) {
       LDBG() << "  -> Processing mask operation";
+      auto maskVectorType = cast<VectorType>(maskOp.getType());
       FailureOr<Value> rankReducedMaskOp = failure();
       if (auto createMaskOp = maskOp.getDefiningOp<vector::CreateMaskOp>())
         rankReducedMaskOp =
@@ -534,16 +538,19 @@ class TransferReadDropUnitDimsPattern
                    maskOp.getDefiningOp<vector::ConstantMaskOp>())
         rankReducedMaskOp =
             maskDropNonScalableUnitDims(rewriter, loc, constantMaskOp);
-
-      if (failed(rankReducedMaskOp)) {
-        LDBG() << "  -> Failed to reduce mask dimensions";
+      else
         return rewriter.notifyMatchFailure(
             transferReadOp,
             "unsupported mask op, only 'vector.create_mask' and "
             "'vector.constant_mask' are currently supported");
+
+      if (succeeded(rankReducedMaskOp)) {
+        maskOp = *rankReducedMaskOp;
+        LDBG() << "  -> Successfully reduced mask dimensions";
+      } else if (maskVectorType.getRank() != reducedVectorType.getRank()) {
+        return rewriter.notifyMatchFailure(
+            transferReadOp, "Mask reduction required, but failed");
       }
-      maskOp = *rankReducedMaskOp;
-      LDBG() << "  -> Successfully reduced mask dimensions";
     }
 
     LDBG() << "  -> Creating rank-reduced subview and new transfer_read";
@@ -642,6 +649,7 @@ class TransferWriteDropUnitDimsPattern
     Value maskOp = transferWriteOp.getMask();
     if (maskOp) {
       LDBG() << "  -> Processing mask operation";
+      auto maskVectorType = cast<VectorType>(maskOp.getType());
       FailureOr<Value> rankReducedMask = failure();
       if (auto createMaskOp = maskOp.getDefiningOp<vector::CreateMaskOp>())
         rankReducedMask =
@@ -650,16 +658,19 @@ class TransferWriteDropUnitDimsPattern
                    maskOp.getDefiningOp<vector::ConstantMaskOp>())
         rankReducedMask =
             maskDropNonScalableUnitDims(rewriter, loc, constantMaskOp);
-
-      if (failed(rankReducedMask)) {
-        LDBG() << "  -> Failed to reduce mask dimensions";
+      else
         return rewriter.notifyMatchFailure(
             transferWriteOp,
             "unsupported mask op, only 'vector.create_mask' and "
             "'vector.constant_mask' are currently supported");
+
+      if (succeeded(rankReducedMask)) {
+        maskOp = *rankReducedMask;
+        LDBG() << "  -> Successfully reduced mask dimensions";
+      } else if (maskVectorType.getRank() != reducedVectorType.getRank()) {
+        return rewriter.notifyMatchFailure(
+            transferWriteOp, "Mask reduction required, but failed");
       }
-      maskOp = *rankReducedMask;
-      LDBG() << "  -> Successfully reduced mask dimensions";
     }
     LDBG() << "  -> Creating rank-reduced subview and new transfer_write";
     Value reducedShapeSource =

diff  --git a/mlir/test/Dialect/Vector/vector-transfer-drop-unit-dims-patterns.mlir b/mlir/test/Dialect/Vector/vector-transfer-drop-unit-dims-patterns.mlir
index d30ba64c09159..e6c9fc297215c 100644
--- a/mlir/test/Dialect/Vector/vector-transfer-drop-unit-dims-patterns.mlir
+++ b/mlir/test/Dialect/Vector/vector-transfer-drop-unit-dims-patterns.mlir
@@ -176,7 +176,7 @@ func.func @transfer_read_dynamic_rank_reducing(
 //       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG]][0, 0] [%[[DIM0]], 1] [1, 1] : memref<?x1xi8, {{.*}}> to memref<?xi8, {{.*}}>
 //       CHECK:   vector.transfer_read %[[SUBVIEW]]{{.*}} : memref<?xi8, {{.*}}>, vector<[16]xi8>
 
-func.func @masked_transfer_read_dynamic_rank_reducing_1_create_mask(
+func.func @transfer_read_with_mask_dynamic_rank_reducing_1_create_mask(
       %arg : memref<?x1xi8, strided<[?, ?], offset: ?>>,
       %mask_dim0 : index) -> vector<[16]x1xi8> {
     %c0 = arith.constant 0 : index
@@ -187,7 +187,7 @@ func.func @masked_transfer_read_dynamic_rank_reducing_1_create_mask(
       memref<?x1xi8, strided<[?, ?], offset: ?>>, vector<[16]x1xi8>
     return %v : vector<[16]x1xi8>
 }
-// CHECK-LABEL: func @masked_transfer_read_dynamic_rank_reducing_1_create_mask
+// CHECK-LABEL: func @transfer_read_with_mask_dynamic_rank_reducing_1_create_mask
 //  CHECK-SAME:     %[[ARG:.+]]: memref<?x1xi8
 //  CHECK-SAME:     %[[MASK_DIM0:.+]]: index
 //       CHECK:   %[[C0:.+]] = arith.constant 0 : index
@@ -197,7 +197,7 @@ func.func @masked_transfer_read_dynamic_rank_reducing_1_create_mask(
 //       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG]][0, 0] [%[[DIM0]], 1] [1, 1] : memref<?x1xi8, {{.*}}> to memref<?xi8, {{.*}}>
 //       CHECK:   vector.transfer_read %[[SUBVIEW]][{{.*}}], %[[PAD]], %[[MASK]] {in_bounds = [true]} : memref<?xi8, {{.*}}>, vector<[16]xi8>
 
-func.func @masked_transfer_read_dynamic_rank_reducing_1_constant_mask(
+func.func @transfer_read_with_mask_dynamic_rank_reducing_1_constant_mask(
       %arg : memref<?x1xi8, strided<[?, ?], offset: ?>>) -> vector<[16]x1xi8> {
     %c0 = arith.constant 0 : index
     %pad = arith.constant 0 : i8
@@ -206,13 +206,13 @@ func.func @masked_transfer_read_dynamic_rank_reducing_1_constant_mask(
       memref<?x1xi8, strided<[?, ?], offset: ?>>, vector<[16]x1xi8>
     return %v : vector<[16]x1xi8>
 }
-// CHECK-LABEL: func @masked_transfer_read_dynamic_rank_reducing_1_constant_mask
+// CHECK-LABEL: func @transfer_read_with_mask_dynamic_rank_reducing_1_constant_mask
 //  CHECK-SAME:     %[[ARG:.+]]: memref<?x1xi8
 //   CHECK-NOT:   vector.constant_mask
 //       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG]][0, 0] [{{.*}}, 1] [1, 1] : memref<?x1xi8, {{.*}}> to memref<?xi8, {{.*}}>
 //       CHECK:   vector.transfer_read %[[SUBVIEW]]{{.*}} {in_bounds = [true]} : memref<?xi8, {{.*}}>, vector<[16]xi8>
 
-func.func @masked_transfer_read_dynamic_rank_reducing_2_create_mask(
+func.func @transfer_read_with_mask_dynamic_rank_reducing_2_create_mask(
       %arg : memref<1x?x3x1x?x1xi8, strided<[?, ?, ?, ?, ?, ?], offset: ?>>,
       %mask_dim1 : index, %mask_dim4 : index) -> vector<1x[1]x3x1x[16]x1xi8> {
     %c0 = arith.constant 0 : index
@@ -224,7 +224,7 @@ func.func @masked_transfer_read_dynamic_rank_reducing_2_create_mask(
       memref<1x?x3x1x?x1xi8, strided<[?, ?, ?, ?, ?, ?], offset: ?>>, vector<1x[1]x3x1x[16]x1xi8>
     return %v : vector<1x[1]x3x1x[16]x1xi8>
 }
-// CHECK-LABEL: func @masked_transfer_read_dynamic_rank_reducing_2_create_mask
+// CHECK-LABEL: func @transfer_read_with_mask_dynamic_rank_reducing_2_create_mask
 //  CHECK-SAME:     %[[ARG:.+]]: memref<1x?x3x1x?x1xi8
 //  CHECK-SAME:     %[[MASK_DIM1:.+]]: index, %[[MASK_DIM4:.+]]: index
 //   CHECK-DAG:   %[[C0:.+]] = arith.constant 0 : index
@@ -238,7 +238,7 @@ func.func @masked_transfer_read_dynamic_rank_reducing_2_create_mask(
 //       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG]][0, 0, 0, 0, 0, 0] [1, %[[DIM1]], 3, 1, %[[DIM4]], 1] [1, 1, 1, 1, 1, 1] : memref<1x?x3x1x?x1xi8, {{.*}}> to memref<?x3x?xi8, {{.*}}>
 //       CHECK:   vector.transfer_read %[[SUBVIEW]][{{.*}}], %[[PAD]], %[[MASK]] {in_bounds = [true, true, true]} : memref<?x3x?xi8, {{.*}}>, vector<[1]x3x[16]xi8>
 
-func.func @masked_transfer_read_dynamic_rank_reducing_2_constant_mask(
+func.func @transfer_read_with_mask_dynamic_rank_reducing_2_constant_mask(
       %arg : memref<1x?x3x1x?x1xi8, strided<[?, ?, ?, ?, ?, ?], offset: ?>>) -> vector<1x[1]x3x1x[16]x1xi8> {
     %c0 = arith.constant 0 : index
     %pad = arith.constant 0 : i8
@@ -247,7 +247,7 @@ func.func @masked_transfer_read_dynamic_rank_reducing_2_constant_mask(
       memref<1x?x3x1x?x1xi8, strided<[?, ?, ?, ?, ?, ?], offset: ?>>, vector<1x[1]x3x1x[16]x1xi8>
     return %v : vector<1x[1]x3x1x[16]x1xi8>
 }
-// CHECK-LABEL: func @masked_transfer_read_dynamic_rank_reducing_2_constant_mask
+// CHECK-LABEL: func @transfer_read_with_mask_dynamic_rank_reducing_2_constant_mask
 //  CHECK-SAME:     %[[ARG:.+]]: memref<1x?x3x1x?x1xi8
 //   CHECK-DAG:   %[[C0:.+]] = arith.constant 0 : index
 //   CHECK-DAG:   %[[C1:.+]] = arith.constant 1 : index
@@ -259,7 +259,7 @@ func.func @masked_transfer_read_dynamic_rank_reducing_2_constant_mask(
 //       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG]][0, 0, 0, 0, 0, 0] [1, %[[DIM1]], 3, 1, %[[DIM4]], 1] [1, 1, 1, 1, 1, 1] : memref<1x?x3x1x?x1xi8, {{.*}}> to memref<?x3x?xi8, {{.*}}>
 //       CHECK:   vector.transfer_read %[[SUBVIEW]][{{.*}}], %[[PAD]], %[[MASK]] {in_bounds = [true, true, true]} : memref<?x3x?xi8, {{.*}}>, vector<[1]x3x[16]xi8>
 
-func.func @masked_transfer_write_and_vector_rank_reducing_create_mask(
+func.func @transfer_write_with_mask_and_vector_rank_reducing_create_mask(
       %arg : memref<1x1x3x1x16x1xf32>,
       %vec : vector<1x3x1x16x1xf32>,
       %mask_dim1 : index,
@@ -271,7 +271,7 @@ func.func @masked_transfer_write_and_vector_rank_reducing_create_mask(
       vector<1x3x1x16x1xf32>, memref<1x1x3x1x16x1xf32>
     return
 }
-// CHECK-LABEL: func @masked_transfer_write_and_vector_rank_reducing_create_mask
+// CHECK-LABEL: func @transfer_write_with_mask_and_vector_rank_reducing_create_mask
 //  CHECK-SAME:     %[[ARG:.+]]: memref<1x1x3x1x16x1xf32>
 //  CHECK-SAME:     {{.*}}: vector<1x3x1x16x1xf32>,
 //  CHECK-SAME:     %[[MASKDIM1:.+]]: index,
@@ -281,7 +281,7 @@ func.func @masked_transfer_write_and_vector_rank_reducing_create_mask(
 //  CHECK-SAME:     memref<1x1x3x1x16x1xf32> to memref<3x16xf32>
 //       CHECK:   vector.transfer_write %{{.*}}, %[[SUBVIEW]]{{.*}}, %[[MASK]] {in_bounds = [true, true]} : vector<3x16xf32>, memref<3x16xf32>
 
-func.func @masked_transfer_write_and_vector_rank_reducing_constant_mask(
+func.func @transfer_write_with_mask_and_vector_rank_reducing_constant_mask(
       %arg : memref<1x1x3x1x16x1xf32>,
       %vec : vector<1x3x1x16x1xf32>) {
     %c0 = arith.constant 0 : index
@@ -290,14 +290,14 @@ func.func @masked_transfer_write_and_vector_rank_reducing_constant_mask(
       vector<1x3x1x16x1xf32>, memref<1x1x3x1x16x1xf32>
     return
 }
-// CHECK-LABEL: func @masked_transfer_write_and_vector_rank_reducing_constant_mask
+// CHECK-LABEL: func @transfer_write_with_mask_and_vector_rank_reducing_constant_mask
 //  CHECK-SAME:     %[[ARG:.+]]: memref<1x1x3x1x16x1xf32>
 //       CHECK:   %[[MASK:.+]] = vector.constant_mask [2, 8] : vector<3x16xi1>
 //       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG]][0, 0, 0, 0, 0, 0] [1, 1, 3, 1, 16, 1] [1, 1, 1, 1, 1, 1]
 //  CHECK-SAME:     memref<1x1x3x1x16x1xf32> to memref<3x16xf32>
 //       CHECK:   vector.transfer_write %{{.*}}, %[[SUBVIEW]]{{.*}}, %[[MASK]] {in_bounds = [true, true]} : vector<3x16xf32>, memref<3x16xf32>
 
-func.func @masked_transfer_write_dynamic_rank_reducing_create_mask(
+func.func @transfer_write_with_mask_dynamic_rank_reducing_create_mask(
       %arg : memref<?x1xi8, strided<[?, ?], offset: ?>>,
       %vec : vector<[16]x1xi8>,
       %mask_dim0 : index) {
@@ -309,7 +309,7 @@ func.func @masked_transfer_write_dynamic_rank_reducing_create_mask(
       vector<[16]x1xi8>, memref<?x1xi8, strided<[?, ?], offset: ?>>
     return
 }
-// CHECK-LABEL: func @masked_transfer_write_dynamic_rank_reducing_create_mask
+// CHECK-LABEL: func @transfer_write_with_mask_dynamic_rank_reducing_create_mask
 //  CHECK-SAME:     %[[ARG:.+]]: memref<?x1xi8
 //  CHECK-SAME:     %{{.*}}: vector<[16]x1xi8>,
 //  CHECK-SAME:     %[[MASK_DIM0:.+]]: index
@@ -319,7 +319,7 @@ func.func @masked_transfer_write_dynamic_rank_reducing_create_mask(
 //       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG]][0, 0] [%[[DIM0]], 1] [1, 1] : memref<?x1xi8, {{.*}}> to memref<?xi8, {{.*}}>
 //       CHECK:   vector.transfer_write {{.*}}, %[[SUBVIEW]][%[[C0]]], %[[MASK]] {in_bounds = [true]} : vector<[16]xi8>, memref<?xi8, {{.*}}>
 
-func.func @masked_transfer_write_dynamic_rank_reducing_constant_mask(
+func.func @transfer_write_with_mask_dynamic_rank_reducing_constant_mask(
       %arg : memref<?x1xi8, strided<[?, ?], offset: ?>>,
       %vec : vector<[16]x1xi8>) {
     %c0 = arith.constant 0 : index
@@ -328,14 +328,14 @@ func.func @masked_transfer_write_dynamic_rank_reducing_constant_mask(
       vector<[16]x1xi8>, memref<?x1xi8, strided<[?, ?], offset: ?>>
     return
 }
-// CHECK-LABEL: func @masked_transfer_write_dynamic_rank_reducing_constant_mask
+// CHECK-LABEL: func @transfer_write_with_mask_dynamic_rank_reducing_constant_mask
 //  CHECK-SAME:     %[[ARG:.+]]: memref<?x1xi8
 //   CHECK-NOT:   vector.constant_mask
 //       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG]][0, 0] [{{.*}}, 1] [1, 1] : memref<?x1xi8, {{.*}}> to memref<?xi8, {{.*}}>
 //       CHECK:   vector.transfer_write {{.*}}, %[[SUBVIEW]]{{.*}} {in_bounds = [true]} : vector<[16]xi8>, memref<?xi8, {{.*}}>
 
 /// Only vector.create_mask and vector.constant_mask masks are supported.
-func.func @unsupported_masked_transfer_read_dynamic_rank_reducing_1(
+func.func @transfer_read_with_unsupported_mask_dynamic_rank_reducing_1(
       %arg : memref<?x1xi8, strided<[?, ?], offset: ?>>,
       %mask : vector<[16]x1xi1>) -> vector<[16]x1xi8> {
     %c0 = arith.constant 0 : index
@@ -344,14 +344,14 @@ func.func @unsupported_masked_transfer_read_dynamic_rank_reducing_1(
       memref<?x1xi8, strided<[?, ?], offset: ?>>, vector<[16]x1xi8>
     return %v : vector<[16]x1xi8>
 }
-// CHECK-LABEL: func @unsupported_masked_transfer_read_dynamic_rank_reducing_1
+// CHECK-LABEL: func @transfer_read_with_unsupported_mask_dynamic_rank_reducing_1
 //  CHECK-SAME:     %[[ARG:.+]]: memref<?x1xi8
 //   CHECK-NOT: vector.create_mask
 //   CHECK-NOT: memref.subview
 //       CHECK: vector.transfer_read %[[ARG]]
 
 /// Unit dim mask must be constant of 1.
-func.func @unsupported_masked_transfer_read_dynamic_rank_reducing_2(
+func.func @transfer_read_with_unsupported_mask_dynamic_rank_reducing_2(
       %arg : memref<?x1xi8, strided<[?, ?], offset: ?>>,
       %mask_dim0 : index, %mask_dim1 : index) -> vector<[16]x1xi8> {
     %c0 = arith.constant 0 : index
@@ -362,13 +362,13 @@ func.func @unsupported_masked_transfer_read_dynamic_rank_reducing_2(
       memref<?x1xi8, strided<[?, ?], offset: ?>>, vector<[16]x1xi8>
     return %v : vector<[16]x1xi8>
 }
-// CHECK-LABEL: func @unsupported_masked_transfer_read_dynamic_rank_reducing_2
+// CHECK-LABEL: func @transfer_read_with_unsupported_mask_dynamic_rank_reducing_2
 //  CHECK-SAME:     %[[ARG:.+]]: memref<?x1xi8
 //   CHECK-NOT: memref.subview
 //       CHECK: vector.transfer_read {{.*}} vector<[16]x1xi8>
 
 /// Unit dim must be non-scalable.
-func.func @masked_transfer_read_dynamic_rank_reducing_scalable_unit_dim(
+func.func @transfer_read_with_mask_dynamic_rank_reducing_scalable_unit_dim(
       %arg : memref<?x1xi8, strided<[?, ?], offset: ?>>,
       %mask_dim0 : index) -> vector<[16]x[1]xi8> {
     %c0 = arith.constant 0 : index
@@ -379,11 +379,51 @@ func.func @masked_transfer_read_dynamic_rank_reducing_scalable_unit_dim(
       memref<?x1xi8, strided<[?, ?], offset: ?>>, vector<[16]x[1]xi8>
     return %v : vector<[16]x[1]xi8>
 }
-// CHECK-LABEL: func @masked_transfer_read_dynamic_rank_reducing_scalable_unit_dim
+// CHECK-LABEL: func @transfer_read_with_mask_dynamic_rank_reducing_scalable_unit_dim
 //  CHECK-SAME:     %[[ARG:.+]]: memref<?x1xi8
 //   CHECK-NOT: memref.subview
 //       CHECK: vector.transfer_read {{.*}} vector<[16]x[1]xi8>
 
+/// Memref has unit dims but vector has no unit dims (all scalable). The mask
+/// does not need reduction — only the memref rank should be reduced.
+func.func @transfer_read_with_mask_memref_only_unit_dims(
+      %arg : memref<1x1x?x?xf32, strided<[?, ?, ?, ?], offset: ?>>,
+      %mask_dim0 : index, %mask_dim1 : index) -> vector<[4]x[4]xf32> {
+    %c0 = arith.constant 0 : index
+    %pad = arith.constant 0.0 : f32
+    %mask = vector.create_mask %mask_dim0, %mask_dim1 : vector<[4]x[4]xi1>
+    %v = vector.transfer_read %arg[%c0, %c0, %c0, %c0], %pad, %mask {in_bounds = [true, true]} :
+      memref<1x1x?x?xf32, strided<[?, ?, ?, ?], offset: ?>>, vector<[4]x[4]xf32>
+    return %v : vector<[4]x[4]xf32>
+}
+// CHECK-LABEL: func @transfer_read_with_mask_memref_only_unit_dims
+//  CHECK-SAME:     %[[ARG:.+]]: memref<1x1x?x?xf32
+//       CHECK:   %[[MASK:.+]] = vector.create_mask {{.*}} : vector<[4]x[4]xi1>
+//       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG]][0, 0, 0, 0]
+//  CHECK-SAME:     memref<1x1x?x?xf32, {{.*}}> to memref<?x?xf32, {{.*}}>
+//       CHECK:   vector.transfer_read %[[SUBVIEW]]{{.*}}, %[[MASK]]
+//  CHECK-SAME:     memref<?x?xf32, {{.*}}>, vector<[4]x[4]xf32>
+
+func.func @transfer_write_with_mask_memref_only_unit_dims(
+      %arg : memref<1x1x?x?xf32, strided<[?, ?, ?, ?], offset: ?>>,
+      %vec : vector<[4]x[4]xf32>,
+      %mask_dim0 : index, %mask_dim1 : index) {
+    %c0 = arith.constant 0 : index
+    %mask = vector.create_mask %mask_dim0, %mask_dim1 : vector<[4]x[4]xi1>
+    vector.transfer_write %vec, %arg[%c0, %c0, %c0, %c0], %mask {in_bounds = [true, true]} :
+      vector<[4]x[4]xf32>, memref<1x1x?x?xf32, strided<[?, ?, ?, ?], offset: ?>>
+    return
+}
+// CHECK-LABEL: func @transfer_write_with_mask_memref_only_unit_dims
+//  CHECK-SAME:     %[[ARG:.+]]: memref<1x1x?x?xf32
+//  CHECK-SAME:     %[[VEC:.+]]: vector<[4]x[4]xf32>
+//       CHECK:   %[[MASK:.+]] = vector.create_mask {{.*}} : vector<[4]x[4]xi1>
+//       CHECK:   %[[SUBVIEW:.+]] = memref.subview %[[ARG]][0, 0, 0, 0]
+//  CHECK-SAME:     memref<1x1x?x?xf32, {{.*}}> to memref<?x?xf32, {{.*}}>
+//       CHECK:   vector.transfer_write %[[VEC]], %[[SUBVIEW]]{{.*}}, %[[MASK]]
+//  CHECK-SAME:     vector<[4]x[4]xf32>, memref<?x?xf32, {{.*}}>
+
+
 module attributes {transform.with_named_sequence} {
   transform.named_sequence @__transform_main(%root : !transform.any_op {transform.readonly}) {
     %func_op = transform.structured.match ops{["func.func"]} in %root : (!transform.any_op) -> !transform.op<"func.func">


        


More information about the Mlir-commits mailing list