@@ -614,6 +614,27 @@ Value *VPInstruction::generate(VPTransformState &State) {
614
614
return Builder.CreateVectorSplat (
615
615
State.VF , State.get (getOperand (0 ), /* IsScalar*/ true ), " broadcast" );
616
616
}
617
+ case VPInstruction::ComputeFindLastIVResult: {
618
+ // The recipe's operands are the reduction phi, followed by one operand for
619
+ // each part of the reduction.
620
+ unsigned UF = getNumOperands () - 1 ;
621
+ Value *ReducedPartRdx = State.get (getOperand (1 ));
622
+ for (unsigned Part = 1 ; Part < UF; ++Part) {
623
+ ReducedPartRdx = createMinMaxOp (Builder, RecurKind::SMax, ReducedPartRdx,
624
+ State.get (getOperand (1 + Part)));
625
+ }
626
+
627
+ // FIXME: The cross-recipe dependency on VPReductionPHIRecipe is temporary
628
+ // and will be removed by breaking up the recipe further.
629
+ auto *PhiR = cast<VPReductionPHIRecipe>(getOperand (0 ));
630
+ // Get its reduction variable descriptor.
631
+ const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor ();
632
+ RecurKind RK = RdxDesc.getRecurrenceKind ();
633
+
634
+ assert (RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK));
635
+ assert (!PhiR->isInLoop ());
636
+ return createFindLastIVReduction (Builder, ReducedPartRdx, RdxDesc);
637
+ }
617
638
case VPInstruction::ComputeReductionResult: {
618
639
// FIXME: The cross-recipe dependency on VPReductionPHIRecipe is temporary
619
640
// and will be removed by breaking up the recipe further.
@@ -623,6 +644,8 @@ Value *VPInstruction::generate(VPTransformState &State) {
623
644
const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor ();
624
645
625
646
RecurKind RK = RdxDesc.getRecurrenceKind ();
647
+ assert (!RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK) &&
648
+ " should be handled by ComputeFindLastIVResult" );
626
649
627
650
Type *PhiTy = OrigPhi->getType ();
628
651
// The recipe's operands are the reduction phi, followed by one operand for
@@ -658,9 +681,6 @@ Value *VPInstruction::generate(VPTransformState &State) {
658
681
if (Op != Instruction::ICmp && Op != Instruction::FCmp)
659
682
ReducedPartRdx = Builder.CreateBinOp (
660
683
(Instruction::BinaryOps)Op, RdxPart, ReducedPartRdx, " bin.rdx" );
661
- else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK))
662
- ReducedPartRdx =
663
- createMinMaxOp (Builder, RecurKind::SMax, ReducedPartRdx, RdxPart);
664
684
else
665
685
ReducedPartRdx = createMinMaxOp (Builder, RK, ReducedPartRdx, RdxPart);
666
686
}
@@ -669,8 +689,7 @@ Value *VPInstruction::generate(VPTransformState &State) {
669
689
// Create the reduction after the loop. Note that inloop reductions create
670
690
// the target reduction in the loop using a Reduction recipe.
671
691
if ((State.VF .isVector () ||
672
- RecurrenceDescriptor::isAnyOfRecurrenceKind (RK) ||
673
- RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK)) &&
692
+ RecurrenceDescriptor::isAnyOfRecurrenceKind (RK)) &&
674
693
!PhiR->isInLoop ()) {
675
694
// TODO: Support in-order reductions based on the recurrence descriptor.
676
695
// All ops in the reduction inherit fast-math-flags from the recurrence
@@ -681,9 +700,6 @@ Value *VPInstruction::generate(VPTransformState &State) {
681
700
if (RecurrenceDescriptor::isAnyOfRecurrenceKind (RK))
682
701
ReducedPartRdx =
683
702
createAnyOfReduction (Builder, ReducedPartRdx, RdxDesc, OrigPhi);
684
- else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK))
685
- ReducedPartRdx =
686
- createFindLastIVReduction (Builder, ReducedPartRdx, RdxDesc);
687
703
else
688
704
ReducedPartRdx = createSimpleReduction (Builder, ReducedPartRdx, RK);
689
705
@@ -829,6 +845,7 @@ bool VPInstruction::isVectorToScalar() const {
829
845
return getOpcode () == VPInstruction::ExtractFromEnd ||
830
846
getOpcode () == Instruction::ExtractElement ||
831
847
getOpcode () == VPInstruction::FirstActiveLane ||
848
+ getOpcode () == VPInstruction::ComputeFindLastIVResult ||
832
849
getOpcode () == VPInstruction::ComputeReductionResult ||
833
850
getOpcode () == VPInstruction::AnyOf;
834
851
}
@@ -1011,6 +1028,9 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
1011
1028
case VPInstruction::ExtractFromEnd:
1012
1029
O << " extract-from-end" ;
1013
1030
break ;
1031
+ case VPInstruction::ComputeFindLastIVResult:
1032
+ O << " compute-find-last-iv-result" ;
1033
+ break ;
1014
1034
case VPInstruction::ComputeReductionResult:
1015
1035
O << " compute-reduction-result" ;
1016
1036
break ;
0 commit comments