@@ -613,6 +613,29 @@ Value *VPInstruction::generate(VPTransformState &State) {
613613 return Builder.CreateVectorSplat (
614614 State.VF , State.get (getOperand (0 ), /* IsScalar*/ true ), " broadcast" );
615615 }
616+ case VPInstruction::ComputeFindLastIVResult: {
617+ // FIXME: The cross-recipe dependency on VPReductionPHIRecipe is temporary
618+ // and will be removed by breaking up the recipe further.
619+ auto *PhiR = cast<VPReductionPHIRecipe>(getOperand (0 ));
620+ // Get its reduction variable descriptor.
621+ const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor ();
622+ RecurKind RK = RdxDesc.getRecurrenceKind ();
623+ assert (RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK) &&
624+ " Unexpected reduction kind" );
625+ assert (!PhiR->isInLoop () &&
626+ " In-loop FindLastIV reduction is not supported yet" );
627+
628+ // The recipe's operands are the reduction phi, followed by one operand for
629+ // each part of the reduction.
630+ unsigned UF = getNumOperands () - 1 ;
631+ Value *ReducedPartRdx = State.get (getOperand (1 ));
632+ for (unsigned Part = 1 ; Part < UF; ++Part) {
633+ ReducedPartRdx = createMinMaxOp (Builder, RecurKind::SMax, ReducedPartRdx,
634+ State.get (getOperand (1 + Part)));
635+ }
636+
637+ return createFindLastIVReduction (Builder, ReducedPartRdx, RdxDesc);
638+ }
616639 case VPInstruction::ComputeReductionResult: {
617640 // FIXME: The cross-recipe dependency on VPReductionPHIRecipe is temporary
618641 // and will be removed by breaking up the recipe further.
@@ -622,6 +645,8 @@ Value *VPInstruction::generate(VPTransformState &State) {
622645 const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor ();
623646
624647 RecurKind RK = RdxDesc.getRecurrenceKind ();
648+ assert (!RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK) &&
649+ " should be handled by ComputeFindLastIVResult" );
625650
626651 Type *PhiTy = OrigPhi->getType ();
627652 // The recipe's operands are the reduction phi, followed by one operand for
@@ -657,9 +682,6 @@ Value *VPInstruction::generate(VPTransformState &State) {
657682 if (Op != Instruction::ICmp && Op != Instruction::FCmp)
658683 ReducedPartRdx = Builder.CreateBinOp (
659684 (Instruction::BinaryOps)Op, RdxPart, ReducedPartRdx, " bin.rdx" );
660- else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK))
661- ReducedPartRdx =
662- createMinMaxOp (Builder, RecurKind::SMax, ReducedPartRdx, RdxPart);
663685 else
664686 ReducedPartRdx = createMinMaxOp (Builder, RK, ReducedPartRdx, RdxPart);
665687 }
@@ -668,8 +690,7 @@ Value *VPInstruction::generate(VPTransformState &State) {
668690 // Create the reduction after the loop. Note that inloop reductions create
669691 // the target reduction in the loop using a Reduction recipe.
670692 if ((State.VF .isVector () ||
671- RecurrenceDescriptor::isAnyOfRecurrenceKind (RK) ||
672- RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK)) &&
693+ RecurrenceDescriptor::isAnyOfRecurrenceKind (RK)) &&
673694 !PhiR->isInLoop ()) {
674695 // TODO: Support in-order reductions based on the recurrence descriptor.
675696 // All ops in the reduction inherit fast-math-flags from the recurrence
@@ -680,9 +701,6 @@ Value *VPInstruction::generate(VPTransformState &State) {
680701 if (RecurrenceDescriptor::isAnyOfRecurrenceKind (RK))
681702 ReducedPartRdx =
682703 createAnyOfReduction (Builder, ReducedPartRdx, RdxDesc, OrigPhi);
683- else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK))
684- ReducedPartRdx =
685- createFindLastIVReduction (Builder, ReducedPartRdx, RdxDesc);
686704 else
687705 ReducedPartRdx = createSimpleReduction (Builder, ReducedPartRdx, RK);
688706
@@ -828,6 +846,7 @@ bool VPInstruction::isVectorToScalar() const {
828846 return getOpcode () == VPInstruction::ExtractFromEnd ||
829847 getOpcode () == Instruction::ExtractElement ||
830848 getOpcode () == VPInstruction::FirstActiveLane ||
849+ getOpcode () == VPInstruction::ComputeFindLastIVResult ||
831850 getOpcode () == VPInstruction::ComputeReductionResult ||
832851 getOpcode () == VPInstruction::AnyOf;
833852}
@@ -1010,6 +1029,9 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
10101029 case VPInstruction::ExtractFromEnd:
10111030 O << " extract-from-end" ;
10121031 break ;
1032+ case VPInstruction::ComputeFindLastIVResult:
1033+ O << " compute-find-last-iv-result" ;
1034+ break ;
10131035 case VPInstruction::ComputeReductionResult:
10141036 O << " compute-reduction-result" ;
10151037 break ;
0 commit comments