Skip to content

Commit d7a1388

Browse files
author
Florian Hahn
committed
Revert "[LV] Vectorize Epilogues for loops with small VF but high IC (llvm#108190)"
This reverts commit a8538b9.
1 parent 4116360 commit d7a1388

28 files changed

+1681
-2087
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -525,12 +525,6 @@ class LoopVectorizationPlanner {
525525
bool isMoreProfitable(const VectorizationFactor &A,
526526
const VectorizationFactor &B) const;
527527

528-
/// Returns true if the per-lane cost of VectorizationFactor A is lower than
529-
/// that of B in the context of vectorizing a loop with known \p MaxTripCount.
530-
bool isMoreProfitable(const VectorizationFactor &A,
531-
const VectorizationFactor &B,
532-
const unsigned MaxTripCount) const;
533-
534528
/// Determines if we have the infrastructure to vectorize the loop and its
535529
/// epilogue, assuming the main loop is vectorized by \p VF.
536530
bool isCandidateForEpilogueVectorization(const ElementCount VF) const;

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,10 +1555,7 @@ class LoopVectorizationCostModel {
15551555
/// Returns true if epilogue vectorization is considered profitable, and
15561556
/// false otherwise.
15571557
/// \p VF is the vectorization factor chosen for the original loop.
1558-
/// \p Multiplier is an aditional scaling factor applied to VF before
1559-
/// comparing to EpilogueVectorizationMinVF.
1560-
bool isEpilogueVectorizationProfitable(const ElementCount VF,
1561-
const unsigned IC) const;
1558+
bool isEpilogueVectorizationProfitable(const ElementCount VF) const;
15621559

15631560
/// Returns the execution time cost of an instruction for a given vector
15641561
/// width. Vector width of one means scalar.
@@ -4387,11 +4384,12 @@ static unsigned getEstimatedRuntimeVF(const Loop *L,
43874384
}
43884385

43894386
bool LoopVectorizationPlanner::isMoreProfitable(
4390-
const VectorizationFactor &A, const VectorizationFactor &B,
4391-
const unsigned MaxTripCount) const {
4387+
const VectorizationFactor &A, const VectorizationFactor &B) const {
43924388
InstructionCost CostA = A.Cost;
43934389
InstructionCost CostB = B.Cost;
43944390

4391+
unsigned MaxTripCount = PSE.getSmallConstantMaxTripCount();
4392+
43954393
// Improve estimate for the vector width if it is scalable.
43964394
unsigned EstimatedWidthA = A.Width.getKnownMinValue();
43974395
unsigned EstimatedWidthB = B.Width.getKnownMinValue();
@@ -4440,12 +4438,6 @@ bool LoopVectorizationPlanner::isMoreProfitable(
44404438
return CmpFn(RTCostA, RTCostB);
44414439
}
44424440

4443-
bool LoopVectorizationPlanner::isMoreProfitable(
4444-
const VectorizationFactor &A, const VectorizationFactor &B) const {
4445-
const unsigned MaxTripCount = PSE.getSmallConstantMaxTripCount();
4446-
return LoopVectorizationPlanner::isMoreProfitable(A, B, MaxTripCount);
4447-
}
4448-
44494441
void LoopVectorizationPlanner::emitInvalidCostRemarks(
44504442
OptimizationRemarkEmitter *ORE) {
44514443
using RecipeVFPair = std::pair<VPRecipeBase *, ElementCount>;
@@ -4760,7 +4752,7 @@ bool LoopVectorizationPlanner::isCandidateForEpilogueVectorization(
47604752
}
47614753

47624754
bool LoopVectorizationCostModel::isEpilogueVectorizationProfitable(
4763-
const ElementCount VF, const unsigned IC) const {
4755+
const ElementCount VF) const {
47644756
// FIXME: We need a much better cost-model to take different parameters such
47654757
// as register pressure, code size increase and cost of extra branches into
47664758
// account. For now we apply a very crude heuristic and only consider loops
@@ -4775,15 +4767,12 @@ bool LoopVectorizationCostModel::isEpilogueVectorizationProfitable(
47754767
if (TTI.getMaxInterleaveFactor(VF) <= 1)
47764768
return false;
47774769

4778-
// TODO: PR #108190 introduced a discrepancy between fixed-width and scalable
4779-
// VFs when deciding profitability.
4780-
// See related "TODO: extend to support scalable VFs." in
4781-
// selectEpilogueVectorizationFactor.
4782-
unsigned Multiplier = VF.isFixed() ? IC : 1;
4783-
unsigned MinVFThreshold = EpilogueVectorizationMinVF.getNumOccurrences() > 0
4784-
? EpilogueVectorizationMinVF
4785-
: TTI.getEpilogueVectorizationMinVF();
4786-
return getEstimatedRuntimeVF(TheLoop, TTI, VF * Multiplier) >= MinVFThreshold;
4770+
unsigned Multiplier = 1;
4771+
if (VF.isScalable())
4772+
Multiplier = getVScaleForTuning(TheLoop, TTI).value_or(1);
4773+
if ((Multiplier * VF.getKnownMinValue()) >= EpilogueVectorizationMinVF)
4774+
return true;
4775+
return false;
47874776
}
47884777

47894778
VectorizationFactor LoopVectorizationPlanner::selectEpilogueVectorizationFactor(
@@ -4826,7 +4815,7 @@ VectorizationFactor LoopVectorizationPlanner::selectEpilogueVectorizationFactor(
48264815
return Result;
48274816
}
48284817

4829-
if (!CM.isEpilogueVectorizationProfitable(MainLoopVF, IC)) {
4818+
if (!CM.isEpilogueVectorizationProfitable(MainLoopVF)) {
48304819
LLVM_DEBUG(dbgs() << "LEV: Epilogue vectorization is not profitable for "
48314820
"this loop\n");
48324821
return Result;
@@ -4841,20 +4830,16 @@ VectorizationFactor LoopVectorizationPlanner::selectEpilogueVectorizationFactor(
48414830
ScalarEvolution &SE = *PSE.getSE();
48424831
Type *TCType = Legal->getWidestInductionType();
48434832
const SCEV *RemainingIterations = nullptr;
4844-
unsigned MaxTripCount = 0;
48454833
for (auto &NextVF : ProfitableVFs) {
48464834
// Skip candidate VFs without a corresponding VPlan.
48474835
if (!hasPlanWithVF(NextVF.Width))
48484836
continue;
48494837

4850-
// Skip candidate VFs with widths >= the (estimated) runtime VF (scalable
4851-
// vectors) or > the VF of the main loop (fixed vectors).
4838+
// Skip candidate VFs with widths >= the estimate runtime VF (scalable
4839+
// vectors) or the VF of the main loop (fixed vectors).
48524840
if ((!NextVF.Width.isScalable() && MainLoopVF.isScalable() &&
48534841
ElementCount::isKnownGE(NextVF.Width, EstimatedRuntimeVF)) ||
4854-
(NextVF.Width.isScalable() &&
4855-
ElementCount::isKnownGE(NextVF.Width, MainLoopVF)) ||
4856-
(!NextVF.Width.isScalable() && !MainLoopVF.isScalable() &&
4857-
ElementCount::isKnownGT(NextVF.Width, MainLoopVF)))
4842+
ElementCount::isKnownGE(NextVF.Width, MainLoopVF))
48584843
continue;
48594844

48604845
// If NextVF is greater than the number of remaining iterations, the
@@ -4868,14 +4853,6 @@ VectorizationFactor LoopVectorizationPlanner::selectEpilogueVectorizationFactor(
48684853
"Trip count SCEV must be computable");
48694854
RemainingIterations = SE.getURemExpr(
48704855
TC, SE.getConstant(TCType, MainLoopVF.getKnownMinValue() * IC));
4871-
MaxTripCount = MainLoopVF.getKnownMinValue() * IC - 1;
4872-
if (SE.isKnownPredicate(CmpInst::ICMP_ULT, RemainingIterations,
4873-
SE.getConstant(TCType, MaxTripCount))) {
4874-
MaxTripCount =
4875-
SE.getUnsignedRangeMax(RemainingIterations).getZExtValue();
4876-
}
4877-
LLVM_DEBUG(dbgs() << "LEV: Maximum Trip Count for Epilogue: "
4878-
<< MaxTripCount << "\n");
48794856
}
48804857
if (SE.isKnownPredicate(
48814858
CmpInst::ICMP_UGT,
@@ -4884,8 +4861,7 @@ VectorizationFactor LoopVectorizationPlanner::selectEpilogueVectorizationFactor(
48844861
continue;
48854862
}
48864863

4887-
if (Result.Width.isScalar() ||
4888-
isMoreProfitable(NextVF, Result, MaxTripCount))
4864+
if (Result.Width.isScalar() || isMoreProfitable(NextVF, Result))
48894865
Result = NextVF;
48904866
}
48914867

llvm/test/Transforms/LoopVectorize/AArch64/deterministic-type-shrinkage.ll

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ define void @test_pr25490(i32 %n, ptr noalias nocapture %a, ptr noalias nocaptur
1616
; CHECK-NEXT: br i1 [[CMP_28]], label [[FOR_COND_CLEANUP:%.*]], label [[ITER_CHECK:%.*]]
1717
; CHECK: iter.check:
1818
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[N]] to i64
19-
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[N]], 4
19+
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[N]], 8
2020
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[VEC_EPILOG_SCALAR_PH:%.*]], label [[VECTOR_MAIN_LOOP_ITER_CHECK:%.*]]
2121
; CHECK: vector.main.loop.iter.check:
2222
; CHECK-NEXT: [[MIN_ITERS_CHECK1:%.*]] = icmp ult i32 [[N]], 16
@@ -50,33 +50,33 @@ define void @test_pr25490(i32 %n, ptr noalias nocapture %a, ptr noalias nocaptur
5050
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N_VEC]], [[TMP0]]
5151
; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[VEC_EPILOG_ITER_CHECK:%.*]]
5252
; CHECK: vec.epilog.iter.check:
53-
; CHECK-NEXT: [[N_VEC_REMAINING:%.*]] = and i64 [[TMP0]], 12
54-
; CHECK-NEXT: [[MIN_EPILOG_ITERS_CHECK:%.*]] = icmp eq i64 [[N_VEC_REMAINING]], 0
55-
; CHECK-NEXT: br i1 [[MIN_EPILOG_ITERS_CHECK]], label [[VEC_EPILOG_SCALAR_PH]], label [[VEC_EPILOG_PH]]
53+
; CHECK-NEXT: [[N_VEC_REMAINING:%.*]] = and i64 [[TMP0]], 8
54+
; CHECK-NEXT: [[MIN_EPILOG_ITERS_CHECK_NOT_NOT:%.*]] = icmp eq i64 [[N_VEC_REMAINING]], 0
55+
; CHECK-NEXT: br i1 [[MIN_EPILOG_ITERS_CHECK_NOT_NOT]], label [[VEC_EPILOG_SCALAR_PH]], label [[VEC_EPILOG_PH]]
5656
; CHECK: vec.epilog.ph:
5757
; CHECK-NEXT: [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_MAIN_LOOP_ITER_CHECK]] ]
58-
; CHECK-NEXT: [[N_VEC5:%.*]] = and i64 [[TMP0]], 4294967292
58+
; CHECK-NEXT: [[N_VEC5:%.*]] = and i64 [[TMP0]], 4294967288
5959
; CHECK-NEXT: br label [[VEC_EPILOG_VECTOR_BODY:%.*]]
6060
; CHECK: vec.epilog.vector.body:
6161
; CHECK-NEXT: [[INDEX6:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT10:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ]
6262
; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 [[INDEX6]]
63-
; CHECK-NEXT: [[WIDE_LOAD7:%.*]] = load <4 x i8>, ptr [[TMP14]], align 1
63+
; CHECK-NEXT: [[WIDE_LOAD7:%.*]] = load <8 x i8>, ptr [[TMP14]], align 1
6464
; CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDEX6]]
65-
; CHECK-NEXT: [[WIDE_LOAD8:%.*]] = load <4 x i8>, ptr [[TMP15]], align 1
66-
; CHECK-NEXT: [[TMP16:%.*]] = zext <4 x i8> [[WIDE_LOAD8]] to <4 x i16>
67-
; CHECK-NEXT: [[TMP17:%.*]] = zext <4 x i8> [[WIDE_LOAD7]] to <4 x i16>
68-
; CHECK-NEXT: [[TMP18:%.*]] = mul nuw <4 x i16> [[TMP16]], [[TMP17]]
69-
; CHECK-NEXT: [[TMP19:%.*]] = lshr <4 x i16> [[TMP18]], splat (i16 8)
70-
; CHECK-NEXT: [[TMP20:%.*]] = trunc nuw <4 x i16> [[TMP19]] to <4 x i8>
71-
; CHECK-NEXT: store <4 x i8> [[TMP20]], ptr [[TMP15]], align 1
65+
; CHECK-NEXT: [[WIDE_LOAD8:%.*]] = load <8 x i8>, ptr [[TMP15]], align 1
66+
; CHECK-NEXT: [[TMP16:%.*]] = zext <8 x i8> [[WIDE_LOAD8]] to <8 x i16>
67+
; CHECK-NEXT: [[TMP17:%.*]] = zext <8 x i8> [[WIDE_LOAD7]] to <8 x i16>
68+
; CHECK-NEXT: [[TMP18:%.*]] = mul nuw <8 x i16> [[TMP16]], [[TMP17]]
69+
; CHECK-NEXT: [[TMP19:%.*]] = lshr <8 x i16> [[TMP18]], splat (i16 8)
70+
; CHECK-NEXT: [[TMP20:%.*]] = trunc nuw <8 x i16> [[TMP19]] to <8 x i8>
71+
; CHECK-NEXT: store <8 x i8> [[TMP20]], ptr [[TMP15]], align 1
7272
; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 [[INDEX6]]
73-
; CHECK-NEXT: [[WIDE_LOAD9:%.*]] = load <4 x i8>, ptr [[TMP21]], align 1
74-
; CHECK-NEXT: [[TMP22:%.*]] = zext <4 x i8> [[WIDE_LOAD9]] to <4 x i16>
75-
; CHECK-NEXT: [[TMP23:%.*]] = mul nuw <4 x i16> [[TMP22]], [[TMP17]]
76-
; CHECK-NEXT: [[TMP24:%.*]] = lshr <4 x i16> [[TMP23]], splat (i16 8)
77-
; CHECK-NEXT: [[TMP25:%.*]] = trunc nuw <4 x i16> [[TMP24]] to <4 x i8>
78-
; CHECK-NEXT: store <4 x i8> [[TMP25]], ptr [[TMP21]], align 1
79-
; CHECK-NEXT: [[INDEX_NEXT10]] = add nuw i64 [[INDEX6]], 4
73+
; CHECK-NEXT: [[WIDE_LOAD9:%.*]] = load <8 x i8>, ptr [[TMP21]], align 1
74+
; CHECK-NEXT: [[TMP22:%.*]] = zext <8 x i8> [[WIDE_LOAD9]] to <8 x i16>
75+
; CHECK-NEXT: [[TMP23:%.*]] = mul nuw <8 x i16> [[TMP22]], [[TMP17]]
76+
; CHECK-NEXT: [[TMP24:%.*]] = lshr <8 x i16> [[TMP23]], splat (i16 8)
77+
; CHECK-NEXT: [[TMP25:%.*]] = trunc nuw <8 x i16> [[TMP24]] to <8 x i8>
78+
; CHECK-NEXT: store <8 x i8> [[TMP25]], ptr [[TMP21]], align 1
79+
; CHECK-NEXT: [[INDEX_NEXT10]] = add nuw i64 [[INDEX6]], 8
8080
; CHECK-NEXT: [[TMP26:%.*]] = icmp eq i64 [[INDEX_NEXT10]], [[N_VEC5]]
8181
; CHECK-NEXT: br i1 [[TMP26]], label [[VEC_EPILOG_MIDDLE_BLOCK:%.*]], label [[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
8282
; CHECK: vec.epilog.middle.block:

0 commit comments

Comments
 (0)