[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