[llvm-branch-commits] [llvm] [SLP][modularisation][NFC] Move full-vector width helpers to SLPTypeUtils (2/2) (PR #214673)

Madhur Amilkanthwar via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Aug 7 02:07:11 PDT 2026


https://github.com/madhur13490 created https://github.com/llvm/llvm-project/pull/214673



Move the following BoUpSLP-independent helpers out of SLPVectorizer.cpp into SLPVectorizer/SLPTypeUtils.{h,cpp}:

  getFullVectorNumberOfElements
  getFloorFullVectorNumberOfElements
  getMaskedDivRemType
  hasFullVectorsOrPowerOf2

They build on the type helpers moved in (1/2). Behavior is unchanged.

Part of the SLPVectorizer.cpp modularization effort: https://discourse.llvm.org/t/modularizing-slpvectorizer-cpp/90922

>From ff99615fc3c6725cbd2f5c546bcf5319122d56a0 Mon Sep 17 00:00:00 2001
From: Madhur Amilkanthwar <madhura at nvidia.com>
Date: Wed, 5 Aug 2026 23:51:35 -0700
Subject: [PATCH] [SLP][modularisation][NFC] Move full-vector width helpers to
 SLPTypeUtils (2/2)

Move the following BoUpSLP-independent helpers out of SLPVectorizer.cpp
into SLPVectorizer/SLPTypeUtils.{h,cpp}:

  getFullVectorNumberOfElements
  getFloorFullVectorNumberOfElements
  getMaskedDivRemType
  hasFullVectorsOrPowerOf2

They build on the type helpers moved in (1/2). Behavior is unchanged.

Part of the SLPVectorizer.cpp modularization effort:
https://discourse.llvm.org/t/modularizing-slpvectorizer-cpp/90922
---
 .../Transforms/Vectorize/SLPVectorizer.cpp    | 66 -------------------
 .../Vectorize/SLPVectorizer/SLPTypeUtils.cpp  | 56 ++++++++++++++++
 .../Vectorize/SLPVectorizer/SLPTypeUtils.h    | 28 ++++++++
 3 files changed, 84 insertions(+), 66 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index ed1bb0229319b..73f4cba512448 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -353,54 +353,6 @@ static const int MinScheduleRegionSize = 16;
 /// Maximum allowed number of operands in the PHI nodes.
 static const unsigned MaxPHINumOperands = 128;
 
-/// Returns the number of elements of the given type \p Ty, not less than \p Sz,
-/// which forms type, which splits by \p TTI into whole vector types during
-/// legalization.
-static unsigned getFullVectorNumberOfElements(const TargetTransformInfo &TTI,
-                                              Type *Ty, unsigned Sz) {
-  if (!isValidElementType(Ty) || isa<StructType>(Ty))
-    return bit_ceil(Sz);
-  // Find the number of elements, which forms full vectors.
-  const unsigned NumParts = TTI.getNumberOfParts(getWidenedType(Ty, Sz));
-  if (NumParts == 0 || NumParts >= Sz)
-    return bit_ceil(Sz);
-  return bit_ceil(divideCeil(Sz, NumParts)) * NumParts;
-}
-
-/// Returns the number of elements of the given type \p Ty, not greater than \p
-/// Sz, which forms type, which splits by \p TTI into whole vector types during
-/// legalization.
-static unsigned
-getFloorFullVectorNumberOfElements(const TargetTransformInfo &TTI, Type *Ty,
-                                   unsigned Sz) {
-  if (!isValidElementType(Ty) || isa<StructType>(Ty))
-    return bit_floor(Sz);
-  // Find the number of elements, which forms full vectors.
-  unsigned NumParts = TTI.getNumberOfParts(getWidenedType(Ty, Sz));
-  if (NumParts == 0 || NumParts >= Sz)
-    return bit_floor(Sz);
-  unsigned RegVF = bit_ceil(divideCeil(Sz, NumParts));
-  if (RegVF > Sz)
-    return bit_floor(Sz);
-  return (Sz / RegVF) * RegVF;
-}
-
-/// For a non-power-of-2 \p NumElts-wide integer div/rem \p Opcode, returns the
-/// padded full-register vector type if padding is structurally possible, or
-/// nullptr if the vector already fills a register or the opcode is not
-/// div/rem. Does not check profitability; see getMaskedDivRemCost for that.
-static FixedVectorType *getMaskedDivRemType(const TargetTransformInfo &TTI,
-                                            unsigned Opcode, Type *ScalarTy,
-                                            unsigned NumElts) {
-  if (!Instruction::isIntDivRem(Opcode) || has_single_bit(NumElts))
-    return nullptr;
-  unsigned PaddedNumElts =
-      getFullVectorNumberOfElements(TTI, ScalarTy, NumElts);
-  if (PaddedNumElts == NumElts)
-    return nullptr;
-  return cast<FixedVectorType>(getWidenedType(ScalarTy, PaddedNumElts));
-}
-
 /// For a non-power-of-2 \p NumElts-wide integer div/rem \p Opcode, checks if
 /// padding to a full register and using the masked div/rem intrinsic is
 /// cheaper than the direct vector op. Returns the cost of the masked
@@ -539,24 +491,6 @@ isFixedVectorShuffle(ArrayRef<Value *> VL, SmallVectorImpl<int> &Mask,
               : TargetTransformInfo::SK_PermuteSingleSrc;
 }
 
-/// Returns true if widened type of \p Ty elements with size \p Sz represents
-/// full vector type, i.e. adding extra element results in extra parts upon type
-/// legalization.
-static bool hasFullVectorsOrPowerOf2(const TargetTransformInfo &TTI, Type *Ty,
-                                     unsigned Sz) {
-  if (Sz <= 1)
-    return false;
-  if (!isValidElementType(Ty) && !isa<FixedVectorType>(Ty))
-    return false;
-  if (has_single_bit(Sz))
-    return true;
-  if (isa<StructType>(Ty))
-    return false;
-  const unsigned NumParts = TTI.getNumberOfParts(getWidenedType(Ty, Sz));
-  return NumParts > 0 && NumParts < Sz && has_single_bit(Sz / NumParts) &&
-         Sz % NumParts == 0;
-}
-
 /// Returns number of parts, the type \p VecTy will be split at the codegen
 /// phase. If the type is going to be scalarized or does not uses whole
 /// registers, returns 1.
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.cpp
index dd8f0ac69c735..7c06a587372fe 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.cpp
@@ -11,13 +11,17 @@
 
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVectorExtras.h"
+#include "llvm/ADT/bit.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Analysis/VectorUtils.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instruction.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Type.h"
 #include "llvm/IR/Value.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/MathExtras.h"
 
 #include <cassert>
 
@@ -73,4 +77,56 @@ Type *getWidenedType(Type *ScalarTy, unsigned VF) {
                         ElementCount::getFixed(VF * getNumElements(ScalarTy)));
 }
 
