Skip to content

Commit 5df3db6

Browse files
committed
Unify Find recurrence detection.
1 parent 570f0e3 commit 5df3db6

File tree

5 files changed

+35
-55
lines changed

5 files changed

+35
-55
lines changed

llvm/include/llvm/Analysis/IVDescriptors.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,8 @@ class RecurrenceDescriptor {
186186
/// where one of (X, Y) is an increasing (FindLastIV) or decreasing
187187
/// (FindFirstIV) loop induction variable, or an arbitrary integer value
188188
/// (FindLast), and the other is a PHI value.
189-
LLVM_ABI static InstDesc isFindPattern(RecurKind Kind, Loop *TheLoop,
190-
PHINode *OrigPhi, Instruction *I,
191-
ScalarEvolution &SE);
189+
LLVM_ABI static InstDesc isFindPattern(Loop *TheLoop, PHINode *OrigPhi,
190+
Instruction *I, ScalarEvolution &SE);
192191

193192
/// Returns a struct describing if the instruction is a
194193
/// Select(FCmp(X, Y), (Z = X op PHINode), PHINode) instruction pattern.
@@ -319,6 +318,10 @@ class RecurrenceDescriptor {
319318
return Kind == RecurKind::FindLast;
320319
}
321320

321+
static bool isFindRecurrenceKind(RecurKind Kind) {
322+
return isFindLastRecurrenceKind(Kind) || isFindIVRecurrenceKind(Kind);
323+
}
324+
322325
/// Returns the type of the recurrence. This type can be narrower than the
323326
/// actual type of the Phi if the recurrence has been type-promoted.
324327
Type *getRecurrenceType() const { return RecurrenceType; }

llvm/lib/Analysis/IVDescriptors.cpp

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -758,9 +758,8 @@ RecurrenceDescriptor::isAnyOfPattern(Loop *Loop, PHINode *OrigPhi,
758758
// will either be the initial value (0) if the condition was never met, or the
759759
// value of a[i] in the most recent loop iteration where the condition was met.
760760
RecurrenceDescriptor::InstDesc
761-
RecurrenceDescriptor::isFindPattern(RecurKind Kind, Loop *TheLoop,
762-
PHINode *OrigPhi, Instruction *I,
763-
ScalarEvolution &SE) {
761+
RecurrenceDescriptor::isFindPattern(Loop *TheLoop, PHINode *OrigPhi,
762+
Instruction *I, ScalarEvolution &SE) {
764763
// TODO: Support the vectorization of FindLastIV when the reduction phi is
765764
// used by more than one select instruction. This vectorization is only
766765
// performed when the SCEV of each increasing induction variable used by the
@@ -781,17 +780,6 @@ RecurrenceDescriptor::isFindPattern(RecurKind Kind, Loop *TheLoop,
781780
m_Value(NonRdxPhi)))))
782781
return InstDesc(false, I);
783782

784-
if (isFindLastRecurrenceKind(Kind)) {
785-
// Must be an integer scalar.
786-
Type *Type = OrigPhi->getType();
787-
if (!Type->isIntegerTy())
788-
return InstDesc(false, I);
789-
790-
// FIXME: Support more complex patterns, including multiple selects.
791-
// The Select must be used only outside the loop and by the PHI.
792-
return InstDesc(I, RecurKind::FindLast);
793-
}
794-
795783
// Returns either FindFirstIV/FindLastIV, if such a pattern is found, or
796784
// std::nullopt.
797785
auto GetRecurKind = [&](Value *V) -> std::optional<RecurKind> {
@@ -805,8 +793,9 @@ RecurrenceDescriptor::isFindPattern(RecurKind Kind, Loop *TheLoop,
805793
m_SpecificLoop(TheLoop))))
806794
return std::nullopt;
807795

808-
if ((isFindFirstIVRecurrenceKind(Kind) && !SE.isKnownNegative(Step)) ||
809-
(isFindLastIVRecurrenceKind(Kind) && !SE.isKnownPositive(Step)))
796+
// We must have a known positive or negative step for FindIV
797+
const bool PositiveStep = SE.isKnownPositive(Step);
798+
if (!PositiveStep && !SE.isKnownNegative(Step))
810799
return std::nullopt;
811800

