[llvm] [IV][RISCV] Make the isDeInterleaveMask check the contents of shuffle (PR #185384)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 9 03:11:16 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Liao Chunyu (ChunyuLiao)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/185384.diff
2 Files Affected:
- (modified) llvm/lib/CodeGen/InterleavedAccessPass.cpp (+13-4)
- (modified) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-interleaved-access.ll (+11)
``````````diff
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 9b35860904f11..17aea73064274 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,14 @@ 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: 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>
+ ret <4 x i8> %v0
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/185384
More information about the llvm-commits
mailing list