[Mlir-commits] [mlir] [mlir][vector] Support fixed-size masks in `eliminateVectorMasks` (PR #221595)

Dhairyashil R G llvmlistbot at llvm.org
Mon Sep 21 07:12:31 PDT 2026


================
@@ -164,8 +251,45 @@ func.func @negative_value_bounds_scalable_dim_not_all_true(%tensor: tensor<2x100
   %c3_vscale = arith.muli %vscale, %c3 : index
   %slice = tensor.extract_slice %tensor[0, 0] [2, %c3_vscale] [1, 1] : tensor<2x100xf32> to tensor<2x?xf32>
   // Another simple example, but value bounds will be used to resolve the tensor.dim.
+  // There is no fixed-size equivalent: the dimension under test is scalable.
   %dim = tensor.dim %slice, %c1 : tensor<2x?xf32>
   %mask = vector.create_mask %c3, %dim : vector<3x[4]xi1>
   "test.some_use"(%mask) : (vector<3x[4]xi1>) -> ()
   return
 }
+
+// -----
+
+// Nothing bounds %n from below, so no bound is found at all.
+
+// CHECK-LABEL: @negative_unbounded_operand_fixed_size
+// CHECK-NOT: vector.constant_mask
+// CHECK: %[[MASK:.*]] = vector.create_mask
+// CHECK: "test.some_use"(%[[MASK]]) : (vector<4xi1>) -> ()
+func.func @negative_unbounded_operand_fixed_size(%n: index) {
+  %mask = vector.create_mask %n : vector<4xi1>
+  "test.some_use"(%mask) : (vector<4xi1>) -> ()
+  return
+}
+
+// -----
+
+// A mask dimension that is only provably all-true once a vscale range is known.
+// `max(%n, 4 * vscale) >= 4 * vscale`, which is exactly the runtime size of
+// `vector<[4]xi1>`.
+
+// CHECK-LABEL: @scalable_dim_requires_vscale_range
+//  WITH-RANGE: %[[ALL_TRUE_MASK:.*]] = vector.constant_mask [4] : vector<[4]xi1>
+//  WITH-RANGE: "test.some_use"(%[[ALL_TRUE_MASK]]) : (vector<[4]xi1>) -> ()
+//  NO-RANGE-NOT: vector.constant_mask
+//  NO-RANGE: %[[MASK:.*]] = vector.create_mask
+//  NO-RANGE: "test.some_use"(%[[MASK]]) : (vector<[4]xi1>) -> ()
+func.func @scalable_dim_requires_vscale_range(%n: index) {
+  %c4 = arith.constant 4 : index
+  %vscale = vector.vscale
+  %c4_vscale = arith.muli %vscale, %c4 : index
+  %m = arith.maxsi %n, %c4_vscale : index
+  %mask = vector.create_mask %m : vector<[4]xi1>
+  "test.some_use"(%mask) : (vector<[4]xi1>) -> ()
+  return
+}
----------------
dhairyashilRG wrote:

You're right that it doesn't test a new path. Looking into why, it turned out not to test the guard either: if I delete the scalable-dimension bail on the fixed-width path, this test still passes. The bound was `max(%n, 4 * vscale)`, which the constant-bound path declines anyway, so the bail never decided anything.

`max(%n, 4)` does test it. Without the guard the mask is folded to `vector.constant_mask [4] : vector<[4]xi1>`, which is wrong for every `vscale > 1`; with it, the mask stays. I've changed the test to that and renamed it `@negative_scalable_dim_constant_lower_bound`. Both runs behave the same now, so it uses the shared prefix.


https://github.com/llvm/llvm-project/pull/221595


More information about the Mlir-commits mailing list