Index: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1813,42 +1813,28 @@ // variable. Instruction *EntryVal = Trunc ? cast(Trunc) : IV; - // True if we have vectorized the induction variable. - auto VectorizedIV = false; - - // Determine if we want a scalar version of the induction variable. This is - // true if the induction variable itself is not widened, or if it has at - // least one user in the loop that is not widened. - auto NeedsScalarIV = VF > 1 && needsScalarInduction(EntryVal); + Value *Step = nullptr; + auto &DL = OrigLoop->getHeader()->getModule()->getDataLayout(); // Generate code for the induction step. Note that induction steps are // required to be loop-invariant - assert(PSE.getSE()->isLoopInvariant(ID.getStep(), OrigLoop) && - "Induction step should be loop invariant"); - auto &DL = OrigLoop->getHeader()->getModule()->getDataLayout(); - Value *Step = nullptr; - if (PSE.getSE()->isSCEVable(IV->getType())) { - SCEVExpander Exp(*PSE.getSE(), DL, "induction"); - Step = Exp.expandCodeFor(ID.getStep(), ID.getStep()->getType(), - LoopVectorPreHeader->getTerminator()); - } else { - Step = cast(ID.getStep())->getValue(); - } - - // Try to create a new independent vector induction variable. If we can't - // create the phi node, we will splat the scalar induction variable in each - // loop iteration. - if (VF > 1 && !shouldScalarizeInstruction(EntryVal)) { - createVectorIntOrFpInductionPHI(ID, Step, EntryVal); - VectorizedIV = true; - } + auto CreateStepValue = [&] () { + assert(PSE.getSE()->isLoopInvariant(ID.getStep(), OrigLoop) && + "Induction step should be loop invariant"); + if (PSE.getSE()->isSCEVable(IV->getType())) { + SCEVExpander Exp(*PSE.getSE(), DL, "induction"); + Step = Exp.expandCodeFor(ID.getStep(), ID.getStep()->getType(), + LoopVectorPreHeader->getTerminator()); + } else + Step = cast(ID.getStep())->getValue(); + }; // If we haven't yet vectorized the induction variable, or if we will create // a scalar one, we need to define the scalar induction variable and step // values. If we were given a truncation type, truncate the canonical // induction variable and step. Otherwise, derive these values from the // induction descriptor. - if (!VectorizedIV || NeedsScalarIV) { + auto CreateScalarIV = [&] () { ScalarIV = Induction; if (IV != OldInduction) { ScalarIV = IV->getType()->isIntegerTy() @@ -1865,12 +1851,12 @@ ScalarIV = Builder.CreateTrunc(ScalarIV, TruncType); Step = Builder.CreateTrunc(Step, TruncType); } - } + }; // If we haven't yet vectorized the induction variable, splat the scalar // induction variable, and build the necessary step vectors. // TODO: Don't do it unless the vectorized IV is really required. - if (!VectorizedIV) { + auto CreateSplatIV = [&]() { Value *Broadcasted = getBroadcastInstrs(ScalarIV); for (unsigned Part = 0; Part < UF; ++Part) { Value *EntryPart = @@ -1880,16 +1866,62 @@ addMetadata(EntryPart, Trunc); recordVectorLoopValueForInductionCast(ID, EntryVal, EntryPart, Part); } + }; + + auto CreateScalarIVCode = [&]() { + CreateScalarIV(); + + Value *Broadcasted = getBroadcastInstrs(ScalarIV); + for (unsigned Part = 0; Part < UF; ++Part) { + Value *EntryPart = + getStepVector(Broadcasted, VF * Part, Step, ID.getInductionOpcode()); + VectorLoopValueMap.setVectorValue(EntryVal, Part, EntryPart); + if (Trunc) + addMetadata(EntryPart, Trunc); + recordVectorLoopValueForInductionCast(ID, EntryVal, EntryPart, Part); + } + }; + + // Now do the actual transformations, and start with creating the step value. + CreateStepValue(); + + if (VF <= 1) { + CreateScalarIVCode(); + return; + } + + // Determine if we want a scalar version of the induction variable. This is + // true if the induction variable itself is not widened, or if it has at + // least one user in the loop that is not widened. + auto NeedsScalarIV = needsScalarInduction(EntryVal); + + if (!shouldScalarizeInstruction(EntryVal)) { + // Try to create a new independent vector induction variable. If we can't + // create the phi node, we will splat the scalar induction variable in each + // loop iteration. + createVectorIntOrFpInductionPHI(ID, Step, EntryVal); + if (NeedsScalarIV) { + CreateScalarIV(); + buildScalarSteps(ScalarIV, Step, EntryVal, ID); + } + return; } + // We are done if we don't need a scalar IV. + if (!NeedsScalarIV) + return; + + // Otherwise, create the scalar IV, the splat and the step values. + CreateScalarIV(); + CreateSplatIV(); + // If an induction variable is only used for counting loop iterations or // calculating addresses, it doesn't need to be widened. Create scalar steps // that can be used by instructions we will later scalarize. Note that the // addition of the scalar steps will not increase the number of instructions // in the loop in the common case prior to InstCombine. We will be trading // one vector extract for each scalar step. - if (NeedsScalarIV) - buildScalarSteps(ScalarIV, Step, EntryVal, ID); + buildScalarSteps(ScalarIV, Step, EntryVal, ID); } Value *InnerLoopVectorizer::getStepVector(Value *Val, int StartIdx, Value *Step,