[llvm] [IV][RISCV] Make the isDeInterleaveMask check the contents of shuffle (PR #185384)
Liao Chunyu via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 9 03:15:15 PDT 2026
https://github.com/ChunyuLiao updated https://github.com/llvm/llvm-project/pull/185384
>From d483540d6ce115885d8e3c0cd17b8ca754c25f58 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Mon, 9 Mar 2026 03:05:05 +0000
Subject: [PATCH 1/3] init testcase
---
.../rvv/fixed-vectors-interleaved-access.ll | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-interleaved-access.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-interleaved-access.ll
index 9b35860904f11..aaf126dec0173 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-interleaved-access.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-interleaved-access.ll
@@ -2465,3 +2465,21 @@ define {<4 x i32>, <4 x i32>, <4 x i32>} @maskedload_factor5_skip_fields(ptr %pt
ret {<4 x i32>, <4 x i32>, <4 x i32>} %res2
}
+define <4 x i8> @vp_load_v16i8_factor5_one_active(ptr %ptr) {
+; CHECK-LABEL: vp_load_v16i8_factor5_one_active:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 20, e8, m1, ta, ma
+; CHECK-NEXT: vle8.v v8, (a0)
+; CHECK-NEXT: li a0, 33
+; CHECK-NEXT: vmv.s.x v0, a0
+; CHECK-NEXT: vsetivli zero, 8, e8, m1, ta, ma
+; CHECK-NEXT: vslidedown.vi v9, v8, 8
+; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, mu
+; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
+; CHECK-NEXT: vmv.v.i v0, 10
+; CHECK-NEXT: vslidedown.vi v8, v8, 4, v0.t
+; CHECK-NEXT: ret
+ %interleaved.vec = tail call <16 x i8> @llvm.vp.load.v16i8.p0(ptr %ptr, <16 x i1> splat (i1 true), i32 20)
+ %v0 = shufflevector <16 x i8> %interleaved.vec, <16 x i8> poison, <4 x i32> <i32 0, i32 5, i32 10, i32 15>
+ ret <4 x i8> %v0
+}
>From 7d7d4ab36e828bcc3998cf673ec1dac59e836cce Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Mon, 9 Mar 2026 07:04:46 +0000
Subject: [PATCH 2/3] [IV][RISCV] Make the isDeInterleaveMask check the
contents of shuffle
Inspect the shuffle contents to detect potential undefined behavior,
enabling broader support for interleave loads.
For example, load.v16* with factor 5 and mask[0,5,10,15] is now
handled, whereas it would have been skipped previously.
---
llvm/lib/CodeGen/InterleavedAccessPass.cpp | 17 +++++++++++++----
.../rvv/fixed-vectors-interleaved-access.ll | 13 +++----------
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/CodeGen/InterleavedAccessPass.cpp b/llvm/lib/CodeGen/InterleavedAccessPass.cpp
index 9df7d53c63ff3..5dd62ac929e2b 100644
--- a/llvm/lib/CodeGen/InterleavedAccessPass.cpp
+++ b/llvm/lib/CodeGen/InterleavedAccessPass.cpp
@@ -209,15 +209,24 @@ FunctionPass *llvm::createInterleavedAccessPass() {
/// <1, 3, 5, 7> (mask of index 1 to extract odd elements)
static bool isDeInterleaveMask(ArrayRef<int> Mask, unsigned &Factor,
unsigned &Index, unsigned MaxFactor,
- unsigned NumLoadElements) {
+ unsigned NumLoadElements,
+ SmallVector<ShuffleVectorInst *, 4> Shuffles) {
if (Mask.size() < 2)
return false;
// Check potential Factors.
for (Factor = 2; Factor <= MaxFactor; Factor++) {
// Make sure we don't produce a load wider than the input load.
- if (Mask.size() * Factor > NumLoadElements)
- return false;
+ if (Mask.size() * Factor > NumLoadElements) {
+ if (Shuffles.size() == 0)
+ return false;
+ for (unsigned i = 0; i < Shuffles.size(); i++) {
+ for (unsigned j = 0; j < Mask.size(); j++) {
+ if ((unsigned)Shuffles[i]->getShuffleMask()[j] > NumLoadElements)
+ return false;
+ }
+ }
+ }
if (ShuffleVectorInst::isDeInterleaveMaskOfFactor(Mask, Factor, Index))
return true;
}
@@ -333,7 +342,7 @@ bool InterleavedAccessImpl::lowerInterleavedLoad(
auto *FirstSVI = Shuffles.size() > 0 ? Shuffles[0] : BinOpShuffles[0];
// Check if the first shufflevector is DE-interleave shuffle.
if (!isDeInterleaveMask(FirstSVI->getShuffleMask(), Factor, Index, MaxFactor,
- NumLoadElements))
+ NumLoadElements, Shuffles))
return false;
// Holds the corresponding index for each DE-interleave shuffle.
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-interleaved-access.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-interleaved-access.ll
index aaf126dec0173..17aea73064274 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-interleaved-access.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-interleaved-access.ll
@@ -2468,16 +2468,9 @@ define {<4 x i32>, <4 x i32>, <4 x i32>} @maskedload_factor5_skip_fields(ptr %pt
define <4 x i8> @vp_load_v16i8_factor5_one_active(ptr %ptr) {
; CHECK-LABEL: vp_load_v16i8_factor5_one_active:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 20, e8, m1, ta, ma
-; CHECK-NEXT: vle8.v v8, (a0)
-; CHECK-NEXT: li a0, 33
-; CHECK-NEXT: vmv.s.x v0, a0
-; CHECK-NEXT: vsetivli zero, 8, e8, m1, ta, ma
-; CHECK-NEXT: vslidedown.vi v9, v8, 8
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, mu
-; CHECK-NEXT: vmerge.vvm v8, v9, v8, v0
-; CHECK-NEXT: vmv.v.i v0, 10
-; CHECK-NEXT: vslidedown.vi v8, v8, 4, v0.t
+; CHECK-NEXT: li a1, 5
+; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
+; CHECK-NEXT: vlse8.v v8, (a0), a1
; CHECK-NEXT: ret
%interleaved.vec = tail call <16 x i8> @llvm.vp.load.v16i8.p0(ptr %ptr, <16 x i1> splat (i1 true), i32 20)
%v0 = shufflevector <16 x i8> %interleaved.vec, <16 x i8> poison, <4 x i32> <i32 0, i32 5, i32 10, i32 15>
>From 318116819b92fa679929317e8b167ab916df2f92 Mon Sep 17 00:00:00 2001
From: Liao Chunyu <chunyu at iscas.ac.cn>
Date: Mon, 9 Mar 2026 10:14:48 +0000
Subject: [PATCH 3/3] format
---
llvm/lib/CodeGen/InterleavedAccessPass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/InterleavedAccessPass.cpp b/llvm/lib/CodeGen/InterleavedAccessPass.cpp
index 5dd62ac929e2b..de0ca57d08e06 100644
--- a/llvm/lib/CodeGen/InterleavedAccessPass.cpp
+++ b/llvm/lib/CodeGen/InterleavedAccessPass.cpp
@@ -219,7 +219,7 @@ static bool isDeInterleaveMask(ArrayRef<int> Mask, unsigned &Factor,
// Make sure we don't produce a load wider than the input load.
if (Mask.size() * Factor > NumLoadElements) {
if (Shuffles.size() == 0)
- return false;
+ return false;
for (unsigned i = 0; i < Shuffles.size(); i++) {
for (unsigned j = 0; j < Mask.size(); j++) {
if ((unsigned)Shuffles[i]->getShuffleMask()[j] > NumLoadElements)
More information about the llvm-commits
mailing list