[Mlir-commits] [mlir] [MLIR][vector] vector.deinterleave to vector.shuffle decomposition (PR #177897)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Sun Jan 25 20:55:06 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-vector

Author: Noah Prisament (nprisament)

<details>
<summary>Changes</summary>

This PR adds a rewrite pattern for vector.deinterleave ops that rewrites them using vector.shuffle ops. This is similar to the existing pattern for vector.interleave and allows for supporting these ops for lowering to targets without native deinterleave support. A transform dialect op is also added to apply this pattern.

---
Full diff: https://github.com/llvm/llvm-project/pull/177897.diff


5 Files Affected:

- (modified) mlir/include/mlir/Dialect/Vector/TransformOps/VectorTransformOps.td (+14) 
- (modified) mlir/include/mlir/Dialect/Vector/Transforms/LoweringPatterns.h (+3) 
- (modified) mlir/lib/Dialect/Vector/TransformOps/VectorTransformOps.cpp (+5) 
- (modified) mlir/lib/Dialect/Vector/Transforms/LowerVectorInterleave.cpp (+48) 
- (added) mlir/test/Dialect/Vector/vector-deinterleave-to-shuffle.mlir (+21) 


``````````diff
diff --git a/mlir/include/mlir/Dialect/Vector/TransformOps/VectorTransformOps.td b/mlir/include/mlir/Dialect/Vector/TransformOps/VectorTransformOps.td
index 03d25505dc65c..04e6e887a24e2 100644
--- a/mlir/include/mlir/Dialect/Vector/TransformOps/VectorTransformOps.td
+++ b/mlir/include/mlir/Dialect/Vector/TransformOps/VectorTransformOps.td
@@ -387,6 +387,20 @@ def ApplyInterleaveToShufflePatternsOp : Op<Transform_Dialect,
   let assemblyFormat = "attr-dict";
 }
 
