Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 14, 2025

Conversation

mshockwave
Copy link
Member

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.

@mshockwave mshockwave requested review from preames and lukel97 July 14, 2025 17:57
@llvmbot llvmbot added llvm:codegen llvm:analysis Includes value tracking, cost tables and constant folding labels Jul 14, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 14, 2025

@llvm/pr-subscribers-llvm-analysis

Author: Min-Yih Hsu (mshockwave)

Changes

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 --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);
     }
   }

Copy link
Contributor

@lukel97 lukel97 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mshockwave mshockwave merged commit ae810dd into llvm:main Jul 14, 2025
12 checks passed
@mshockwave mshockwave deleted the patch/factor-interleave-utils branch July 14, 2025 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:analysis Includes value tracking, cost tables and constant folding llvm:codegen
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants