@@ -42,13 +42,9 @@ enum class RecurKind {
4242 And, // /< Bitwise or logical AND of integers.
4343 Xor, // /< Bitwise or logical XOR of integers.
4444 SMin, // /< Signed integer min implemented in terms of select(cmp()).
45- SMinMultiUse, // /< Signed integer min implemented in terms of select(cmp()).
4645 SMax, // /< Signed integer max implemented in terms of select(cmp()).
47- SMaxMultiUse, // /< Signed integer max implemented in terms of select(cmp()).
4846 UMin, // /< Unsigned integer min implemented in terms of select(cmp()).
49- UMinMultiUse, // /< Unsigned integer min implemented in terms of select(cmp()).
5047 UMax, // /< Unsigned integer max implemented in terms of select(cmp()).
51- UMaxMultiUse, // /< Unsigned integer max implemented in terms of select(cmp()).
5248 FAdd, // /< Sum of floats.
5349 FMul, // /< Product of floats.
5450 FMin, // /< FP min implemented in terms of select(cmp()).
@@ -99,12 +95,15 @@ class RecurrenceDescriptor {
9995 RecurKind K, FastMathFlags FMF, Instruction *ExactFP,
10096 Type *RT, bool Signed, bool Ordered,
10197 SmallPtrSetImpl<Instruction *> &CI,
102- unsigned MinWidthCastToRecurTy)
98+ unsigned MinWidthCastToRecurTy, bool PhiMultiUse = false )
10399 : IntermediateStore(Store), StartValue(Start), LoopExitInstr(Exit),
104100 Kind (K), FMF(FMF), ExactFPMathInst(ExactFP), RecurrenceType(RT),
105- IsSigned(Signed), IsOrdered(Ordered),
101+ IsSigned(Signed), IsOrdered(Ordered), IsPhiMultiUse(PhiMultiUse),
106102 MinWidthCastToRecurrenceType(MinWidthCastToRecurTy) {
107103 CastInsts.insert_range (CI);
104+ assert (
105+ (!PhiMultiUse || isMinMaxRecurrenceKind (K)) &&
106+ " Only min/max recurrences are allowed to have multiple uses currently" );
108107 }
109108
110109 // / This POD struct holds information about a potential recurrence operation.
@@ -251,26 +250,8 @@ class RecurrenceDescriptor {
251250
252251 // / Returns true if the recurrence kind is an integer min/max kind.
253252 static bool isIntMinMaxRecurrenceKind (RecurKind Kind) {
254- return Kind == RecurKind::UMin || Kind == RecurKind::UMinMultiUse ||
255- Kind == RecurKind::UMax || Kind == RecurKind::UMaxMultiUse ||
256- Kind == RecurKind::SMin || Kind == RecurKind::SMinMultiUse ||
257- Kind == RecurKind::SMax || Kind == RecurKind::SMaxMultiUse;
258- }
259-
260- static RecurKind convertFromMultiUseKind (RecurKind Kind) {
261- switch (Kind) {
262- case RecurKind::UMaxMultiUse:
263- return RecurKind::UMax;
264- case RecurKind::UMinMultiUse:
265- return RecurKind::UMin;
266- case RecurKind::SMinMultiUse:
267- return RecurKind::SMin;
268- case RecurKind::SMaxMultiUse:
269- return RecurKind::SMax;
270- default :
271- return Kind;
272- }
273- llvm_unreachable (" all cases must be handled above" );
253+ return Kind == RecurKind::UMin || Kind == RecurKind::UMax ||
254+ Kind == RecurKind::SMin || Kind == RecurKind::SMax;
274255 }
275256
276257 // / Returns true if the recurrence kind is a floating-point minnum/maxnum
@@ -361,6 +342,10 @@ class RecurrenceDescriptor {
361342 // / Expose an ordered FP reduction to the instance users.
362343 bool isOrdered () const { return IsOrdered; }
363344
345+ // / Returns true if the reduction PHI has multiple in-loop users. This is
346+ // / relevant for min/max reductions that are part of a FindLastIV pattern.
347+ bool isPhiMultiUse () const { return IsPhiMultiUse; }
348+
364349 // / Attempts to find a chain of operations from Phi to LoopExitInst that can
365350 // / be treated as a set of reductions instructions for in-loop reductions.
366351 LLVM_ABI SmallVector<Instruction *, 4 > getReductionOpChain (PHINode *Phi,
@@ -398,6 +383,9 @@ class RecurrenceDescriptor {
398383 // Currently only a non-reassociative FAdd can be considered in-order,
399384 // if it is also the only FAdd in the PHI's use chain.
400385 bool IsOrdered = false ;
386+ // True if the reduction PHI has multiple in-loop users. This is relevant
387+ // for min/max reductions that are part of a FindLastIV pattern.
388+ bool IsPhiMultiUse = false ;
401389 // Instructions used for type-promoting the recurrence.
402390 SmallPtrSet<Instruction *, 8 > CastInsts;
403391 // The minimum width used by the recurrence.
0 commit comments