[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