https://github.com/madhur13490 updated https://github.com/llvm/llvm-project/pull/214673
>From 90efd40daf5b619a3457d0a08e24c665dbe271ae Mon Sep 17 00:00:00 2001 From: Madhur Amilkanthwar <[email protected]> Date: Wed, 5 Aug 2026 23:51:35 -0700 Subject: [PATCH 1/2] [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 36e0bdbf7ac4a..0a647205c3d57 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 @@ -542,24 +494,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 >From 54b32d386dd3d60e5d8042bdac484b8314f26dee Mon Sep 17 00:00:00 2001 From: Madhur Amilkanthwar <[email protected]> Date: Sun, 30 Aug 2026 21:36:13 -0700 Subject: [PATCH 2/2] fixup! [SLP][modularisation][NFC] Move full-vector width helpers to SLPTypeUtils (2/2) --- llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h index cd2641c885732..2bd7065cac433 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h @@ -58,7 +58,7 @@ unsigned getFloorFullVectorNumberOfElements(const TargetTransformInfo &TTI, /// 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. +/// div/rem. Does not check profitability. FixedVectorType *getMaskedDivRemType(const TargetTransformInfo &TTI, unsigned Opcode, Type *ScalarTy, unsigned NumElts); _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
