@@ -7485,6 +7485,13 @@ static void addRuntimeUnrollDisableMetaData(Loop *L) {
7485
7485
}
7486
7486
}
7487
7487
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
+
7488
7495
// If \p R is a ComputeReductionResult when vectorizing the epilog loop,
7489
7496
// fix the reduction's scalar PHI node by adding the incoming value from the
7490
7497
// main vector loop.
@@ -7493,7 +7500,8 @@ static void fixReductionScalarResumeWhenVectorizingEpilog(
7493
7500
BasicBlock *BypassBlock) {
7494
7501
auto *EpiRedResult = dyn_cast<VPInstruction>(R);
7495
7502
if (!EpiRedResult ||
7496
- (EpiRedResult->getOpcode () != VPInstruction::ComputeReductionResult &&
7503
+ (EpiRedResult->getOpcode () != VPInstruction::ComputeAnyOfResult &&
7504
+ EpiRedResult->getOpcode () != VPInstruction::ComputeReductionResult &&
7497
7505
EpiRedResult->getOpcode () != VPInstruction::ComputeFindLastIVResult))
7498
7506
return ;
7499
7507
@@ -7505,15 +7513,19 @@ static void fixReductionScalarResumeWhenVectorizingEpilog(
7505
7513
EpiRedHeaderPhi->getStartValue ()->getUnderlyingValue ();
7506
7514
if (RecurrenceDescriptor::isAnyOfRecurrenceKind (
7507
7515
RdxDesc.getRecurrenceKind ())) {
7516
+ Value *StartV = EpiRedResult->getOperand (1 )->getLiveInIRValue ();
7517
+ (void )StartV;
7508
7518
auto *Cmp = cast<ICmpInst>(MainResumeValue);
7509
7519
assert (Cmp->getPredicate () == CmpInst::ICMP_NE &&
7510
7520
" AnyOf expected to start with ICMP_NE" );
7511
- assert (Cmp->getOperand (1 ) == RdxDesc. getRecurrenceStartValue () &&
7521
+ assert (Cmp->getOperand (1 ) == StartV &&
7512
7522
" AnyOf expected to start by comparing main resume value to original "
7513
7523
" start value" );
7514
7524
MainResumeValue = Cmp->getOperand (0 );
7515
7525
} else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind (
7516
7526
RdxDesc.getRecurrenceKind ())) {
7527
+ Value *StartV = getStartValueFromReductionResult (EpiRedResult);
7528
+ (void )StartV;
7517
7529
using namespace llvm ::PatternMatch;
7518
7530
Value *Cmp, *OrigResumeV, *CmpOp;
7519
7531
bool IsExpectedPattern =
@@ -7522,10 +7534,7 @@ static void fixReductionScalarResumeWhenVectorizingEpilog(
7522
7534
m_Value (OrigResumeV))) &&
7523
7535
(match (Cmp, m_SpecificICmp (ICmpInst::ICMP_EQ, m_Specific (OrigResumeV),
7524
7536
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))));
7529
7538
assert (IsExpectedPattern && " Unexpected reduction resume pattern" );
7530
7539
(void )IsExpectedPattern;
7531
7540
MainResumeValue = OrigResumeV;
@@ -9460,7 +9469,10 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
9460
9469
OrigExitingVPV->replaceUsesWithIf (NewExitingVPV, [](VPUser &U, unsigned ) {
9461
9470
return isa<VPInstruction>(&U) &&
9462
9471
(cast<VPInstruction>(&U)->getOpcode () ==
9472
+ VPInstruction::ComputeAnyOfResult ||
9473
+ cast<VPInstruction>(&U)->getOpcode () ==
9463
9474
VPInstruction::ComputeReductionResult ||
9475
+
9464
9476
cast<VPInstruction>(&U)->getOpcode () ==
9465
9477
VPInstruction::ComputeFindLastIVResult);
9466
9478
});
@@ -9512,6 +9524,12 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
9512
9524
FinalReductionResult =
9513
9525
Builder.createNaryOp (VPInstruction::ComputeFindLastIVResult,
9514
9526
{PhiR, Start, NewExitingVPV}, ExitDL);
9527
+ } else if (RecurrenceDescriptor::isAnyOfRecurrenceKind (
9528
+ RdxDesc.getRecurrenceKind ())) {
9529
+ VPValue *Start = PhiR->getStartValue ();
9530
+ FinalReductionResult =
9531
+ Builder.createNaryOp (VPInstruction::ComputeAnyOfResult,
9532
+ {PhiR, Start, NewExitingVPV}, ExitDL);
9515
9533
} else {
9516
9534
VPIRFlags Flags = RecurrenceDescriptor::isFloatingPointRecurrenceKind (
9517
9535
RdxDesc.getRecurrenceKind ())
@@ -10040,23 +10058,36 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
10040
10058
Value *ResumeV = nullptr ;
10041
10059
// TODO: Move setting of resume values to prepareToExecute.
10042
10060
if (auto *ReductionPhi = dyn_cast<VPReductionPHIRecipe>(&R)) {
10061
+ auto *RdxResult =
10062
+ cast<VPInstruction>(*find_if (ReductionPhi->users (), [](VPUser *U) {
10063
+ auto *VPI = dyn_cast<VPInstruction>(U);
10064
+ return VPI &&
10065
+ (VPI->getOpcode () == VPInstruction::ComputeReductionResult ||
10066
+ VPI->getOpcode () == VPInstruction::ComputeFindLastIVResult);
10067
+ }));
10043
10068
ResumeV = cast<PHINode>(ReductionPhi->getUnderlyingInstr ())
10044
10069
->getIncomingValueForBlock (L->getLoopPreheader ());
10045
10070
const RecurrenceDescriptor &RdxDesc =
10046
10071
ReductionPhi->getRecurrenceDescriptor ();
10047
10072
RecurKind RK = RdxDesc.getRecurrenceKind ();
10048
10073
if (RecurrenceDescriptor::isAnyOfRecurrenceKind (RK)) {
10074
+ Value *StartV = RdxResult->getOperand (1 )->getLiveInIRValue ();
10075
+ assert (RdxDesc.getRecurrenceStartValue () == StartV &&
10076
+ " start value from ComputeAnyOfResult must match" );
10077
+
10049
10078
// VPReductionPHIRecipes for AnyOf reductions expect a boolean as
10050
10079
// start value; compare the final value from the main vector loop
10051
10080
// to the start value.
10052
10081
BasicBlock *PBB = cast<Instruction>(ResumeV)->getParent ();
10053
10082
IRBuilder<> Builder (PBB, PBB->getFirstNonPHIIt ());
10054
- ResumeV =
10055
- Builder.CreateICmpNE (ResumeV, RdxDesc.getRecurrenceStartValue ());
10083
+ ResumeV = Builder.CreateICmpNE (ResumeV, StartV);
10056
10084
} else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK)) {
10057
- ToFrozen[RdxDesc.getRecurrenceStartValue ()] =
10058
- cast<PHINode>(ResumeV)->getIncomingValueForBlock (
10059
- EPI.MainLoopIterationCountCheck );
10085
+ Value *StartV = getStartValueFromReductionResult (RdxResult);
10086
+ assert (RdxDesc.getRecurrenceStartValue () == StartV &&
10087
+ " start value from ComputeFindLastIVResult must match" );
10088
+
10089
+ ToFrozen[StartV] = cast<PHINode>(ResumeV)->getIncomingValueForBlock (
10090
+ EPI.MainLoopIterationCountCheck );
10060
10091
10061
10092
// VPReductionPHIRecipe for FindLastIV reductions requires an adjustment
10062
10093
// to the resume value. The resume value is adjusted to the sentinel
@@ -10066,8 +10097,7 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
10066
10097
// variable.
10067
10098
BasicBlock *ResumeBB = cast<Instruction>(ResumeV)->getParent ();
10068
10099
IRBuilder<> Builder (ResumeBB, ResumeBB->getFirstNonPHIIt ());
10069
- Value *Cmp = Builder.CreateICmpEQ (
10070
- ResumeV, ToFrozen[RdxDesc.getRecurrenceStartValue ()]);
10100
+ Value *Cmp = Builder.CreateICmpEQ (ResumeV, ToFrozen[StartV]);
10071
10101
ResumeV =
10072
10102
Builder.CreateSelect (Cmp, RdxDesc.getSentinelValue (), ResumeV);
10073
10103
}
0 commit comments