[llvm] [IA][NFC] Factoring out helper functions that extract (de)interleaving factors (PR #148689)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 14 10:58:38 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Min-Yih Hsu (mshockwave)

<details>
<summary>Changes</summary>

Factoring out and combining `isInterleaveIntrinsic`, `isDeinterleaveIntrinsic`, and `getIntrinsicFactor` into `getInterleaveIntrinsicFactor` and `getDeinterleaveIntrinsicFactor` inside VectorUtils.

NFC.
--------
For context: I'm working on another InterleavedAccess-related patch that might use these functions in other places.

---
Full diff: https://github.com/llvm/llvm-project/pull/148689.diff


3 Files Affected:

- (modified) llvm/include/llvm/Analysis/VectorUtils.h (+6) 
- (modified) llvm/lib/Analysis/VectorUtils.cpp (+42) 
- (modified) llvm/lib/CodeGen/InterleavedAccessPass.cpp (+10-64) 


``````````diff
diff --git a/llvm/include/llvm/Analysis/VectorUtils.h b/llvm/include/llvm/Analysis/VectorUtils.h
index 53ba1e8f77791..af1e0d7251a4f 100644
--- a/llvm/include/llvm/Analysis/VectorUtils.h
+++ b/llvm/include/llvm/Analysis/VectorUtils.h
@@ -182,6 +182,12 @@ LLVM_ABI Intrinsic::ID getInterleaveIntrinsicID(unsigned Factor);
 /// Returns the corresponding llvm.vector.deinterleaveN intrinsic for factor N.
 LLVM_ABI Intrinsic::ID getDeinterleaveIntrinsicID(unsigned Factor);
 
+/// Returns the corresponding factor of llvm.vector.interleaveN intrinsics.
+LLVM_ABI unsigned getInterleaveIntrinsicFactor(Intrinsic::ID ID);
+
+/// Returns the corresponding factor of llvm.vector.deinterleaveN intrinsics.
+LLVM_ABI unsigned getDeinterleaveIntrinsicFactor(Intrinsic::ID ID);
+
 /// Given a vector and an element number, see if the scalar value is
 /// already around as a register, for example if it were inserted then extracted
 /// from the vector.
diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp
index 63fccee63c0ae..7f0ed0b60a785 100644
--- a/llvm/lib/Analysis/VectorUtils.cpp
+++ b/llvm/lib/Analysis/VectorUtils.cpp
@@ -264,6 +264,48 @@ Intrinsic::ID llvm::getDeinterleaveIntrinsicID(unsigned Factor) {
   return InterleaveIntrinsics[Factor - 2].Deinterleave;
 }
 
+unsigned llvm::getInterleaveIntrinsicFactor(Intrinsic::ID ID) {
+  switch (ID) {
+  case Intrinsic::vector_interleave2:
+    return 2;
+  case Intrinsic::vector_interleave3:
+    return 3;
+  case Intrinsic::vector_interleave4:
+    return 4;
+  case Intrinsic::vector_interleave5:
+    return 5;
+  case Intrinsic::vector_interleave6:
+    return 6;
+  case Intrinsic::vector_interleave7:
+    return 7;
+  case Intrinsic::vector_interleave8:
+    return 8;
+  default:
+    return 0;
+  }
+}
+
+unsigned llvm::getDeinterleaveIntrinsicFactor(Intrinsic::ID ID) {
+  switch (ID) {
+  case Intrinsic::vector_deinterleave2:
+    return 2;
+  case Intrinsic::vector_deinterleave3:
+    return 3;
+  case Intrinsic::vector_deinterleave4:
+    return 4;
+  case Intrinsic::vector_deinterleave5:
+    return 5;
+  case Intrinsic::vector_deinterleave6:
+    return 6;
+  case Intrinsic::vector_deinterleave7:
+    return 7;
+  case Intrinsic::vector_deinterleave8:
+    return 8;
+  default:
+    return 0;
+  }
+}
+
 /// Given a vector and an element number, see if the scalar value is
 /// already around as a register, for example if it were inserted then extracted
 /// from the vector.
diff --git a/llvm/lib/CodeGen/InterleavedAccessPass.cpp b/llvm/lib/CodeGen/InterleavedAccessPass.cpp
index 7343eed0372e4..7259834975cf4 100644
--- a/llvm/lib/CodeGen/InterleavedAccessPass.cpp
+++ b/llvm/lib/CodeGen/InterleavedAccessPass.cpp
@@ -48,6 +48,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/VectorUtils.h"
 #include "llvm/CodeGen/InterleavedAccess.h"
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
@@ -574,69 +575,11 @@ bool InterleavedAccessImpl::lowerInterleavedStore(
   return true;
 }
 
-static bool isInterleaveIntrinsic(Intrinsic::ID IID) {
-  switch (IID) {
-  case Intrinsic::vector_interleave2:
-  case Intrinsic::vector_interleave3:
-  case Intrinsic::vector_interleave4:
-  case Intrinsic::vector_interleave5:
-  case Intrinsic::vector_interleave6:
-  case Intrinsic::vector_interleave7:
-  case Intrinsic::vector_interleave8:
-    return true;
-  default:
-    return false;
-  }
-}
-
-static bool isDeinterleaveIntrinsic(Intrinsic::ID IID) {
-  switch (IID) {
-  case Intrinsic::vector_deinterleave2:
-  case Intrinsic::vector_deinterleave3:
-  case Intrinsic::vector_deinterleave4:
-  case Intrinsic::vector_deinterleave5:
-  case Intrinsic::vector_deinterleave6:
-  case Intrinsic::vector_deinterleave7:
-  case Intrinsic::vector_deinterleave8:
-    return true;
-  default:
-    return false;
-  }
-}
-
-static unsigned getIntrinsicFactor(const IntrinsicInst *II) {
-  switch (II->getIntrinsicID()) {
-  case Intrinsic::vector_deinterleave2:
-  case Intrinsic::vector_interleave2:
-    return 2;
-  case Intrinsic::vector_deinterleave3:
-  case Intrinsic::vector_interleave3:
-    return 3;
-  case Intrinsic::vector_deinterleave4:
-  case Intrinsic::vector_interleave4:
-    return 4;
-  case Intrinsic::vector_deinterleave5:
-  case Intrinsic::vector_interleave5:
-    return 5;
-  case Intrinsic::vector_deinterleave6:
-  case Intrinsic::vector_interleave6:
-    return 6;
-  case Intrinsic::vector_deinterleave7:
-  case Intrinsic::vector_interleave7:
-    return 7;
-  case Intrinsic::vector_deinterleave8:
-  case Intrinsic::vector_interleave8:
-    return 8;
-  default:
-    llvm_unreachable("Unexpected intrinsic");
-  }
-}
-
 static Value *getMask(Value *WideMask, unsigned Factor,
                       ElementCount LeafValueEC) {
   if (auto *IMI = dyn_cast<IntrinsicInst>(WideMask)) {
-    if (isInterleaveIntrinsic(IMI->getIntrinsicID()) &&
-        getIntrinsicFactor(IMI) == Factor && llvm::all_equal(IMI->args())) {
+    if (unsigned F = getInterleaveIntrinsicFactor(IMI->getIntrinsicID());
+        F && F == Factor && llvm::all_equal(IMI->args())) {
       return IMI->getArgOperand(0);
     }
   }
@@ -672,7 +615,9 @@ bool InterleavedAccessImpl::lowerDeinterleaveIntrinsic(
   if (!LoadedVal->hasOneUse() || !isa<LoadInst, VPIntrinsic>(LoadedVal))
     return false;
 
-  const unsigned Factor = getIntrinsicFactor(DI);
+  const unsigned Factor = getDeinterleaveIntrinsicFactor(DI->getIntrinsicID());
+  assert(Factor && "unexpected deinterleave intrinsic");
+
   SmallVector<Value *, 8> DeinterleaveValues(Factor, nullptr);
   Value *LastFactor = nullptr;
   for (auto *User : DI->users()) {
@@ -738,7 +683,8 @@ bool InterleavedAccessImpl::lowerInterleaveIntrinsic(
     return false;
 
   SmallVector<Value *, 8> InterleaveValues(II->args());
-  const unsigned Factor = getIntrinsicFactor(II);
+  const unsigned Factor = getInterleaveIntrinsicFactor(II->getIntrinsicID());
+  assert(Factor && "unexpected interleave intrinsic");
 
   if (auto *VPStore = dyn_cast<VPIntrinsic>(StoredBy)) {
     if (VPStore->getIntrinsicID() != Intrinsic::vp_store)
@@ -792,9 +738,9 @@ bool InterleavedAccessImpl::runOnFunction(Function &F) {
       Changed |= lowerInterleavedStore(&I, DeadInsts);
 
     if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
-      if (isDeinterleaveIntrinsic(II->getIntrinsicID()))
+      if (getDeinterleaveIntrinsicFactor(II->getIntrinsicID()))
         Changed |= lowerDeinterleaveIntrinsic(II, DeadInsts);
-      else if (isInterleaveIntrinsic(II->getIntrinsicID()))
+      else if (getInterleaveIntrinsicFactor(II->getIntrinsicID()))
         Changed |= lowerInterleaveIntrinsic(II, DeadInsts);
     }
   }

``````````

</details>


https://github.com/llvm/llvm-project/pull/148689


More information about the llvm-commits mailing list