|
56 | 56 | #include "llvm/Transforms/Vectorize/LoopVectorize.h"
|
57 | 57 | #include "LoopVectorizationPlanner.h"
|
58 | 58 | #include "VPRecipeBuilder.h"
|
| 59 | +#include "VPlanPatternMatch.h" |
59 | 60 | #include "VPlan.h"
|
60 | 61 | #include "VPlanAnalysis.h"
|
61 | 62 | #include "VPlanHCFGBuilder.h"
|
@@ -606,8 +607,8 @@ class InnerLoopVectorizer {
|
606 | 607 | BasicBlock *MiddleBlock, BasicBlock *VectorHeader,
|
607 | 608 | VPlan &Plan, VPTransformState &State);
|
608 | 609 |
|
609 |
| - /// Create the exit value of first order recurrences in the middle block and |
610 |
| - /// update their users. |
| 610 | + /// Create the phi node for the resume value of first order recurrences in the scalar preheader and |
| 611 | + /// update the users in the scalar loop. |
611 | 612 | void fixFixedOrderRecurrence(VPLiveOut *LO, VPTransformState &State);
|
612 | 613 |
|
613 | 614 | /// Iteratively sink the scalarized operands of a predicated instruction into
|
@@ -3392,8 +3393,8 @@ void InnerLoopVectorizer::fixVectorizedLoop(VPTransformState &State,
|
3392 | 3393 | // At this point every instruction in the original loop is widened to a
|
3393 | 3394 | // vector form. Note that fixing reduction phis, as well as extracting the
|
3394 | 3395 | // exit and resume values for fixed-order recurrences are already modeled in
|
3395 |
| - // VPlan. All that remains to do here is creating a phi in the scalar |
3396 |
| - // pre-header for each fixed-rder recurrence resume value. |
| 3396 | + // VPlan. All that remains to do here is to create a phi in the scalar |
| 3397 | + // pre-header for each fixed-order recurrence resume value. |
3397 | 3398 | // TODO: Also model creating phis in the scalar pre-header in VPlan.
|
3398 | 3399 | for (const auto &[_, LO] : to_vector(Plan.getLiveOuts())) {
|
3399 | 3400 | if (!Legal->isFixedOrderRecurrence(LO->getPhi()))
|
@@ -3473,21 +3474,24 @@ void InnerLoopVectorizer::fixFixedOrderRecurrence(VPLiveOut *LO,
|
3473 | 3474 | VPTransformState &State) {
|
3474 | 3475 | // Extract the last vector element in the middle block. This will be the
|
3475 | 3476 | // initial value for the recurrence when jumping to the scalar loop.
|
3476 |
| - Value *ExtractForScalar = State.get(LO->getOperand(0), UF - 1, true); |
| 3477 | + VPValue *VPExtract = LO->getOperand(0); |
| 3478 | +using namespace llvm::VPlanPatternMatch; |
| 3479 | + assert(match(VPExtract, m_VPInstruction<VPInstruction::ExtractFromEnd>(m_VPValue(), m_VPValue())) && "FOR LiveOut expects to use an extract from end."); |
| 3480 | + Value *ResumeScalarFOR = State.get(VPExtract, UF - 1, true); |
3477 | 3481 |
|
3478 | 3482 | // Fix the initial value of the original recurrence in the scalar loop.
|
3479 | 3483 | Builder.SetInsertPoint(LoopScalarPreHeader, LoopScalarPreHeader->begin());
|
3480 |
| - PHINode *Phi = LO->getPhi(); |
3481 |
| - auto *Start = Builder.CreatePHI(Phi->getType(), 2, "scalar.recur.init"); |
3482 |
| - auto *ScalarInit = |
3483 |
| - LO->getPhi()->getIncomingValueForBlock(LoopScalarPreHeader); |
| 3484 | + PHINode *ScalarHeaderPhi = LO->getPhi(); |
| 3485 | + auto *NewScalarHeaderPhi = Builder.CreatePHI(ScalarHeaderPhi->getType(), 2, "scalar.recur.init"); |
| 3486 | + auto *InitScalarFOR = |
| 3487 | + ScalarHeaderPhi->getIncomingValueForBlock(LoopScalarPreHeader); |
3484 | 3488 | for (auto *BB : predecessors(LoopScalarPreHeader)) {
|
3485 |
| - auto *Incoming = BB == LoopMiddleBlock ? ExtractForScalar : ScalarInit; |
3486 |
| - Start->addIncoming(Incoming, BB); |
| 3489 | + auto *Incoming = BB == LoopMiddleBlock ? ResumeScalarFOR : InitScalarFOR; |
| 3490 | + NewScalarHeaderPhi ->addIncoming(Incoming, BB); |
3487 | 3491 | }
|
3488 | 3492 |
|
3489 |
| - Phi->setIncomingValueForBlock(LoopScalarPreHeader, Start); |
3490 |
| - Phi->setName("scalar.recur"); |
| 3493 | + ScalarHeaderPhi->setIncomingValueForBlock(LoopScalarPreHeader, NewScalarHeaderPhi ); |
| 3494 | + ScalarHeaderPhi->setName("scalar.recur"); |
3491 | 3495 | }
|
3492 | 3496 |
|
3493 | 3497 | void InnerLoopVectorizer::sinkScalarOperands(Instruction *PredInst) {
|
|
0 commit comments