[llvm-branch-commits] [llvm] [SLP][modularisation][NFC] Move getReductionInstr/getAggregateSize to SLPReductionUtils (PR #222613)
Madhur Amilkanthwar via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Oct 8 23:29:34 PDT 2026
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 <madhura at nvidia.com>
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
More information about the llvm-branch-commits
mailing list