@@ -7485,6 +7485,13 @@ static void addRuntimeUnrollDisableMetaData(Loop *L) {
74857485 }
74867486}
74877487
7488+ static Value *getStartValueFromReductionResult (VPInstruction *RdxResult) {
7489+ using namespace VPlanPatternMatch ;
7490+ VPValue *StartVPV = RdxResult->getOperand (1 );
7491+ match (StartVPV, m_Freeze (m_VPValue (StartVPV)));
7492+ return StartVPV->getLiveInIRValue ();
7493+ }
7494+
74887495// If \p R is a ComputeReductionResult when vectorizing the epilog loop,
74897496// fix the reduction's scalar PHI node by adding the incoming value from the
74907497// main vector loop.
@@ -7493,7 +7500,8 @@ static void fixReductionScalarResumeWhenVectorizingEpilog(
74937500 BasicBlock *BypassBlock) {
74947501 auto *EpiRedResult = dyn_cast<VPInstruction>(R);
74957502 if (!EpiRedResult ||
7496- (EpiRedResult->getOpcode () != VPInstruction::ComputeReductionResult &&
7503+ (EpiRedResult->getOpcode () != VPInstruction::ComputeAnyOfResult &&
7504+ EpiRedResult->getOpcode () != VPInstruction::ComputeReductionResult &&
74977505 EpiRedResult->getOpcode () != VPInstruction::ComputeFindLastIVResult))
74987506 return ;
74997507
@@ -7505,15 +7513,19 @@ static void fixReductionScalarResumeWhenVectorizingEpilog(
75057513 EpiRedHeaderPhi->getStartValue ()->getUnderlyingValue ();
75067514 if (RecurrenceDescriptor::isAnyOfRecurrenceKind (
75077515 RdxDesc.getRecurrenceKind ())) {
7516+ Value *StartV = EpiRedResult->getOperand (1 )->getLiveInIRValue ();
7517+ (void )StartV;
75087518 auto *Cmp = cast<ICmpInst>(MainResumeValue);
75097519 assert (Cmp->getPredicate () == CmpInst::ICMP_NE &&
75107520 " AnyOf expected to start with ICMP_NE" );
7511- assert (Cmp->getOperand (1 ) == RdxDesc. getRecurrenceStartValue () &&
7521+ assert (Cmp->getOperand (1 ) == StartV &&
75127522 " AnyOf expected to start by comparing main resume value to original "
75137523 " start value" );
75147524 MainResumeValue = Cmp->getOperand (0 );
75157525 } else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind (
75167526 RdxDesc.getRecurrenceKind ())) {
7527+ Value *StartV = getStartValueFromReductionResult (EpiRedResult);
7528+ (void )StartV;
75177529 using namespace llvm ::PatternMatch;
75187530 Value *Cmp, *OrigResumeV, *CmpOp;
75197531 bool IsExpectedPattern =
@@ -7522,10 +7534,7 @@ static void fixReductionScalarResumeWhenVectorizingEpilog(
75227534 m_Value (OrigResumeV))) &&
75237535 (match (Cmp, m_SpecificICmp (ICmpInst::ICMP_EQ, m_Specific (OrigResumeV),
75247536 m_Value (CmpOp))) &&
7525- (match (CmpOp,
7526- m_Freeze (m_Specific (RdxDesc.getRecurrenceStartValue ()))) ||
7527- (CmpOp == RdxDesc.getRecurrenceStartValue () &&
7528- isGuaranteedNotToBeUndefOrPoison (CmpOp))));
7537+ ((CmpOp == StartV && isGuaranteedNotToBeUndefOrPoison (CmpOp))));
75297538 assert (IsExpectedPattern && " Unexpected reduction resume pattern" );
75307539 (void )IsExpectedPattern;
75317540 MainResumeValue = OrigResumeV;
@@ -9467,7 +9476,10 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
94679476 OrigExitingVPV->replaceUsesWithIf (NewExitingVPV, [](VPUser &U, unsigned ) {
94689477 return isa<VPInstruction>(&U) &&
94699478 (cast<VPInstruction>(&U)->getOpcode () ==
9479+ VPInstruction::ComputeAnyOfResult ||
9480+ cast<VPInstruction>(&U)->getOpcode () ==
94709481 VPInstruction::ComputeReductionResult ||
9482+
94719483 cast<VPInstruction>(&U)->getOpcode () ==
94729484 VPInstruction::ComputeFindLastIVResult);
94739485 });
@@ -9497,6 +9509,12 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
94979509 FinalReductionResult =
94989510 Builder.createNaryOp (VPInstruction::ComputeFindLastIVResult,
94999511 {PhiR, Start, NewExitingVPV}, ExitDL);
9512+ } else if (RecurrenceDescriptor::isAnyOfRecurrenceKind (
9513+ RdxDesc.getRecurrenceKind ())) {
9514+ VPValue *Start = PhiR->getStartValue ();
9515+ FinalReductionResult =
9516+ Builder.createNaryOp (VPInstruction::ComputeAnyOfResult,
9517+ {PhiR, Start, NewExitingVPV}, ExitDL);
95009518 } else {
95019519 VPIRFlags Flags = RecurrenceDescriptor::isFloatingPointRecurrenceKind (
95029520 RdxDesc.getRecurrenceKind ())
@@ -10050,23 +10068,36 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
1005010068 Value *ResumeV = nullptr ;
1005110069 // TODO: Move setting of resume values to prepareToExecute.
1005210070 if (auto *ReductionPhi = dyn_cast<VPReductionPHIRecipe>(&R)) {
10071+ auto *RdxResult =
10072+ cast<VPInstruction>(*find_if (ReductionPhi->users (), [](VPUser *U) {
10073+ auto *VPI = dyn_cast<VPInstruction>(U);
10074+ return VPI &&
10075+ (VPI->getOpcode () == VPInstruction::ComputeReductionResult ||
10076+ VPI->getOpcode () == VPInstruction::ComputeFindLastIVResult);
10077+ }));
1005310078 ResumeV = cast<PHINode>(ReductionPhi->getUnderlyingInstr ())
1005410079 ->getIncomingValueForBlock (L->getLoopPreheader ());
1005510080 const RecurrenceDescriptor &RdxDesc =
1005610081 ReductionPhi->getRecurrenceDescriptor ();
1005710082 RecurKind RK = RdxDesc.getRecurrenceKind ();
1005810083 if (RecurrenceDescriptor::isAnyOfRecurrenceKind (RK)) {
10084+ Value *StartV = RdxResult->getOperand (1 )->getLiveInIRValue ();
10085+ assert (RdxDesc.getRecurrenceStartValue () == StartV &&
10086+ " start value from ComputeAnyOfResult must match" );
10087+
1005910088 // VPReductionPHIRecipes for AnyOf reductions expect a boolean as
1006010089 // start value; compare the final value from the main vector loop
1006110090 // to the start value.
1006210091 BasicBlock *PBB = cast<Instruction>(ResumeV)->getParent ();
1006310092 IRBuilder<> Builder (PBB, PBB->getFirstNonPHIIt ());
10064- ResumeV =
10065- Builder.CreateICmpNE (ResumeV, RdxDesc.getRecurrenceStartValue ());
10093+ ResumeV = Builder.CreateICmpNE (ResumeV, StartV);
1006610094 } else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK)) {
10067- ToFrozen[RdxDesc.getRecurrenceStartValue ()] =
10068- cast<PHINode>(ResumeV)->getIncomingValueForBlock (
10069- EPI.MainLoopIterationCountCheck );
10095+ Value *StartV = getStartValueFromReductionResult (RdxResult);
10096+ assert (RdxDesc.getRecurrenceStartValue () == StartV &&
10097+ " start value from ComputeFindLastIVResult must match" );
10098+
10099+ ToFrozen[StartV] = cast<PHINode>(ResumeV)->getIncomingValueForBlock (
10100+ EPI.MainLoopIterationCountCheck );
1007010101
1007110102 // VPReductionPHIRecipe for FindLastIV reductions requires an adjustment
1007210103 // to the resume value. The resume value is adjusted to the sentinel
@@ -10076,8 +10107,7 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
1007610107 // variable.
1007710108 BasicBlock *ResumeBB = cast<Instruction>(ResumeV)->getParent ();
1007810109 IRBuilder<> Builder (ResumeBB, ResumeBB->getFirstNonPHIIt ());
10079- Value *Cmp = Builder.CreateICmpEQ (
10080- ResumeV, ToFrozen[RdxDesc.getRecurrenceStartValue ()]);
10110+ Value *Cmp = Builder.CreateICmpEQ (ResumeV, ToFrozen[StartV]);
1008110111 ResumeV =
1008210112 Builder.CreateSelect (Cmp, RdxDesc.getSentinelValue (), ResumeV);
1008310113 }
0 commit comments