@@ -51,6 +51,7 @@ bool RecurrenceDescriptor::isIntegerRecurrenceKind(RecurKind Kind) {
51
51
case RecurKind::UMin:
52
52
case RecurKind::AnyOf:
53
53
case RecurKind::FindFirstIVSMin:
54
+ case RecurKind::FindFirstIVUMin:
54
55
case RecurKind::FindLastIVSMax:
55
56
case RecurKind::FindLastIVUMax:
56
57
return true ;
@@ -663,9 +664,9 @@ RecurrenceDescriptor::isAnyOfPattern(Loop *Loop, PHINode *OrigPhi,
663
664
// if (src[i] > 3)
664
665
// r = i;
665
666
// }
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:
669
670
// for.body:
670
671
// %r = phi i32 [ %spec.select, %for.body ], [ 0, %entry ]
671
672
// %i = phi i32 [ %inc, %for.body ], [ 0, %entry ]
@@ -674,13 +675,16 @@ RecurrenceDescriptor::isAnyOfPattern(Loop *Loop, PHINode *OrigPhi,
674
675
// %spec.select = select i1 %cmp, i32 %i, i32 %r
675
676
// %inc = add nsw i32 %i, 1
676
677
// ...
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.
684
688
// TODO: It is possible to solve the case where the start value is the minimum
685
689
// value of the data type or a non-constant value by using mask and multiple
686
690
// reduction operations.
@@ -695,6 +699,9 @@ RecurrenceDescriptor::isFindIVPattern(RecurKind Kind, Loop *TheLoop,
695
699
if (!OrigPhi->hasOneUse ())
696
700
return InstDesc (false , I);
697
701
702
+ // We are looking for selects of the form:
703
+ // select(cmp(), phi, loop_induction) or
704
+ // select(cmp(), loop_induction, phi)
698
705
// TODO: Match selects with multi-use cmp conditions.
699
706
Value *NonRdxPhi = nullptr ;
700
707
if (!match (I, m_CombineOr (m_Select (m_OneUse (m_Cmp ()), m_Value (NonRdxPhi),
@@ -703,8 +710,8 @@ RecurrenceDescriptor::isFindIVPattern(RecurKind Kind, Loop *TheLoop,
703
710
m_Value (NonRdxPhi)))))
704
711
return InstDesc (false , I);
705
712
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 .
708
715
auto GetRecurKind = [&](Value *V) -> std::optional<RecurKind> {
709
716
Type *Ty = V->getType ();
710
717
if (!SE.isSCEVable (Ty))
@@ -719,16 +726,12 @@ RecurrenceDescriptor::isFindIVPattern(RecurKind Kind, Loop *TheLoop,
719
726
(isFindLastIVRecurrenceKind (Kind) && !SE.isKnownPositive (Step)))
720
727
return std::nullopt;
721
728
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.
732
735
// TODO: This range restriction can be lifted by adding an additional
733
736
// virtual OR reduction.
734
737
auto CheckRange = [&](bool IsSigned) {
@@ -741,10 +744,13 @@ RecurrenceDescriptor::isFindIVPattern(RecurKind Kind, Loop *TheLoop,
741
744
: APInt::getMinValue (NumBits);
742
745
ValidRange = ConstantRange::getNonEmpty (Sentinel + 1 , Sentinel);
743
746
} 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 );
748
754
}
749
755
750
756
LLVM_DEBUG (dbgs () << " LV: "
@@ -770,13 +776,11 @@ RecurrenceDescriptor::isFindIVPattern(RecurKind Kind, Loop *TheLoop,
770
776
771
777
if (CheckRange (true ))
772
778
return RecurKind::FindFirstIVSMin;
779
+ if (CheckRange (false ))
780
+ return RecurKind::FindFirstIVUMin;
773
781
return std::nullopt;
774
782
};
775
783
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
780
784
if (auto RK = GetRecurKind (NonRdxPhi))
781
785
return InstDesc (I, *RK);
782
786
@@ -1183,6 +1187,7 @@ unsigned RecurrenceDescriptor::getOpcode(RecurKind Kind) {
1183
1187
return Instruction::Mul;
1184
1188
case RecurKind::AnyOf:
1185
1189
case RecurKind::FindFirstIVSMin:
1190
+ case RecurKind::FindFirstIVUMin:
1186
1191
case RecurKind::FindLastIVSMax:
1187
1192
case RecurKind::FindLastIVUMax:
1188
1193
case RecurKind::Or:
0 commit comments