+def ApplyDeinterleaveToShufflePatternsOp : Op<Transform_Dialect,
+    "apply_patterns.vector.deinterleave_to_shuffle",
+    [DeclareOpInterfaceMethods<PatternDescriptorOpInterface>]> {
+  let description = [{
+    Indicates that 1D vector deinterleave operations should be rewritten as
+    vector shuffle operations.
+
+    This is motivated by some current codegen backends not handling vector
+    deinterleave operations.
+  }];
+
+  let assemblyFormat = "attr-dict";
+}
+
 def ApplyRewriteNarrowTypePatternsOp : Op<Transform_Dialect,
     "apply_patterns.vector.rewrite_narrow_types",
     [DeclareOpInterfaceMethods<PatternDescriptorOpInterface>]> {
diff --git a/mlir/include/mlir/Dialect/Vector/Transforms/LoweringPatterns.h b/mlir/include/mlir/Dialect/Vector/Transforms/LoweringPatterns.h
index 7bd96c8a6d1a1..c0fa1afdee9b8 100644
--- a/mlir/include/mlir/Dialect/Vector/Transforms/LoweringPatterns.h
+++ b/mlir/include/mlir/Dialect/Vector/Transforms/LoweringPatterns.h
@@ -284,6 +284,9 @@ void populateVectorInterleaveLoweringPatterns(RewritePatternSet &patterns,
 void populateVectorInterleaveToShufflePatterns(RewritePatternSet &patterns,
                                                PatternBenefit benefit = 1);
 
+void populateVectorDeinterleaveToShufflePatterns(RewritePatternSet &patterns,
+                                                 PatternBenefit benefit = 1);
+
 /// Populates the pattern set with the following patterns:
 ///
 /// [UnrollBitCastOp]
diff --git a/mlir/lib/Dialect/Vector/TransformOps/VectorTransformOps.cpp b/mlir/lib/Dialect/Vector/TransformOps/VectorTransformOps.cpp
index 7faa222a9e574..2bf8c3175a986 100644
--- a/mlir/lib/Dialect/Vector/TransformOps/VectorTransformOps.cpp
+++ b/mlir/lib/Dialect/Vector/TransformOps/VectorTransformOps.cpp
@@ -195,6 +195,11 @@ void transform::ApplyInterleaveToShufflePatternsOp::populatePatterns(
   vector::populateVectorInterleaveToShufflePatterns(patterns);
 }
 
+void transform::ApplyDeinterleaveToShufflePatternsOp::populatePatterns(
+    RewritePatternSet &patterns) {
+  vector::populateVectorDeinterleaveToShufflePatterns(patterns);
+}
+
 void transform::ApplyRewriteNarrowTypePatternsOp::populatePatterns(
     RewritePatternSet &patterns) {
   populateVectorNarrowTypeRewritePatterns(patterns);
diff --git a/mlir/lib/Dialect/Vector/Transforms/LowerVectorInterleave.cpp b/mlir/lib/Dialect/Vector/Transforms/LowerVectorInterleave.cpp
index 479fc0c6a9d8c..c6324554168ec 100644
--- a/mlir/lib/Dialect/Vector/Transforms/LowerVectorInterleave.cpp
+++ b/mlir/lib/Dialect/Vector/Transforms/LowerVectorInterleave.cpp
@@ -16,6 +16,7 @@
 #include "mlir/Dialect/Vector/Utils/VectorUtils.h"
 #include "mlir/IR/BuiltinTypes.h"
 #include "mlir/IR/PatternMatch.h"
+#include "llvm/ADT/STLExtras.h"
 
 #define DEBUG_TYPE "vector-interleave-lowering"
 
@@ -147,6 +148,7 @@ class UnrollDeinterleaveOp final
 private:
   int64_t targetRank = 1;
 };
+
 /// Rewrite vector.interleave op into an equivalent vector.shuffle op, when
 /// applicable: `sourceType` must be 1D and non-scalable.
 ///
@@ -180,6 +182,47 @@ struct InterleaveToShuffle final : OpRewritePattern<vector::InterleaveOp> {
   }
 };
 
+/// Rewrite vector.deinterleave op into two equivalent vector.shuffle ops, when
+/// applicable: `sourceType` must be 1D and non-scalable.
+///
+/// Example:
+///
+/// ```mlir
+/// %evens, %odds = vector.deinterleave %arg0 : vector<4xi32> -> vector<2xi32>
+/// ```
+///
+/// Is rewritten into:
+///
+/// ```mlir
+/// %evens = vector.shuffle %arg0, %arg0 [0, 2] : vector<4xi32>, vector<4xi32>
+/// %odds = vector.shuffle %arg0, %arg0 [1, 3] : vector<4xi32>, vector<4xi32>
+/// ```
+struct DeinterleaveToShuffle final : OpRewritePattern<vector::DeinterleaveOp> {
+  using Base::Base;
+
+  LogicalResult matchAndRewrite(vector::DeinterleaveOp op,
+                                PatternRewriter &rewriter) const override {
+    VectorType sourceType = op.getSourceVectorType();
+    if (sourceType.getRank() != 1 || sourceType.isScalable()) {
+      return failure();
+    }
+
+    auto seq = llvm::seq<int64_t>(sourceType.getNumElements() / 2);
+    auto evenZip =
+        llvm::to_vector(llvm::map_range(seq, [](int64_t i) { return i * 2; }));
+    auto oddZip = llvm::to_vector(
+        llvm::map_range(evenZip, [](int64_t i) { return i + 1; }));
+
+    Value evenResult = vector::ShuffleOp::create(
+        rewriter, op.getLoc(), op.getOperand(), op.getOperand(), evenZip);
+    Value oddResult = vector::ShuffleOp::create(
+        rewriter, op.getLoc(), op.getOperand(), op.getOperand(), oddZip);
+
+    rewriter.replaceOp(op, ValueRange{evenResult, oddResult});
+    return success();
+  }
+};
+
 } // namespace
 
 void mlir::vector::populateVectorInterleaveLoweringPatterns(
@@ -192,3 +235,8 @@ void mlir::vector::populateVectorInterleaveToShufflePatterns(
     RewritePatternSet &patterns, PatternBenefit benefit) {
   patterns.add<InterleaveToShuffle>(patterns.getContext(), benefit);
 }
+
+void mlir::vector::populateVectorDeinterleaveToShufflePatterns(
+    RewritePatternSet &patterns, PatternBenefit benefit) {
+  patterns.add<DeinterleaveToShuffle>(patterns.getContext(), benefit);
+}
diff --git a/mlir/test/Dialect/Vector/vector-deinterleave-to-shuffle.mlir b/mlir/test/Dialect/Vector/vector-deinterleave-to-shuffle.mlir
new file mode 100644
index 0000000000000..d238a8fe28ae4
--- /dev/null
+++ b/mlir/test/Dialect/Vector/vector-deinterleave-to-shuffle.mlir
@@ -0,0 +1,21 @@
+// RUN: mlir-opt %s --transform-interpreter | FileCheck %s
+
+// CHECK-LABEL: @vector_deinterleave_to_shuffle
+func.func @vector_deinterleave_to_shuffle(%arg0: vector<14xi16>) -> (vector<7xi16>, vector<7xi16>) {
+  %evens, %odds = vector.deinterleave %arg0 : vector<14xi16> -> vector<7xi16>
+  return %evens, %odds : vector<7xi16>, vector<7xi16>
+}
+// CHECK: vector.shuffle %arg0, %arg0 [0, 2, 4, 6, 8, 10, 12] : vector<14xi16>, vector<14xi16>
+// CHECK: vector.shuffle %arg0, %arg0 [1, 3, 5, 7, 9, 11, 13] : vector<14xi16>, vector<14xi16>
+
+module attributes {transform.with_named_sequence} {
+  transform.named_sequence @__transform_main(%module_op: !transform.any_op {transform.readonly}) {
+    %f = transform.structured.match ops{["func.func"]} in %module_op
+      : (!transform.any_op) -> !transform.any_op
+
+    transform.apply_patterns to %f {
+      transform.apply_patterns.vector.deinterleave_to_shuffle
+    } : !transform.any_op
+    transform.yield
+  }
+}

``````````

</details>


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


More information about the Mlir-commits mailing list