@@ -7209,15 +7209,25 @@ static void addRuntimeUnrollDisableMetaData(Loop *L) {
7209
7209
}
7210
7210
}
7211
7211
7212
- // If \p R is a ComputeReductionResult when vectorizing the epilog loop,
7213
- // fix the reduction's scalar PHI node by adding the incoming value from the
7214
- // main vector loop.
7212
+ static Value *getStartValueFromReductionResult (VPInstruction *RdxResult) {
7213
+ using namespace VPlanPatternMatch ;
7214
+ assert (RdxResult->getOpcode () == VPInstruction::ComputeFindLastIVResult &&
7215
+ " RdxResult must be ComputeFindLastIVResult" );
7216
+ VPValue *StartVPV = RdxResult->getOperand (1 );
7217
+ match (StartVPV, m_Freeze (m_VPValue (StartVPV)));
7218
+ return StartVPV->getLiveInIRValue ();
7219
+ }
7220
+
7221
+ // If \p R is a Compute{Reduction,AnyOf,FindLastIV}Result when vectorizing the
7222
+ // epilog loop, fix the reduction's scalar PHI node by adding the incoming value
7223
+ // from the main vector loop.
7215
7224
static void fixReductionScalarResumeWhenVectorizingEpilog (
7216
7225
VPRecipeBase *R, VPTransformState &State, BasicBlock *LoopMiddleBlock,
7217
7226
BasicBlock *BypassBlock) {
7218
7227
auto *EpiRedResult = dyn_cast<VPInstruction>(R);
7219
7228
if (!EpiRedResult ||
7220
- (EpiRedResult->getOpcode () != VPInstruction::ComputeReductionResult &&
7229
+ (EpiRedResult->getOpcode () != VPInstruction::ComputeAnyOfResult &&
7230
+ EpiRedResult->getOpcode () != VPInstruction::ComputeReductionResult &&
7221
7231
EpiRedResult->getOpcode () != VPInstruction::ComputeFindLastIVResult))
7222
7232
return ;
7223
7233
@@ -7229,15 +7239,18 @@ static void fixReductionScalarResumeWhenVectorizingEpilog(
7229
7239
EpiRedHeaderPhi->getStartValue ()->getUnderlyingValue ();
7230
7240
if (RecurrenceDescriptor::isAnyOfRecurrenceKind (
7231
7241
RdxDesc.getRecurrenceKind ())) {
7242
+ Value *StartV = EpiRedResult->getOperand (1 )->getLiveInIRValue ();
7243
+ (void )StartV;
7232
7244
auto *Cmp = cast<ICmpInst>(MainResumeValue);
7233
7245
assert (Cmp->getPredicate () == CmpInst::ICMP_NE &&
7234
7246
" AnyOf expected to start with ICMP_NE" );
7235
- assert (Cmp->getOperand (1 ) == RdxDesc. getRecurrenceStartValue () &&
7247
+ assert (Cmp->getOperand (1 ) == StartV &&
7236
7248
" AnyOf expected to start by comparing main resume value to original "
7237
7249
" start value" );
7238
7250
MainResumeValue = Cmp->getOperand (0 );
7239
7251
} else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind (
7240
7252
RdxDesc.getRecurrenceKind ())) {
7253
+ Value *StartV = getStartValueFromReductionResult (EpiRedResult);
7241
7254
using namespace llvm ::PatternMatch;
7242
7255
Value *Cmp, *OrigResumeV, *CmpOp;
7243
7256
bool IsExpectedPattern =
@@ -7246,10 +7259,7 @@ static void fixReductionScalarResumeWhenVectorizingEpilog(
7246
7259
m_Value (OrigResumeV))) &&
7247
7260
(match (Cmp, m_SpecificICmp (ICmpInst::ICMP_EQ, m_Specific (OrigResumeV),
7248
7261
m_Value (CmpOp))) &&
7249
- (match (CmpOp,
7250
- m_Freeze (m_Specific (RdxDesc.getRecurrenceStartValue ()))) ||
7251
- (CmpOp == RdxDesc.getRecurrenceStartValue () &&
7252
- isGuaranteedNotToBeUndefOrPoison (CmpOp))));
7262
+ ((CmpOp == StartV && isGuaranteedNotToBeUndefOrPoison (CmpOp))));
7253
7263
assert (IsExpectedPattern && " Unexpected reduction resume pattern" );
7254
7264
(void )IsExpectedPattern;
7255
7265
MainResumeValue = OrigResumeV;
@@ -9184,6 +9194,8 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
9184
9194
OrigExitingVPV->replaceUsesWithIf (NewExitingVPV, [](VPUser &U, unsigned ) {
9185
9195
return isa<VPInstruction>(&U) &&
9186
9196
(cast<VPInstruction>(&U)->getOpcode () ==
9197
+ VPInstruction::ComputeAnyOfResult ||
9198
+ cast<VPInstruction>(&U)->getOpcode () ==
9187
9199
VPInstruction::ComputeReductionResult ||
9188
9200
cast<VPInstruction>(&U)->getOpcode () ==
9189
9201
VPInstruction::ComputeFindLastIVResult);
@@ -9236,6 +9248,12 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
9236
9248
FinalReductionResult =
9237
9249
Builder.createNaryOp (VPInstruction::ComputeFindLastIVResult,
9238
9250
{PhiR, Start, NewExitingVPV}, ExitDL);
9251
+ } else if (RecurrenceDescriptor::isAnyOfRecurrenceKind (
9252
+ RdxDesc.getRecurrenceKind ())) {
9253
+ VPValue *Start = PhiR->getStartValue ();
9254
+ FinalReductionResult =
9255
+ Builder.createNaryOp (VPInstruction::ComputeAnyOfResult,
9256
+ {PhiR, Start, NewExitingVPV}, ExitDL);
9239
9257
} else {
9240
9258
VPIRFlags Flags = RecurrenceDescriptor::isFloatingPointRecurrenceKind (
9241
9259
RdxDesc.getRecurrenceKind ())
@@ -9764,23 +9782,37 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
9764
9782
Value *ResumeV = nullptr ;
9765
9783
// TODO: Move setting of resume values to prepareToExecute.
9766
9784
if (auto *ReductionPhi = dyn_cast<VPReductionPHIRecipe>(&R)) {
9785
+ auto *RdxResult =
9786
+ cast<VPInstruction>(*find_if (ReductionPhi->users (), [](VPUser *U) {
9787
+ auto *VPI = dyn_cast<VPInstruction>(U);
9788
+ return VPI &&
9789
+ (VPI->getOpcode () == VPInstruction::ComputeAnyOfResult ||
9790
+ VPI->getOpcode () == VPInstruction::ComputeReductionResult ||
9791
+ VPI->getOpcode () == VPInstruction::ComputeFindLastIVResult);
9792
+ }));
9767
9793
ResumeV = cast<PHINode>(ReductionPhi->getUnderlyingInstr ())
9768
9794
->getIncomingValueForBlock (L->getLoopPreheader ());
9769
9795
const RecurrenceDescriptor &RdxDesc =
9770
9796
ReductionPhi->getRecurrenceDescriptor ();
9771
9797
RecurKind RK = RdxDesc.getRecurrenceKind ();
9772
9798
if (RecurrenceDescriptor::isAnyOfRecurrenceKind (RK)) {
9799
+ Value *StartV = RdxResult->getOperand (1 )->getLiveInIRValue ();
9800
+ assert (RdxDesc.getRecurrenceStartValue () == StartV &&
9801
+ " start value from ComputeAnyOfResult must match" );
9802
+
9773
9803
// VPReductionPHIRecipes for AnyOf reductions expect a boolean as
9774
9804
// start value; compare the final value from the main vector loop
9775
9805
// to the start value.
9776
9806
BasicBlock *PBB = cast<Instruction>(ResumeV)->getParent ();
9777
9807
IRBuilder<> Builder (PBB, PBB->getFirstNonPHIIt ());
9778
- ResumeV =
9779
- Builder.CreateICmpNE (ResumeV, RdxDesc.getRecurrenceStartValue ());
9808
+ ResumeV = Builder.CreateICmpNE (ResumeV, StartV);
9780
9809
} else if (RecurrenceDescriptor::isFindLastIVRecurrenceKind (RK)) {
9781
- ToFrozen[RdxDesc.getRecurrenceStartValue ()] =
9782
- cast<PHINode>(ResumeV)->getIncomingValueForBlock (
9783
- EPI.MainLoopIterationCountCheck );
9810
+ Value *StartV = getStartValueFromReductionResult (RdxResult);
9811
+ assert (RdxDesc.getRecurrenceStartValue () == StartV &&
9812
+ " start value from ComputeFindLastIVResult must match" );
9813
+
9814
+ ToFrozen[StartV] = cast<PHINode>(ResumeV)->getIncomingValueForBlock (
9815
+ EPI.MainLoopIterationCountCheck );
9784
9816
9785
9817
// VPReductionPHIRecipe for FindLastIV reductions requires an adjustment
9786
9818
// to the resume value. The resume value is adjusted to the sentinel
@@ -9790,8 +9822,7 @@ preparePlanForEpilogueVectorLoop(VPlan &Plan, Loop *L,
9790
9822
// variable.
9791
9823
BasicBlock *ResumeBB = cast<Instruction>(ResumeV)->getParent ();
9792
9824
IRBuilder<> Builder (ResumeBB, ResumeBB->getFirstNonPHIIt ());
9793
- Value *Cmp = Builder.CreateICmpEQ (
9794
- ResumeV, ToFrozen[RdxDesc.getRecurrenceStartValue ()]);
9825
+ Value *Cmp = Builder.CreateICmpEQ (ResumeV, ToFrozen[StartV]);
9795
9826
ResumeV =
9796
9827
Builder.CreateSelect (Cmp, RdxDesc.getSentinelValue (), ResumeV);
9797
9828
}
0 commit comments