https://github.com/madhur13490 updated https://github.com/llvm/llvm-project/pull/222613
>From aba6f58d009057dc2447427d1ceb7d99ca2658ec Mon Sep 17 00:00:00 2001 From: Madhur Amilkanthwar <[email protected]> Date: Thu, 10 Sep 2026 04:12:20 -0700 Subject: [PATCH] [SLP][modularisation][NFC] Move getReductionInstr to SLPReductionUtils, getAggregateSize to SLPUtils Move the reduction-root helper getReductionInstr out of SLPVectorizer.cpp into the self-contained SLPVectorizer/SLPReductionUtils.{h,cpp} module. getAggregateSize is not reduction-specific: its only user is findBuildAggregate and it only computes the element count of a homogeneous aggregate from its type. Move it to the generic SLPVectorizer/SLPUtils module instead. Part of the SLPVectorizer.cpp modularization effort: https://discourse.llvm.org/t/modularizing-slpvectorizer-cpp/90922 Assisted by AI --- .../Transforms/Vectorize/SLPVectorizer.cpp | 79 ------------------- .../SLPVectorizer/SLPReductionUtils.cpp | 47 +++++++++++ .../SLPVectorizer/SLPReductionUtils.h | 9 +++ .../Vectorize/SLPVectorizer/SLPUtils.cpp | 29 +++++++ .../Vectorize/SLPVectorizer/SLPUtils.h | 5 ++ 5 files changed, 90 insertions(+), 79 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index e7bf44f6669a7e..0ee63c3e276189 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -34808,34 +34808,6 @@ class HorizontalReduction { static RecurKind getRdxKind(Value *V) { return HorizontalReduction::getRdxKind(V); } -static std::optional<unsigned> getAggregateSize(Instruction *InsertInst) { - if (auto *IE = dyn_cast<InsertElementInst>(InsertInst)) - return cast<FixedVectorType>(IE->getType())->getNumElements(); - - unsigned AggregateSize = 1; - auto *IV = cast<InsertValueInst>(InsertInst); - Type *CurrentType = IV->getType(); - do { - if (auto *ST = dyn_cast<StructType>(CurrentType)) { - for (auto *Elt : ST->elements()) - if (Elt != ST->getElementType(0)) // check homogeneity - return std::nullopt; - AggregateSize *= ST->getNumElements(); - CurrentType = ST->getElementType(0); - } else if (auto *AT = dyn_cast<ArrayType>(CurrentType)) { - AggregateSize *= AT->getNumElements(); - CurrentType = AT->getElementType(); - } else if (auto *VT = dyn_cast<FixedVectorType>(CurrentType)) { - AggregateSize *= VT->getNumElements(); - return AggregateSize; - } else if (CurrentType->isSingleValueType()) { - return AggregateSize; - } else { - return std::nullopt; - } - } while (true); -} - static void findBuildAggregateRec(Instruction *LastInsertInst, TargetTransformInfo *TTI, SmallVectorImpl<Value *> &BuildVectorOpds, @@ -34903,57 +34875,6 @@ static bool findBuildAggregate(Instruction *LastInsertInst, return false; } -/// Try and get a reduction instruction from a phi node. -/// -/// Given a phi node \p P in a block \p ParentBB, consider possible reductions -/// if they come from either \p ParentBB or a containing loop latch. -/// -/// \returns A candidate reduction value if possible, or \code nullptr \endcode -/// if not possible. -static Instruction *getReductionInstr(const DominatorTree *DT, PHINode *P, - BasicBlock *ParentBB, LoopInfo *LI) { - // There are situations where the reduction value is not dominated by the - // reduction phi. Vectorizing such cases has been reported to cause - // miscompiles. See PR25787. - auto DominatedReduxValue = [&](Value *R) { - return isa<Instruction>(R) && - DT->dominates(P->getParent(), cast<Instruction>(R)->getParent()); - }; - - Instruction *Rdx = nullptr; - - // Return the incoming value if it comes from the same BB as the phi node. - if (P->getIncomingBlock(0) == ParentBB) { - Rdx = dyn_cast<Instruction>(P->getIncomingValue(0)); - } else if (P->getIncomingBlock(1) == ParentBB) { - Rdx = dyn_cast<Instruction>(P->getIncomingValue(1)); - } - - if (Rdx && DominatedReduxValue(Rdx)) - return Rdx; - - // Otherwise, check whether we have a loop latch to look at. - Loop *BBL = LI->getLoopFor(ParentBB); - if (!BBL) - return nullptr; - BasicBlock *BBLatch = BBL->getLoopLatch(); - if (!BBLatch) - return nullptr; - - // There is a loop latch, return the incoming value if it comes from - // that. This reduction pattern occasionally turns up. - if (P->getIncomingBlock(0) == BBLatch) { - Rdx = dyn_cast<Instruction>(P->getIncomingValue(0)); - } else if (P->getIncomingBlock(1) == BBLatch) { - Rdx = dyn_cast<Instruction>(P->getIncomingValue(1)); - } - - if (Rdx && DominatedReduxValue(Rdx)) - return Rdx; - - return nullptr; -} - /// We could have an initial reduction that is not an add. /// r *= v1 + v2 + v3 + v4 /// In such a case start looking for a tree rooted in the first '+'. diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.cpp index e8626c9a00b480..d95e185e49978a 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.cpp @@ -14,9 +14,12 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallBitVector.h" #include "llvm/Analysis/IVDescriptors.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Dominators.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" @@ -169,4 +172,48 @@ Value *tryEmitBoolReduxBitcastCmp(IRBuilderBase &Builder, return Res; } +Instruction *getReductionInstr(const DominatorTree *DT, PHINode *P, + BasicBlock *ParentBB, LoopInfo *LI) { + // There are situations where the reduction value is not dominated by the + // reduction phi. Vectorizing such cases has been reported to cause + // miscompiles. See PR25787. + auto DominatedReduxValue = [&](Value *R) { + return isa<Instruction>(R) && + DT->dominates(P->getParent(), cast<Instruction>(R)->getParent()); + }; + + Instruction *Rdx = nullptr; + + // Return the incoming value if it comes from the same BB as the phi node. + if (P->getIncomingBlock(0) == ParentBB) { + Rdx = dyn_cast<Instruction>(P->getIncomingValue(0)); + } else if (P->getIncomingBlock(1) == ParentBB) { + Rdx = dyn_cast<Instruction>(P->getIncomingValue(1)); + } + + if (Rdx && DominatedReduxValue(Rdx)) + return Rdx; + + // Otherwise, check whether we have a loop latch to look at. + Loop *BBL = LI->getLoopFor(ParentBB); + if (!BBL) + return nullptr; + BasicBlock *BBLatch = BBL->getLoopLatch(); + if (!BBLatch) + return nullptr; + + // There is a loop latch, return the incoming value if it comes from + // that. This reduction pattern occasionally turns up. + if (P->getIncomingBlock(0) == BBLatch) { + Rdx = dyn_cast<Instruction>(P->getIncomingValue(0)); + } else if (P->getIncomingBlock(1) == BBLatch) { + Rdx = dyn_cast<Instruction>(P->getIncomingValue(1)); + } + + if (Rdx && DominatedReduxValue(Rdx)) + return Rdx; + + return nullptr; +} + } // namespace llvm::slpvectorizer diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h index 6e55bfdad861c8..fb0246255d20b3 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPReductionUtils.h @@ -20,10 +20,13 @@ #include "llvm/Analysis/TargetTransformInfo.h" namespace llvm { +class BasicBlock; class DataLayout; +class DominatorTree; class FastMathFlags; class IRBuilderBase; class Instruction; +class LoopInfo; class PHINode; class Type; class Value; @@ -82,6 +85,12 @@ Value *tryEmitBoolReduxBitcastCmp(IRBuilderBase &Builder, const Value *Root, FastMathFlags FMF, TargetTransformInfo::TargetCostKind CostKind); +/// Try to get a reduction instruction from phi node \p P in block \p ParentBB, +/// considering incoming values from \p ParentBB or the containing loop latch. +/// \returns a candidate reduction value, or nullptr if none. +Instruction *getReductionInstr(const DominatorTree *DT, PHINode *P, + BasicBlock *ParentBB, LoopInfo *LI); + } // namespace llvm::slpvectorizer #endif // LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPREDUCTIONUTILS_H diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.cpp index b4f855ad38306f..7872d039176c69 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.cpp @@ -30,6 +30,7 @@ #include <algorithm> #include <numeric> +#include <optional> #include <string> #include <type_traits> @@ -1565,4 +1566,32 @@ DebugLoc getDebugLocFromPHI(PHINode &PN) { return DebugLoc::getUnknown(); } +std::optional<unsigned> getAggregateSize(Instruction *InsertInst) { + if (auto *IE = dyn_cast<InsertElementInst>(InsertInst)) + return cast<FixedVectorType>(IE->getType())->getNumElements(); + + unsigned AggregateSize = 1; + auto *IV = cast<InsertValueInst>(InsertInst); + Type *CurrentType = IV->getType(); + do { + if (auto *ST = dyn_cast<StructType>(CurrentType)) { + for (auto *Elt : ST->elements()) + if (Elt != ST->getElementType(0)) // check homogeneity + return std::nullopt; + AggregateSize *= ST->getNumElements(); + CurrentType = ST->getElementType(0); + } else if (auto *AT = dyn_cast<ArrayType>(CurrentType)) { + AggregateSize *= AT->getNumElements(); + CurrentType = AT->getElementType(); + } else if (auto *VT = dyn_cast<FixedVectorType>(CurrentType)) { + AggregateSize *= VT->getNumElements(); + return AggregateSize; + } else if (CurrentType->isSingleValueType()) { + return AggregateSize; + } else { + return std::nullopt; + } + } while (true); +} + } // namespace llvm::slpvectorizer diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.h b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.h index 82518f5e57e472..5be848c8fb585d 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.h +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPUtils.h @@ -513,6 +513,11 @@ bool isFirstInsertElement(const InsertElementInst *IE1, /// none. DebugLoc getDebugLocFromPHI(PHINode &PN); +/// \returns the number of elements of the homogeneous aggregate built by +/// \p InsertInst (insertelement or insertvalue), or std::nullopt if it is not +/// a homogeneous aggregate. +std::optional<unsigned> getAggregateSize(Instruction *InsertInst); + } // namespace llvm::slpvectorizer #endif // LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPUTILS_H _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
