[Mlir-commits] [mlir] [MLIR][XeVM] Update HandleVectorExtractPattern (PR #186247)

Sang Ik Lee llvmlistbot at llvm.org
Tue Mar 17 12:57:48 PDT 2026


https://github.com/silee2 updated https://github.com/llvm/llvm-project/pull/186247

>From fa446d75007bdc70b60724b3cc334ddd0e6a6b4f Mon Sep 17 00:00:00 2001
From: "Lee, Sang Ik" <sang.ik.lee at intel.com>
Date: Thu, 12 Mar 2026 20:35:26 +0000
Subject: [PATCH 1/4] [MLIR][XeVM] Update HandleVectorExtractPattern
 isExtractContiguousSlice: - Check if mask size is not greater than the vector
 size of the operand. - Check if mask values do not exceed vector size.
 HandleVectorExtractPattern: - Narrow the scope of matching to,     Source
 shuffle doing contiguous extract.     Source shuffle with at least the same
 mask size.

---
 mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp b/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp
index 24009b63e8e26..baf9a6ccc4b09 100644
--- a/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp
+++ b/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp
@@ -895,11 +895,17 @@ static bool isExtractingContiguousSlice(LLVM::ShuffleVectorOp op) {
   if (op.getV1() != op.getV2())
     return false;
   auto maskAttr = op.getMask();
+  int64_t maskSize = static_cast<int64_t>(maskAttr.size());
+  int64_t sourceSize = op.getV1().getType().getNumElements();
+  if (maskSize > sourceSize)
+    return false;
   int64_t firstIndex = maskAttr[0];
-  for (int64_t i = 1; i < static_cast<int64_t>(maskAttr.size()); ++i) {
+  for (int64_t i = 1; i < maskSize; ++i) {
     int64_t index = maskAttr[i];
     if (index != firstIndex + i)
       return false;
+    if (index >= sourceSize)
+      return false;
   }
   return true;
 }
@@ -984,9 +990,18 @@ class HandleVectorExtractPattern
             LLVM::BitcastOp::create(rewriter, loc, ty, newShuffle);
         rewriter.replaceOp(op, newBitcast);
       } else if (isa<LLVM::ShuffleVectorOp>(srcOp)) {
-        // 2. Merge with another shuffle vector op
+        // 2. Merge with source shuffle vector op if,
+        //  - the source op is also extracting a contigous slice.
+        //  - the source op mask size is not smaller than the current
+        //    op mask size.
+        // And create a new shuffle vector op directly from the source
+        // of the first shuffle.
         auto srcShuffle = cast<LLVM::ShuffleVectorOp>(srcOp);
+        if (!isExtractingContiguousSlice(srcShuffle))
+          return failure();
         auto srcMask = srcShuffle.getMask();
+        if (srcMask.size() < mask.size())
+          return failure();
         SmallVector<int32_t> combinedMask;
         for (auto index : mask) {
           combinedMask.push_back(srcMask[index]);

>From 29d4877c385b29de6048bf4ce9287fcdd45bdffb Mon Sep 17 00:00:00 2001
From: "Lee, Sang Ik" <sang.ik.lee at intel.com>
Date: Thu, 12 Mar 2026 20:58:40 +0000
Subject: [PATCH 2/4] Remove redundant check.

---
 mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp b/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp
index baf9a6ccc4b09..93a7891bfcddb 100644
--- a/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp
+++ b/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp
@@ -1000,8 +1000,6 @@ class HandleVectorExtractPattern
         if (!isExtractingContiguousSlice(srcShuffle))
           return failure();
         auto srcMask = srcShuffle.getMask();
-        if (srcMask.size() < mask.size())
-          return failure();
         SmallVector<int32_t> combinedMask;
         for (auto index : mask) {
           combinedMask.push_back(srcMask[index]);

>From 4f28ed174e6cc1aa1c85c4e6c90f560cebe1eef2 Mon Sep 17 00:00:00 2001
From: "Lee, Sang Ik" <sang.ik.lee at intel.com>
Date: Thu, 12 Mar 2026 21:05:35 +0000
Subject: [PATCH 3/4] Update code comments.

---
 mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp b/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp
index 93a7891bfcddb..601507135e701 100644
--- a/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp
+++ b/mlir/lib/Conversion/XeVMToLLVM/XeVMToLLVM.cpp
@@ -891,6 +891,12 @@ class AllocaToGlobalPattern : public OpConversionPattern<LLVM::AllocaOp> {
   }
 };
 
+// Checks if shufflevector is used as a way to extract a contiguous slice
+// from a vector.
+// - source vector V1 and V2 are the same vector.
+// - mask size is not greater than the source vector size
+// - mask values represent a sequence of consecutive increasing numbers
+//   that stay in bounds of the source vector when used for indexing.
 static bool isExtractingContiguousSlice(LLVM::ShuffleVectorOp op) {
   if (op.getV1() != op.getV2())
     return false;
@@ -990,12 +996,10 @@ class HandleVectorExtractPattern
             LLVM::BitcastOp::create(rewriter, loc, ty, newShuffle);
         rewriter.replaceOp(op, newBitcast);
       } else if (isa<LLVM::ShuffleVectorOp>(srcOp)) {
-        // 2. Merge with source shuffle vector op if,
-        //  - the source op is also extracting a contigous slice.
-        //  - the source op mask size is not smaller than the current
-        //    op mask size.
-        // And create a new shuffle vector op directly from the source
-        // of the first shuffle.
+        // 2. Merge with source shuffle vector op if, the source op is
+        //    also extracting a contigous slice and create a new
+        //    shuffle vector op directly from the source of
+        //    the first shuffle.
         auto srcShuffle = cast<LLVM::ShuffleVectorOp>(srcOp);
         if (!isExtractingContiguousSlice(srcShuffle))
           return failure();

>From aab1077691945dc1748fb482cf06c7ab31cd0e9d Mon Sep 17 00:00:00 2001
From: "Lee, Sang Ik" <sang.ik.lee at intel.com>
Date: Tue, 17 Mar 2026 19:57:35 +0000
Subject: [PATCH 4/4] Add test where match should fail.

---
 .../XeVMToLLVM/legalize_large_vector.mlir     | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/mlir/test/Conversion/XeVMToLLVM/legalize_large_vector.mlir b/mlir/test/Conversion/XeVMToLLVM/legalize_large_vector.mlir
index 150f6dba5cbaa..bf11758c074e9 100644
--- a/mlir/test/Conversion/XeVMToLLVM/legalize_large_vector.mlir
+++ b/mlir/test/Conversion/XeVMToLLVM/legalize_large_vector.mlir
@@ -49,3 +49,27 @@ module @test_illegal_vector {
       llvm.return
   }
 }
+
+// -----
+
+module @test_match_fail {
+  // CHECK-LABEL: llvm.func @test_match_fail
+  // CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr, %[[ARG1:.*]]: !llvm.ptr, %[[ARG2:.*]]: !llvm.ptr, %[[ARG3:.*]]: !llvm.ptr
+  llvm.func @test_match_fail(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: !llvm.ptr) {
+    // CHECK: %[[VAR0:.*]] = llvm.load %[[ARG0]]
+    %0 = llvm.load %arg0 : !llvm.ptr -> vector<4xi16>
+    // CHECK: %[[VAR1:.*]] = llvm.load %[[ARG1]]
+    %1 = llvm.load %arg1 : !llvm.ptr -> vector<4xi16>
+    // CHECK: %[[VAR2:.*]] = llvm.shufflevector %[[VAR0]], %[[VAR1]]
+    %2 = llvm.shufflevector %0, %1 [0, 1, 2, 3, 4, 5, 6, 7] : vector<4xi16>
+    // CHECK: %[[VAR3:.*]] = llvm.shufflevector %[[VAR0]], %[[VAR0]]
+    %3 = llvm.shufflevector %0, %0 [0, 1, 2, 3, 4, 5, 6, 7] : vector<4xi16>
+    // CHECK: %[[VAR4:.*]] = llvm.shufflevector %[[VAR2]], %[[VAR2]]
+    %4 = llvm.shufflevector %2, %2 [0, 1, 2, 3, 4, 5] : vector<8xi16>
+    // CHECK: %[[VAR5:.*]] = llvm.shufflevector %[[VAR3]], %[[VAR3]]
+    %5 = llvm.shufflevector %3, %3 [0, 1, 2, 3, 4, 5] : vector<8xi16>
+    llvm.store %4, %arg2 : vector<6xi16>, !llvm.ptr
+    llvm.store %5, %arg3 : vector<6xi16>, !llvm.ptr
+    llvm.return
+  }
+}



More information about the Mlir-commits mailing list