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