@@ -526,7 +526,8 @@ class InnerLoopVectorizer {
526
526
// / Widen an integer or floating-point induction variable \p IV. If \p Trunc
527
527
// / is provided, the integer induction variable will first be truncated to
528
528
// / the corresponding type.
529
- void widenIntOrFpInduction (PHINode *IV, TruncInst *Trunc = nullptr );
529
+ void widenIntOrFpInduction (PHINode *IV, Value *Start,
530
+ TruncInst *Trunc = nullptr );
530
531
531
532
// / getOrCreateVectorValue and getOrCreateScalarValue coordinate to generate a
532
533
// / vector or scalar value on-demand if one is not yet available. When
@@ -666,7 +667,8 @@ class InnerLoopVectorizer {
666
667
// / truncate instruction, instead of widening the original IV, we widen a
667
668
// / version of the IV truncated to \p EntryVal's type.
668
669
void createVectorIntOrFpInductionPHI (const InductionDescriptor &II,
669
- Value *Step, Instruction *EntryVal);
670
+ Value *Step, Value *Start,
671
+ Instruction *EntryVal);
670
672
671
673
// / Returns true if an instruction \p I should be scalarized instead of
672
674
// / vectorized for the chosen vectorization factor.
@@ -2005,10 +2007,10 @@ Value *InnerLoopVectorizer::getBroadcastInstrs(Value *V) {
2005
2007
}
2006
2008
2007
2009
void InnerLoopVectorizer::createVectorIntOrFpInductionPHI (
2008
- const InductionDescriptor &II, Value *Step, Instruction *EntryVal) {
2010
+ const InductionDescriptor &II, Value *Step, Value *Start,
2011
+ Instruction *EntryVal) {
2009
2012
assert ((isa<PHINode>(EntryVal) || isa<TruncInst>(EntryVal)) &&
2010
2013
" Expected either an induction phi-node or a truncate of it!" );
2011
- Value *Start = II.getStartValue ();
2012
2014
2013
2015
// Construct the initial value of the vector IV in the vector loop preheader
2014
2016
auto CurrIP = Builder.saveIP ();
@@ -2126,7 +2128,8 @@ void InnerLoopVectorizer::recordVectorLoopValueForInductionCast(
2126
2128
VectorLoopValueMap.setVectorValue (CastInst, Part, VectorLoopVal);
2127
2129
}
2128
2130
2129
- void InnerLoopVectorizer::widenIntOrFpInduction (PHINode *IV, TruncInst *Trunc) {
2131
+ void InnerLoopVectorizer::widenIntOrFpInduction (PHINode *IV, Value *Start,
2132
+ TruncInst *Trunc) {
2130
2133
assert ((IV->getType ()->isIntegerTy () || IV != OldInduction) &&
2131
2134
" Primary induction variable must have an integer type" );
2132
2135
@@ -2208,15 +2211,15 @@ void InnerLoopVectorizer::widenIntOrFpInduction(PHINode *IV, TruncInst *Trunc) {
2208
2211
// least one user in the loop that is not widened.
2209
2212
auto NeedsScalarIV = needsScalarInduction (EntryVal);
2210
2213
if (!NeedsScalarIV) {
2211
- createVectorIntOrFpInductionPHI (ID, Step, EntryVal);
2214
+ createVectorIntOrFpInductionPHI (ID, Step, Start, EntryVal);
2212
2215
return ;
2213
2216
}
2214
2217
2215
2218
// Try to create a new independent vector induction variable. If we can't
2216
2219
// create the phi node, we will splat the scalar induction variable in each
2217
2220
// loop iteration.
2218
2221
if (!shouldScalarizeInstruction (EntryVal)) {
2219
- createVectorIntOrFpInductionPHI (ID, Step, EntryVal);
2222
+ createVectorIntOrFpInductionPHI (ID, Step, Start, EntryVal);
2220
2223
Value *ScalarIV = CreateScalarIV (Step);
2221
2224
// Create scalar steps that can be used by instructions we will later
2222
2225
// scalarize. Note that the addition of the scalar steps will not increase
@@ -8061,20 +8064,22 @@ VPRecipeBase *VPRecipeBuilder::tryToWidenMemory(Instruction *I, VFRange &Range,
8061
8064
}
8062
8065
8063
8066
VPWidenIntOrFpInductionRecipe *
8064
- VPRecipeBuilder::tryToOptimizeInductionPHI (PHINode *Phi) const {
8067
+ VPRecipeBuilder::tryToOptimizeInductionPHI (PHINode *Phi, VPlan &Plan ) const {
8065
8068
// Check if this is an integer or fp induction. If so, build the recipe that
8066
8069
// produces its scalar and vector values.
8067
8070
InductionDescriptor II = Legal->getInductionVars ().lookup (Phi);
8068
8071
if (II.getKind () == InductionDescriptor::IK_IntInduction ||
8069
- II.getKind () == InductionDescriptor::IK_FpInduction)
8070
- return new VPWidenIntOrFpInductionRecipe (Phi);
8072
+ II.getKind () == InductionDescriptor::IK_FpInduction) {
8073
+ VPValue *Start = Plan.getOrAddVPValue (II.getStartValue ());
8074
+ return new VPWidenIntOrFpInductionRecipe (Phi, Start);
8075
+ }
8071
8076
8072
8077
return nullptr ;
8073
8078
}
8074
8079
8075
8080
VPWidenIntOrFpInductionRecipe *
8076
- VPRecipeBuilder::tryToOptimizeInductionTruncate (TruncInst *I,
8077
- VFRange &Range ) const {
8081
+ VPRecipeBuilder::tryToOptimizeInductionTruncate (TruncInst *I, VFRange &Range,
8082
+ VPlan &Plan ) const {
8078
8083
// Optimize the special case where the source is a constant integer
8079
8084
// induction variable. Notice that we can only optimize the 'trunc' case
8080
8085
// because (a) FP conversions lose precision, (b) sext/zext may wrap, and
@@ -8090,9 +8095,14 @@ VPRecipeBuilder::tryToOptimizeInductionTruncate(TruncInst *I,
8090
8095
};
8091
8096
8092
8097
if (LoopVectorizationPlanner::getDecisionAndClampRange (
8093
- isOptimizableIVTruncate (I), Range))
8098
+ isOptimizableIVTruncate (I), Range)) {
8099
+
8100
+ InductionDescriptor II =
8101
+ Legal->getInductionVars ().lookup (cast<PHINode>(I->getOperand (0 )));
8102
+ VPValue *Start = Plan.getOrAddVPValue (II.getStartValue ());
8094
8103
return new VPWidenIntOrFpInductionRecipe (cast<PHINode>(I->getOperand (0 )),
8095
- I);
8104
+ Start, I);
8105
+ }
8096
8106
return nullptr ;
8097
8107
}
8098
8108
@@ -8304,13 +8314,13 @@ VPRecipeBase *VPRecipeBuilder::tryToCreateWidenRecipe(Instruction *Instr,
8304
8314
if (auto Phi = dyn_cast<PHINode>(Instr)) {
8305
8315
if (Phi->getParent () != OrigLoop->getHeader ())
8306
8316
return tryToBlend (Phi, Plan);
8307
- if ((Recipe = tryToOptimizeInductionPHI (Phi)))
8317
+ if ((Recipe = tryToOptimizeInductionPHI (Phi, *Plan )))
8308
8318
return Recipe;
8309
8319
return new VPWidenPHIRecipe (Phi);
8310
8320
}
8311
8321
8312
- if (isa<TruncInst>(Instr) &&
8313
- (Recipe = tryToOptimizeInductionTruncate ( cast<TruncInst>(Instr), Range)))
8322
+ if (isa<TruncInst>(Instr) && (Recipe = tryToOptimizeInductionTruncate (
8323
+ cast<TruncInst>(Instr), Range, *Plan )))
8314
8324
return Recipe;
8315
8325
8316
8326
if (!shouldWiden (Instr, Range))
@@ -8705,7 +8715,8 @@ void VPWidenGEPRecipe::execute(VPTransformState &State) {
8705
8715
8706
8716
void VPWidenIntOrFpInductionRecipe::execute (VPTransformState &State) {
8707
8717
assert (!State.Instance && " Int or FP induction being replicated." );
8708
- State.ILV ->widenIntOrFpInduction (IV, Trunc);
8718
+ State.ILV ->widenIntOrFpInduction (IV, getStartValue ()->getLiveInIRValue (),
8719
+ Trunc);
8709
8720
}
8710
8721
8711
8722
void VPWidenPHIRecipe::execute (VPTransformState &State) {
0 commit comments