812801
// Check if the minimum (FindLast) or maximum (FindFirst) value of the
@@ -822,7 +811,7 @@ RecurrenceDescriptor::isFindPattern(RecurKind Kind, Loop *TheLoop,
822811
IsSigned ? SE.getSignedRange(AR) : SE.getUnsignedRange(AR);
823812
unsigned NumBits = Ty->getIntegerBitWidth();
824813
ConstantRange ValidRange = ConstantRange::getEmpty(NumBits);
825-
if (isFindLastIVRecurrenceKind(Kind)) {
814+
if (PositiveStep) {
826815
APInt Sentinel = IsSigned ? APInt::getSignedMinValue(NumBits)
827816
: APInt::getMinValue(NumBits);
828817
ValidRange = ConstantRange::getNonEmpty(Sentinel + 1, Sentinel);
@@ -836,26 +825,22 @@ RecurrenceDescriptor::isFindPattern(RecurKind Kind, Loop *TheLoop,
836825
APInt::getMinValue(NumBits), APInt::getMaxValue(NumBits) - 1);
837826
}
838827

839-
LLVM_DEBUG(dbgs() << "LV: "
840-
<< (isFindLastIVRecurrenceKind(Kind) ? "FindLastIV"
841-
: "FindFirstIV")
842-
<< " valid range is " << ValidRange
843-
<< ", and the range of " << *AR << " is " << IVRange
844-
<< "\n");
828+
LLVM_DEBUG(
829+
dbgs() << "LV: " << (PositiveStep ? "FindLastIV" : "FindFirstIV")
830+
<< " valid range is " << ValidRange << ", and the range of "
831+
<< *AR << " is " << IVRange << "\n");
845832

846833
// Ensure the induction variable does not wrap around by verifying that
847834
// its range is fully contained within the valid range.
848835
return ValidRange.contains(IVRange);
849836
};
850-
if (isFindLastIVRecurrenceKind(Kind)) {
837+
if (PositiveStep) {
851838
if (CheckRange(true))
852839
return RecurKind::FindLastIVSMax;
853840
if (CheckRange(false))
854841
return RecurKind::FindLastIVUMax;
855842
return std::nullopt;
856843
}
857-
assert(isFindFirstIVRecurrenceKind(Kind) &&
858-
"Kind must either be a FindLastIV or FindFirstIV");
859844

860845
if (CheckRange(true))
861846
return RecurKind::FindFirstIVSMin;
@@ -867,7 +852,8 @@ RecurrenceDescriptor::isFindPattern(RecurKind Kind, Loop *TheLoop,
867852
if (auto RK = GetRecurKind(NonRdxPhi))
868853
return InstDesc(I, *RK);
869854

870-
return InstDesc(false, I);
855+
// If the recurrence is not specific to an IV, return a generic FindLast.
856+
return InstDesc(I, RecurKind::FindLast);
871857
}
872858

873859
RecurrenceDescriptor::InstDesc
@@ -1001,8 +987,8 @@ RecurrenceDescriptor::InstDesc RecurrenceDescriptor::isRecurrenceInstr(
1001987
Kind == RecurKind::Add || Kind == RecurKind::Mul ||
1002988
Kind == RecurKind::Sub || Kind == RecurKind::AddChainWithSubs)
1003989
return isConditionalRdxPattern(I);
1004-
if ((isFindIVRecurrenceKind(Kind) || isFindLastRecurrenceKind(Kind)) && SE)
1005-
return isFindPattern(Kind, L, OrigPhi, I, *SE);
990+
if (isFindRecurrenceKind(Kind) && SE)
991+
return isFindPattern(L, OrigPhi, I, *SE);
1006992
[[fallthrough]];
1007993
case Instruction::FCmp:
1008994
case Instruction::ICmp:
@@ -1142,14 +1128,9 @@ bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop,
11421128
<< "\n");
11431129
return true;
11441130
}
1145-
if (AddReductionVar(Phi, RecurKind::FindLastIVSMax, TheLoop, FMF, RedDes, DB,
1146-
AC, DT, SE)) {
1147-
LLVM_DEBUG(dbgs() << "Found a FindLastIV reduction PHI." << *Phi << "\n");
1148-
return true;
1149-
}
1150-
if (AddReductionVar(Phi, RecurKind::FindFirstIVSMin, TheLoop, FMF, RedDes, DB,
1151-
AC, DT, SE)) {
1152-
LLVM_DEBUG(dbgs() << "Found a FindFirstIV reduction PHI." << *Phi << "\n");
1131+
if (AddReductionVar(Phi, RecurKind::FindLast, TheLoop, FMF, RedDes, DB, AC,
1132+
DT, SE)) {
1133+
LLVM_DEBUG(dbgs() << "Found a Find reduction PHI." << *Phi << "\n");
11531134
return true;
11541135
}
11551136
if (AddReductionVar(Phi, RecurKind::FMul, TheLoop, FMF, RedDes, DB, AC, DT,
@@ -1199,11 +1180,6 @@ bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop,
11991180
<< "\n");
12001181
return true;
12011182
}
1202-
if (AddReductionVar(Phi, RecurKind::FindLast, TheLoop, FMF, RedDes, DB, AC,
1203-
DT, SE)) {
1204-
LLVM_DEBUG(dbgs() << "Found a FindLast reduction PHI." << *Phi << "\n");
1205-
return true;
1206-
}
12071183
// Not a reduction of known type.
12081184
return false;
12091185
}
@@ -1329,7 +1305,6 @@ unsigned RecurrenceDescriptor::getOpcode(RecurKind Kind) {
13291305
case RecurKind::FMinimumNum:
13301306
return Instruction::FCmp;
13311307
case RecurKind::FindLast:
1332-
return Instruction::Select;
13331308
case RecurKind::AnyOf:
13341309
case RecurKind::FindFirstIVSMin:
13351310
case RecurKind::FindFirstIVUMin:

llvm/lib/Transforms/Utils/LoopUnroll.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,11 +1258,11 @@ llvm::canParallelizeReductionWhenUnrolling(PHINode &Phi, Loop *L,
12581258
return std::nullopt;
12591259
RecurKind RK = RdxDesc.getRecurrenceKind();
12601260
// Skip unsupported reductions.
1261-
// TODO: Handle additional reductions, including min-max reductions.
1261+
// TODO: Handle additional reductions, including FP and min-max
1262+
// reductions.
12621263
if (RecurrenceDescriptor::isAnyOfRecurrenceKind(RK) ||
1263-
RecurrenceDescriptor::isFindIVRecurrenceKind(RK) ||
1264-
RecurrenceDescriptor::isMinMaxRecurrenceKind(RK) ||
1265-
RecurrenceDescriptor::isFindLastRecurrenceKind(RK))
1264+
RecurrenceDescriptor::isFindRecurrenceKind(RK) ||
1265+
RecurrenceDescriptor::isMinMaxRecurrenceKind(RK))
12661266
return std::nullopt;
12671267

12681268
if (RdxDesc.hasExactFPMath())

llvm/lib/Transforms/Utils/LoopUtils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1491,7 +1491,7 @@ Value *llvm::createSimpleReduction(IRBuilderBase &Builder, Value *Src,
14911491
Value *llvm::createSimpleReduction(IRBuilderBase &Builder, Value *Src,
14921492
RecurKind Kind, Value *Mask, Value *EVL) {
14931493
assert(!RecurrenceDescriptor::isAnyOfRecurrenceKind(Kind) &&
1494-
!RecurrenceDescriptor::isFindIVRecurrenceKind(Kind) &&
1494+
!RecurrenceDescriptor::isFindRecurrenceKind(Kind) &&
14951495
"AnyOf and FindIV reductions are not supported.");
14961496
Intrinsic::ID Id = getReductionIntrinsicID(Kind);
14971497
auto VPID = VPIntrinsic::getForIntrinsic(Id);

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4617,10 +4617,12 @@ LoopVectorizationPlanner::selectInterleaveCount(VPlan &Plan, ElementCount VF,
46174617
IsaPred<VPReductionPHIRecipe>);
46184618

46194619
// FIXME: implement interleaving for FindLast transform correctly.
4620-
for (auto &[_, RdxDesc] : Legal->getReductionVars())
4621-
if (RecurrenceDescriptor::isFindLastRecurrenceKind(
4622-
RdxDesc.getRecurrenceKind()))
4623-
return 1;
4620+
if (any_of(make_second_range(Legal->getReductionVars()),
4621+
[](const RecurrenceDescriptor &RdxDesc) {
4622+
return RecurrenceDescriptor::isFindLastRecurrenceKind(
4623+
RdxDesc.getRecurrenceKind());
4624+
}))
4625+
return 1;
46244626

46254627
// If we did not calculate the cost for VF (because the user selected the VF)
46264628
// then we calculate the cost of VF here.

0 commit comments

Comments
 (0)