[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