@@ -7563,28 +7563,33 @@ static void addRuntimeUnrollDisableMetaData(Loop *L) {
75637563}
75647564
75657565// If \p R is a ComputeReductionResult when vectorizing the epilog loop,
7566- // update the reduction's scalar PHI node by adding the incoming value from the
7566+ // fix the reduction's scalar PHI node by adding the incoming value from the
75677567// main vector loop.
7568- static void updateMergePhiForReductionForEpilogueVectorization (
7568+ static void fixReductionScalarResumeWhenVectorizingEpilog (
75697569 VPRecipeBase *R, VPTransformState &State, Loop *OrigLoop,
75707570 BasicBlock *LoopMiddleBlock) {
7571- auto *RedResult = dyn_cast<VPInstruction>(R);
7572- if (!RedResult ||
7573- RedResult ->getOpcode () != VPInstruction::ComputeReductionResult)
7571+ auto *EpiRedResult = dyn_cast<VPInstruction>(R);
7572+ if (!EpiRedResult ||
7573+ EpiRedResult ->getOpcode () != VPInstruction::ComputeReductionResult)
75747574 return ;
75757575
7576- auto *PhiR = cast<VPReductionPHIRecipe>(RedResult->getOperand (0 ));
7577- const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor ();
7578- PHINode *MainResumePhi;
7576+ auto *EpiRedHeaderPhi =
7577+ cast<VPReductionPHIRecipe>(EpiRedResult->getOperand (0 ));
7578+ const RecurrenceDescriptor &RdxDesc =
7579+ EpiRedHeaderPhi->getRecurrenceDescriptor ();
7580+ Value *MainResumeValue =
7581+ EpiRedHeaderPhi->getStartValue ()->getUnderlyingValue ();
75797582 if (RecurrenceDescriptor::isAnyOfRecurrenceKind (
75807583 RdxDesc.getRecurrenceKind ())) {
7581- auto *Cmp = cast<ICmpInst>(PhiR->getStartValue ()->getUnderlyingValue ());
7582- assert (Cmp->getPredicate () == CmpInst::ICMP_NE);
7583- assert (Cmp->getOperand (1 ) == RdxDesc.getRecurrenceStartValue ());
7584- MainResumePhi = cast<PHINode>(Cmp->getOperand (0 ));
7585- } else {
7586- MainResumePhi = cast<PHINode>(PhiR->getStartValue ()->getUnderlyingValue ());
7584+ auto *Cmp = cast<ICmpInst>(MainResumeValue);
7585+ assert (Cmp->getPredicate () == CmpInst::ICMP_NE &&
7586+ " AnyOf expected to start with ICMP_NE" );
7587+ assert (Cmp->getOperand (1 ) == RdxDesc.getRecurrenceStartValue () &&
7588+ " AnyOf expected to start by comparing main resume value to original "
7589+ " start value" );
7590+ MainResumeValue = Cmp->getOperand (0 );
75877591 }
7592+ PHINode *MainResumePhi = cast<PHINode>(MainResumeValue);
75887593
75897594 // When fixing reductions in the epilogue loop we should already have
75907595 // created a bc.merge.rdx Phi after the main vector body. Ensure that we carry
@@ -7594,21 +7599,25 @@ static void updateMergePhiForReductionForEpilogueVectorization(
75947599 return match (
75957600 U, m_VPInstruction<VPInstruction::ResumePhi>(m_VPValue (), m_VPValue ()));
75967601 };
7597- auto *EpiResumePhiVPI =
7598- cast<VPInstruction>(*find_if (RedResult->users (), IsResumePhi));
7599- assert (count_if (RedResult->users (), IsResumePhi) == 1 &&
7602+ assert (count_if (EpiRedResult->users (), IsResumePhi) == 1 &&
76007603 " ResumePhi must have a single user" );
7604+ auto *EpiResumePhiVPI =
7605+ cast<VPInstruction>(*find_if (EpiRedResult->users (), IsResumePhi));
76017606 auto *EpiResumePhi = cast<PHINode>(State.get (EpiResumePhiVPI, true ));
76027607 BasicBlock *LoopScalarPreHeader = OrigLoop->getLoopPreheader ();
7608+ unsigned UpdateCnt = 0 ;
76037609 for (auto *Incoming : predecessors (LoopScalarPreHeader)) {
76047610 if (is_contained (MainResumePhi->blocks (), Incoming)) {
76057611 assert (EpiResumePhi->getIncomingValueForBlock (Incoming) ==
76067612 RdxDesc.getRecurrenceStartValue () &&
76077613 " Trying to reset unexpected value" );
76087614 EpiResumePhi->setIncomingValueForBlock (
76097615 Incoming, MainResumePhi->getIncomingValueForBlock (Incoming));
7616+ UpdateCnt++;
76107617 }
76117618 }
7619+ assert (UpdateCnt <= 1 && " Only should update at most 1 incoming value" );
7620+ (void )UpdateCnt;
76127621}
76137622
76147623DenseMap<const SCEV *, Value *> LoopVectorizationPlanner::executePlan (
@@ -7701,7 +7710,7 @@ DenseMap<const SCEV *, Value *> LoopVectorizationPlanner::executePlan(
77017710 cast<VPBasicBlock>(BestVPlan.getVectorLoopRegion ()->getSingleSuccessor ());
77027711 if (VectorizingEpilogue)
77037712 for (VPRecipeBase &R : *ExitVPBB) {
7704- updateMergePhiForReductionForEpilogueVectorization (
7713+ fixReductionScalarResumeWhenVectorizingEpilog (
77057714 &R, State, OrigLoop, State.CFG .VPBB2IRBB [ExitVPBB]);
77067715 }
77077716
@@ -9504,15 +9513,10 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
95049513 });
95059514 FinalReductionResult->insertBefore (*MiddleVPBB, IP);
95069515
9507- VPBasicBlock *ScalarPHVPBB = nullptr ;
9508- if (MiddleVPBB->getNumSuccessors () == 2 ) {
9509- // Order is strict: first is the exit block, second is the scalar
9510- // preheader.
9511- ScalarPHVPBB = cast<VPBasicBlock>(MiddleVPBB->getSuccessors ()[1 ]);
9512- } else {
9513- ScalarPHVPBB = cast<VPBasicBlock>(MiddleVPBB->getSingleSuccessor ());
9514- }
9515-
9516+ // Order is strict: if there are multiple successors, the first is the exit
9517+ // block, second is the scalar preheader.
9518+ VPBasicBlock *ScalarPHVPBB =
9519+ cast<VPBasicBlock>(MiddleVPBB->getSuccessors ().back ());
95169520 VPBuilder ScalarPHBuilder (ScalarPHVPBB);
95179521 auto *ResumePhiRecipe = ScalarPHBuilder.createNaryOp (
95189522 VPInstruction::ResumePhi, {FinalReductionResult, PhiR->getStartValue ()},
0 commit comments