+unsigned getFullVectorNumberOfElements(const TargetTransformInfo &TTI, Type *Ty,
+                                       unsigned Sz) {
+  if (!isValidElementType(Ty) || isa<StructType>(Ty))
+    return bit_ceil(Sz);
+  // Find the number of elements, which forms full vectors.
+  const unsigned NumParts = TTI.getNumberOfParts(getWidenedType(Ty, Sz));
+  if (NumParts == 0 || NumParts >= Sz)
+    return bit_ceil(Sz);
+  return bit_ceil(divideCeil(Sz, NumParts)) * NumParts;
+}
+
+unsigned getFloorFullVectorNumberOfElements(const TargetTransformInfo &TTI,
+                                            Type *Ty, unsigned Sz) {
+  if (!isValidElementType(Ty) || isa<StructType>(Ty))
+    return bit_floor(Sz);
+  // Find the number of elements, which forms full vectors.
+  unsigned NumParts = TTI.getNumberOfParts(getWidenedType(Ty, Sz));
+  if (NumParts == 0 || NumParts >= Sz)
+    return bit_floor(Sz);
+  unsigned RegVF = bit_ceil(divideCeil(Sz, NumParts));
+  if (RegVF > Sz)
+    return bit_floor(Sz);
+  return (Sz / RegVF) * RegVF;
+}
+
+FixedVectorType *getMaskedDivRemType(const TargetTransformInfo &TTI,
+                                     unsigned Opcode, Type *ScalarTy,
+                                     unsigned NumElts) {
+  if (!Instruction::isIntDivRem(Opcode) || has_single_bit(NumElts))
+    return nullptr;
+  unsigned PaddedNumElts =
+      getFullVectorNumberOfElements(TTI, ScalarTy, NumElts);
+  if (PaddedNumElts == NumElts)
+    return nullptr;
+  return cast<FixedVectorType>(getWidenedType(ScalarTy, PaddedNumElts));
+}
+
+bool hasFullVectorsOrPowerOf2(const TargetTransformInfo &TTI, Type *Ty,
+                              unsigned Sz) {
+  if (Sz <= 1)
+    return false;
+  if (!isValidElementType(Ty) && !isa<FixedVectorType>(Ty))
+    return false;
+  if (has_single_bit(Sz))
+    return true;
+  if (isa<StructType>(Ty))
+    return false;
+  const unsigned NumParts = TTI.getNumberOfParts(getWidenedType(Ty, Sz));
+  return NumParts > 0 && NumParts < Sz && has_single_bit(Sz / NumParts) &&
+         Sz % NumParts == 0;
+}
+
 } // namespace llvm::slpvectorizer
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h
index f43fd98b6288e..cd2641c885732 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h
@@ -15,6 +15,8 @@
 #define LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPTYPEUTILS_H
 
 namespace llvm {
+class FixedVectorType;
+class TargetTransformInfo;
 class Type;
 class Value;
 } // namespace llvm
