@@ -50,6 +50,7 @@ bool RecurrenceDescriptor::isIntegerRecurrenceKind(RecurKind Kind) {
50
50
case RecurKind::UMax:
51
51
case RecurKind::UMin:
52
52
case RecurKind::AnyOf:
53
+ case RecurKind::FindFirstIVSMin:
53
54
case RecurKind::FindLastIVSMax:
54
55
case RecurKind::FindLastIVUMax:
55
56
return true ;
@@ -684,8 +685,9 @@ RecurrenceDescriptor::isAnyOfPattern(Loop *Loop, PHINode *OrigPhi,
684
685
// value of the data type or a non-constant value by using mask and multiple
685
686
// reduction operations.
686
687
RecurrenceDescriptor::InstDesc
687
- RecurrenceDescriptor::isFindLastIVPattern (Loop *TheLoop, PHINode *OrigPhi,
688
- Instruction *I, ScalarEvolution &SE) {
688
+ RecurrenceDescriptor::isFindIVPattern (RecurKind Kind, Loop *TheLoop,
689
+ PHINode *OrigPhi, Instruction *I,
690
+ ScalarEvolution &SE) {
689
691
// TODO: Support the vectorization of FindLastIV when the reduction phi is
690
692
// used by more than one select instruction. This vectorization is only
691
693
// performed when the SCEV of each increasing induction variable used by the
@@ -713,36 +715,61 @@ RecurrenceDescriptor::isFindLastIVPattern(Loop *TheLoop, PHINode *OrigPhi,
713
715
return std::nullopt;
714
716
715
717
const SCEV *Step = AR->getStepRecurrence (SE);
716
- if (!SE.isKnownPositive (Step))
718
+ if ((isFindFirstIVRecurrenceKind (Kind) && !SE.isKnownNegative (Step)) ||
719
+ (isFindLastIVRecurrenceKind (Kind) && !SE.isKnownPositive (Step)))
717
720
return std::nullopt;
718
721
719
722
// Keep the minimum value of the recurrence type as the sentinel value.
720
723
// The maximum acceptable range for the increasing induction variable,
721
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
722
729
// [<sentinel value> + 1, <sentinel value>)
723
- // where <sentinel value> is [Signed|Unsigned]Min(<recurrence type>)
730
+ // where <sentinel value> is [Signed|Unsigned]Min(<recurrence type>) for
731
+ // FindLastIV or [Signed|Unsigned]Max(<recurrence type>) for FindFirstIV.
724
732
// TODO: This range restriction can be lifted by adding an additional
725
733
// virtual OR reduction.
726
734
auto CheckRange = [&](bool IsSigned) {
727
735
const ConstantRange IVRange =
728
736
IsSigned ? SE.getSignedRange (AR) : SE.getUnsignedRange (AR);
729
737
unsigned NumBits = Ty->getIntegerBitWidth ();
730
- const APInt Sentinel = IsSigned ? APInt::getSignedMinValue (NumBits)
731
- : APInt::getMinValue (NumBits);
732
- const ConstantRange ValidRange =
733
- ConstantRange::getNonEmpty (Sentinel + 1 , Sentinel);
734
- LLVM_DEBUG (dbgs () << " LV: FindLastIV valid range is " << ValidRange
738
+ ConstantRange ValidRange = ConstantRange::getEmpty (NumBits);
739
+ if (isFindLastIVRecurrenceKind (Kind)) {
740
+ APInt Sentinel = IsSigned ? APInt::getSignedMinValue (NumBits)
741
+ : APInt::getMinValue (NumBits);
742
+ ValidRange = ConstantRange::getNonEmpty (Sentinel + 1 , Sentinel);
743
+ } else {
744
+ assert (IsSigned && " Only FindFirstIV with SMax is supported currently" );
745
+ ValidRange =
746
+ ConstantRange::getNonEmpty (APInt::getSignedMinValue (NumBits),
747
+ APInt::getSignedMaxValue (NumBits) - 1 );
748
+ }
749
+
750
+ LLVM_DEBUG (dbgs () << " LV: "
751
+ << (isFindLastIVRecurrenceKind (Kind) ? " FindLastIV"
752
+ : " FindFirstIV" )
753
+ << " valid range is " << ValidRange
735
754
<< " , and the range of " << *AR << " is " << IVRange
736
755
<< " \n " );
737
756
738
757
// Ensure the induction variable does not wrap around by verifying that
739
758
// its range is fully contained within the valid range.
740
759
return ValidRange.contains (IVRange);
741
760
};
761
+ if (isFindLastIVRecurrenceKind (Kind)) {
762
+ if (CheckRange (true ))
763
+ return RecurKind::FindLastIVSMax;
764
+ if (CheckRange (false ))
765
+ return RecurKind::FindLastIVUMax;
766
+ return std::nullopt;
767
+ }
768
+ assert (isFindFirstIVRecurrenceKind (Kind) &&
769
+ " Kind must either be a FindLastIV or FindFirstIV" );
770
+
742
771
if (CheckRange (true ))
743
- return RecurKind::FindLastIVSMax;
744
- if (CheckRange (false ))
745
- return RecurKind::FindLastIVUMax;
772
+ return RecurKind::FindFirstIVSMin;
746
773
return std::nullopt;
747
774
};
748
775
@@ -888,8 +915,8 @@ RecurrenceDescriptor::InstDesc RecurrenceDescriptor::isRecurrenceInstr(
888
915
if (Kind == RecurKind::FAdd || Kind == RecurKind::FMul ||
889
916
Kind == RecurKind::Add || Kind == RecurKind::Mul)
890
917
return isConditionalRdxPattern (I);
891
- if (isFindLastIVRecurrenceKind (Kind) && SE)
892
- return isFindLastIVPattern ( L, OrigPhi, I, *SE);
918
+ if (isFindIVRecurrenceKind (Kind) && SE)
919
+ return isFindIVPattern (Kind, L, OrigPhi, I, *SE);
893
920
[[fallthrough]];
894
921
case Instruction::FCmp:
895
922
case Instruction::ICmp:
@@ -1003,6 +1030,11 @@ bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop,
1003
1030
LLVM_DEBUG (dbgs () << " Found a FindLastIV reduction PHI." << *Phi << " \n " );
1004
1031
return true ;
1005
1032
}
1033
+ if (AddReductionVar (Phi, RecurKind::FindFirstIVSMin, TheLoop, FMF, RedDes, DB,
1034
+ AC, DT, SE)) {
1035
+ LLVM_DEBUG (dbgs () << " Found a FindFirstIV reduction PHI." << *Phi << " \n " );
1036
+ return true ;
1037
+ }
1006
1038
if (AddReductionVar (Phi, RecurKind::FMul, TheLoop, FMF, RedDes, DB, AC, DT,
1007
1039
SE)) {
1008
1040
LLVM_DEBUG (dbgs () << " Found an FMult reduction PHI." << *Phi << " \n " );
@@ -1150,6 +1182,7 @@ unsigned RecurrenceDescriptor::getOpcode(RecurKind Kind) {
1150
1182
case RecurKind::Mul:
1151
1183
return Instruction::Mul;
1152
1184
case RecurKind::AnyOf:
1185
+ case RecurKind::FindFirstIVSMin:
1153
1186
case RecurKind::FindLastIVSMax:
1154
1187
case RecurKind::FindLastIVUMax:
1155
1188
case RecurKind::Or:
0 commit comments