[Mlir-commits] [mlir] [mlir][Vector] Reject scalable masks in maskedload/maskedstore emulation (PR #223316)

Cheng-Chieh Liu llvmlistbot at llvm.org
Mon Sep 14 00:14:56 PDT 2026


https://github.com/jay87406 created https://github.com/llvm/llvm-project/pull/223316

`VectorMaskedLoadOpConverter` and `VectorMaskedStoreOpConverter` unroll into a fixed number of `scf.if` blocks based on `maskVType.getShape()[0]`. For a scalable mask like `vector<[4]xi1>` that's only the static minimum, not the actual (`vscale`-scaled) element count, so lanes past the fixed 4 iterations were silently dropped whenever `vscale > 1`.

Reject scalable masks the same way the existing rank check does, and add `lit` coverage for both ops.

>From 7609107c3520685082bf1b3400a8928871615785 Mon Sep 17 00:00:00 2001
From: Cheng-Chieh Liu <jay87406 at gmail.com>
Date: Mon, 14 Sep 2026 01:48:04 -0500
Subject: [PATCH] [mlir][Vector] Reject scalable masks in
 maskedload/maskedstore emulation

VectorMaskedLoadOpConverter and VectorMaskedStoreOpConverter unroll
into a fixed number of scf.if blocks based on maskVType.getShape()[0].
For a scalable mask like vector<[4]xi1> that's only the static
minimum, not the actual (vscale-scaled) element count, so lanes past
the fixed 4 iterations were silently dropped whenever vscale > 1.

Reject scalable masks the same way the existing rank check does, and
add lit coverage for both ops.
---
 .../VectorEmulateMaskedLoadStore.cpp          |  6 ++++++
 .../vector-emulate-masked-load-store.mlir     | 19 +++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/mlir/lib/Dialect/Vector/Transforms/VectorEmulateMaskedLoadStore.cpp b/mlir/lib/Dialect/Vector/Transforms/VectorEmulateMaskedLoadStore.cpp
index 3ca08f3099bd3..53df3d3c48c6a 100644
--- a/mlir/lib/Dialect/Vector/Transforms/VectorEmulateMaskedLoadStore.cpp
+++ b/mlir/lib/Dialect/Vector/Transforms/VectorEmulateMaskedLoadStore.cpp
@@ -56,6 +56,9 @@ struct VectorMaskedLoadOpConverter final
     if (maskVType.getShape().size() != 1)
       return rewriter.notifyMatchFailure(
           maskedLoadOp, "expected vector.maskedstore with 1-D mask");
+    if (maskVType.isScalable())
+      return rewriter.notifyMatchFailure(
+          maskedLoadOp, "cannot unroll a scalable mask");
 
     Location loc = maskedLoadOp.getLoc();
     int64_t maskLength = maskVType.getShape()[0];
@@ -125,6 +128,9 @@ struct VectorMaskedStoreOpConverter final
     if (maskVType.getShape().size() != 1)
       return rewriter.notifyMatchFailure(
           maskedStoreOp, "expected vector.maskedstore with 1-D mask");
+    if (maskVType.isScalable())
+      return rewriter.notifyMatchFailure(
+          maskedStoreOp, "cannot unroll a scalable mask");
 
     Location loc = maskedStoreOp.getLoc();
     int64_t maskLength = maskVType.getShape()[0];
diff --git a/mlir/test/Dialect/Vector/vector-emulate-masked-load-store.mlir b/mlir/test/Dialect/Vector/vector-emulate-masked-load-store.mlir
index 7c492781c8c55..76646a21c899b 100644
--- a/mlir/test/Dialect/Vector/vector-emulate-masked-load-store.mlir
+++ b/mlir/test/Dialect/Vector/vector-emulate-masked-load-store.mlir
@@ -145,3 +145,22 @@ func.func @vector_maskedstore_rank0(%arg0: memref<f32>, %arg3: vector<1xi1>, %ar
   vector.maskedstore %arg0[], %arg3, %arg4 : memref<f32>, vector<1xi1>, vector<1xf32>
   return
 }
+
+// A scalable mask cannot be unrolled at compile time, so these must not be
+// converted.
+
+// CHECK-LABEL:  @vector_maskedload_scalable
+//       CHECK:  vector.maskedload
+func.func @vector_maskedload_scalable(%arg0: memref<?xf32>, %mask: vector<[4]xi1>, %pass_thru: vector<[4]xf32>) -> vector<[4]xf32> {
+  %idx_0 = arith.constant 0 : index
+  %0 = vector.maskedload %arg0[%idx_0], %mask, %pass_thru : memref<?xf32>, vector<[4]xi1>, vector<[4]xf32> into vector<[4]xf32>
+  return %0 : vector<[4]xf32>
+}
+
+// CHECK-LABEL:  @vector_maskedstore_scalable
+//       CHECK:  vector.maskedstore
+func.func @vector_maskedstore_scalable(%arg0: memref<?xf32>, %mask: vector<[4]xi1>, %value: vector<[4]xf32>) {
+  %idx_0 = arith.constant 0 : index
+  vector.maskedstore %arg0[%idx_0], %mask, %value : memref<?xf32>, vector<[4]xi1>, vector<[4]xf32>
+  return
+}



More information about the Mlir-commits mailing list