@@ -51,6 +51,7 @@ bool RecurrenceDescriptor::isIntegerRecurrenceKind(RecurKind Kind) {
5151 case RecurKind::UMin:
5252 case RecurKind::AnyOf:
5353 case RecurKind::FindFirstIVSMin:
54+ case RecurKind::FindFirstIVUMin:
5455 case RecurKind::FindLastIVSMax:
5556 case RecurKind::FindLastIVUMax:
5657 return true ;
@@ -663,9 +664,9 @@ RecurrenceDescriptor::isAnyOfPattern(Loop *Loop, PHINode *OrigPhi,
663664// if (src[i] > 3)
664665// r = i;
665666// }
666- // The reduction value (r) is derived from either the values of an increasing
667- // induction variable (i) sequence, or from the start value (0).
668- // The LLVM IR generated for such loops would be as follows:
667+ // The reduction value (r) is derived from either the values of an induction
668+ // variable (i) sequence, or from the start value (0). The LLVM IR generated for
669+ // such loops would be as follows:
669670// for.body:
670671// %r = phi i32 [ %spec.select, %for.body ], [ 0, %entry ]
671672// %i = phi i32 [ %inc, %for.body ], [ 0, %entry ]
@@ -674,13 +675,16 @@ RecurrenceDescriptor::isAnyOfPattern(Loop *Loop, PHINode *OrigPhi,
674675// %spec.select = select i1 %cmp, i32 %i, i32 %r
675676// %inc = add nsw i32 %i, 1
676677// ...
677- // Since 'i' is an increasing induction variable, the reduction value after the
678- // loop will be the maximum value of 'i' that the condition (src[i] > 3) is
679- // satisfied, or the start value (0 in the example above). When the start value
680- // of the increasing induction variable 'i' is greater than the minimum value of
681- // the data type, we can use the minimum value of the data type as a sentinel
682- // value to replace the start value. This allows us to perform a single
683- // reduction max operation to obtain the final reduction result.
678+ // Since 'i' is an induction variable, the reduction value after the loop will
679+ // be the maximum (increasing induction) or minimum (decreasing induction) value
680+ // of 'i' that the condition (src[i] > 3) is satisfied, or the start value (0 in
681+ // the example above). When the start value of the induction variable 'i' is
682+ // greater than the minimum (increasing induction) or maximum (decreasing
683+ // induction) value of the data type, we can use the minimum (increasing
684+ // induction) or maximum (decreasing induction) value of the data type as a
685+ // sentinel value to replace the start value. This allows us to perform a single
686+ // reduction max (increasing induction) or min (decreasing induction) operation
687+ // to obtain the final reduction result.
684688// TODO: It is possible to solve the case where the start value is the minimum
685689// value of the data type or a non-constant value by using mask and multiple
686690// reduction operations.
@@ -695,6 +699,9 @@ RecurrenceDescriptor::isFindIVPattern(RecurKind Kind, Loop *TheLoop,
695699 if (!OrigPhi->hasOneUse ())
696700 return InstDesc (false , I);
697701
702+ // We are looking for selects of the form:
703+ // select(cmp(), phi, loop_induction) or
704+ // select(cmp(), loop_induction, phi)
698705 // TODO: Match selects with multi-use cmp conditions.
699706 Value *NonRdxPhi = nullptr ;
700707 if (!match (I, m_CombineOr (m_Select (m_OneUse (m_Cmp ()), m_Value (NonRdxPhi),
@@ -703,8 +710,8 @@ RecurrenceDescriptor::isFindIVPattern(RecurKind Kind, Loop *TheLoop,
703710 m_Value (NonRdxPhi)))))
704711 return InstDesc (false , I);
705712
706- // Returns a non-nullopt boolean indicating the signedness of the recurrence
707- // when a valid FindLastIV pattern is found .
713+ // Returns either FindFirstIV/FindLastIV, if such a pattern is found, or
714+ // std::nullopt .
708715 auto GetRecurKind = [&](Value *V) -> std::optional<RecurKind> {
709716 Type *Ty = V->getType ();
710717 if (!SE.isSCEVable (Ty))
@@ -719,16 +726,12 @@ RecurrenceDescriptor::isFindIVPattern(RecurKind Kind, Loop *TheLoop,
719726 (isFindLastIVRecurrenceKind (Kind) && !SE.isKnownPositive (Step)))
720727 return std::nullopt ;
721728
722- // Keep the minimum value of the recurrence type as the sentinel value.
723- // The maximum acceptable range for the increasing induction variable,
724- // called the valid range, will be defined as
725-
726- // Keep the minimum (FindLast) or maximum (FindFirst) value of the
727- // recurrence type as the sentinel value. The maximum acceptable range for
728- // the induction variable, called the valid range, will be defined as
729- // [<sentinel value> + 1, <sentinel value>)
730- // where <sentinel value> is [Signed|Unsigned]Min(<recurrence type>) for
731- // FindLastIV or [Signed|Unsigned]Max(<recurrence type>) for FindFirstIV.
729+ // Check if the minimum (FindLast) or maximum (FindFirst) value of the
730+ // recurrence type can be used as a sentinel value. The maximum acceptable
731+ // range for the induction variable, called the valid range will exclude
732+ // <sentinel value>, where <sentinel value> is
733+ // [Signed|Unsigned]Min(<recurrence type>) for FindLastIV or
734+ // [Signed|Unsigned]Max(<recurrence type>) for FindFirstIV.
732735 // TODO: This range restriction can be lifted by adding an additional
733736 // virtual OR reduction.
734737 auto CheckRange = [&](bool IsSigned) {
@@ -741,10 +744,13 @@ RecurrenceDescriptor::isFindIVPattern(RecurKind Kind, Loop *TheLoop,
741744 : APInt::getMinValue (NumBits);
742745 ValidRange = ConstantRange::getNonEmpty (Sentinel + 1 , Sentinel);
743746 } else {
744- assert (IsSigned && " Only FindFirstIV with SMax is supported currently" );
745- ValidRange =
746- ConstantRange::getNonEmpty (APInt::getSignedMinValue (NumBits),
747- APInt::getSignedMaxValue (NumBits) - 1 );
747+ if (IsSigned)
748+ ValidRange =
749+ ConstantRange::getNonEmpty (APInt::getSignedMinValue (NumBits),
750+ APInt::getSignedMaxValue (NumBits) - 1 );
751+ else
752+ ValidRange = ConstantRange::getNonEmpty (
753+ APInt::getMinValue (NumBits), APInt::getMaxValue (NumBits) - 1 );
748754 }
749755
750756 LLVM_DEBUG (dbgs () << " LV: "
@@ -770,13 +776,11 @@ RecurrenceDescriptor::isFindIVPattern(RecurKind Kind, Loop *TheLoop,
770776
771777 if (CheckRange (true ))
772778 return RecurKind::FindFirstIVSMin;
779+ if (CheckRange (false ))
780+ return RecurKind::FindFirstIVUMin;
773781 return std::nullopt ;
774782 };
775783
776- // We are looking for selects of the form:
777- // select(cmp(), phi, increasing_loop_induction) or
778- // select(cmp(), increasing_loop_induction, phi)
779- // TODO: Support for monotonically decreasing induction variable
780784 if (auto RK = GetRecurKind (NonRdxPhi))
781785 return InstDesc (I, *RK);
782786
@@ -1183,6 +1187,7 @@ unsigned RecurrenceDescriptor::getOpcode(RecurKind Kind) {
11831187 return Instruction::Mul;
11841188 case RecurKind::AnyOf:
11851189 case RecurKind::FindFirstIVSMin:
1190+ case RecurKind::FindFirstIVUMin:
11861191 case RecurKind::FindLastIVSMax:
11871192 case RecurKind::FindLastIVUMax:
11881193 case RecurKind::Or:
0 commit comments