@@ -41,6 +43,32 @@ Type *getValueType(Value *V, bool LookThroughCmp = false);
 /// \returns the vector type of ScalarTy based on vectorization factor.
 Type *getWidenedType(Type *ScalarTy, unsigned VF);
 
+/// Returns the number of elements of the given type \p Ty, not less than \p Sz,
+/// which forms type, which splits by \p TTI into whole vector types during
+/// legalization.
+unsigned getFullVectorNumberOfElements(const TargetTransformInfo &TTI, Type *Ty,
+                                       unsigned Sz);
+
+/// Returns the number of elements of the given type \p Ty, not greater than \p
+/// Sz, which forms type, which splits by \p TTI into whole vector types during
+/// legalization.
+unsigned getFloorFullVectorNumberOfElements(const TargetTransformInfo &TTI,
+                                            Type *Ty, unsigned Sz);
+
+/// For a non-power-of-2 \p NumElts-wide integer div/rem \p Opcode, returns the
+/// padded full-register vector type if padding is structurally possible, or
+/// nullptr if the vector already fills a register or the opcode is not
+/// div/rem. Does not check profitability; see getMaskedDivRemCost for that.
+FixedVectorType *getMaskedDivRemType(const TargetTransformInfo &TTI,
+                                     unsigned Opcode, Type *ScalarTy,
+                                     unsigned NumElts);
+
+/// Returns true if widened type of \p Ty elements with size \p Sz represents
+/// full vector type, i.e. adding extra element results in extra parts upon type
+/// legalization.
+bool hasFullVectorsOrPowerOf2(const TargetTransformInfo &TTI, Type *Ty,
+                              unsigned Sz);
+
 } // namespace llvm::slpvectorizer
 
 #endif // LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPTYPEUTILS_H



More information about the llvm-branch-commits mailing list