[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