Skip to content

Commit 25ab47b

Browse files
authored
[VPlan] Use wide IV if scalar lanes > 0 are used with scalable vectors. (#169796)
For scalable vectors, VPScsalarIVStepsRecipe cannot create all scalar step values. At the moment, it creates a vector, in addition to to the first lane. The only supported case for this is when only the last lane is used. A recipe should not set both scalar and vector values. Instead, we can simply use a vector induction. It would also be possible to preserve the current vector code-gen, by creating VPInstructions based on the first lane of VPScalarIVStepsRecipe, but using a vector induction seems simpler. PR: #169796
1 parent 3d862cf commit 25ab47b

File tree

3 files changed

+70
-126
lines changed

3 files changed

+70
-126
lines changed

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,15 +2367,6 @@ void VPScalarIVStepsRecipe::execute(VPTransformState &State) {
23672367
// Compute the scalar steps and save the results in State.
23682368
Type *IntStepTy =
23692369
IntegerType::get(BaseIVTy->getContext(), BaseIVTy->getScalarSizeInBits());
2370-
Type *VecIVTy = nullptr;
2371-
Value *UnitStepVec = nullptr, *SplatStep = nullptr, *SplatIV = nullptr;
2372-
if (!FirstLaneOnly && State.VF.isScalable()) {
2373-
VecIVTy = VectorType::get(BaseIVTy, State.VF);
2374-
UnitStepVec =
2375-
Builder.CreateStepVector(VectorType::get(IntStepTy, State.VF));
2376-
SplatStep = Builder.CreateVectorSplat(State.VF, Step);
2377-
SplatIV = Builder.CreateVectorSplat(State.VF, BaseIV);
2378-
}
23792370

23802371
unsigned StartLane = 0;
23812372
unsigned EndLane = FirstLaneOnly ? 1 : State.VF.getKnownMinValue();
@@ -2396,19 +2387,6 @@ void VPScalarIVStepsRecipe::execute(VPTransformState &State) {
23962387
StartIdx0 = Builder.CreateSExtOrTrunc(StartIdx0, IntStepTy);
23972388
}
23982389

2399-
if (!FirstLaneOnly && State.VF.isScalable()) {
2400-
auto *SplatStartIdx = Builder.CreateVectorSplat(State.VF, StartIdx0);
2401-
auto *InitVec = Builder.CreateAdd(SplatStartIdx, UnitStepVec);
2402-
if (BaseIVTy->isFloatingPointTy())
2403-
InitVec = Builder.CreateSIToFP(InitVec, VecIVTy);
2404-
auto *Mul = Builder.CreateBinOp(MulOp, InitVec, SplatStep);
2405-
auto *Add = Builder.CreateBinOp(AddOp, SplatIV, Mul);
2406-
State.set(this, Add);
2407-
// It's useful to record the lane values too for the known minimum number
2408-
// of elements so we do those below. This improves the code quality when
2409-
// trying to extract the first element, for example.
2410-
}
2411-
24122390
if (BaseIVTy->isFloatingPointTy())
24132391
StartIdx0 = Builder.CreateSIToFP(StartIdx0, BaseIVTy);
24142392

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -794,12 +794,19 @@ static void legalizeAndOptimizeInductions(VPlan &Plan) {
794794
WideIV->getDebugLoc(), Builder);
795795

796796
// Update scalar users of IV to use Step instead.
797-
if (!HasOnlyVectorVFs)
797+
if (!HasOnlyVectorVFs) {
798+
assert(!Plan.hasScalableVF() &&
799+
"plans containing a scalar VF cannot also include scalable VFs");
798800
WideIV->replaceAllUsesWith(Steps);
799-
else
800-
WideIV->replaceUsesWithIf(Steps, [WideIV](VPUser &U, unsigned) {
801-
return U.usesScalars(WideIV);
802-
});
801+
} else {
802+
bool HasScalableVF = Plan.hasScalableVF();
803+
WideIV->replaceUsesWithIf(Steps,
804+
[WideIV, HasScalableVF](VPUser &U, unsigned) {
805+
if (HasScalableVF)
806+
return U.usesFirstLaneOnly(WideIV);
807+
return U.usesScalars(WideIV);
808+
});
809+
}
803810
}
804811
}
805812

0 commit comments

Comments
 (0)