Skip to content

Commit 954097d

Browse files
committed
[VPlan] Use SCEV to check subtract in getOptimizableIVOf.
Simplify checks for IV subtractions in getOptimizableIVOf by using SCEV. This slightly generalizes the patterns we can handle.
1 parent 8afde84 commit 954097d

File tree

4 files changed

+25
-22
lines changed

4 files changed

+25
-22
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8908,7 +8908,7 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(
89088908
VPlanTransforms::addActiveLaneMask(*Plan, ForControlFlow,
89098909
WithoutRuntimeCheck);
89108910
}
8911-
VPlanTransforms::optimizeInductionExitUsers(*Plan, IVEndValues);
8911+
VPlanTransforms::optimizeInductionExitUsers(*Plan, IVEndValues, *PSE.getSE());
89128912

89138913
assert(verifyVPlanIsValid(*Plan) && "VPlan is invalid");
89148914
return Plan;

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,8 @@ static void legalizeAndOptimizeInductions(VPlan &Plan) {
716716
/// Check if \p VPV is an untruncated wide induction, either before or after the
717717
/// increment. If so return the header IV (before the increment), otherwise
718718
/// return null.
719-
static VPWidenInductionRecipe *getOptimizableIVOf(VPValue *VPV) {
719+
static VPWidenInductionRecipe *getOptimizableIVOf(VPValue *VPV,
720+
ScalarEvolution &SE) {
720721
auto *WideIV = dyn_cast<VPWidenInductionRecipe>(VPV);
721722
if (WideIV) {
722723
// VPV itself is a wide induction, separately compute the end value for exit
@@ -753,13 +754,13 @@ static VPWidenInductionRecipe *getOptimizableIVOf(VPValue *VPV) {
753754
// IVStep will be the negated step of the subtraction. Check if Step == -1
754755
// * IVStep.
755756
VPValue *Step;
756-
if (!match(VPV, m_Sub(m_VPValue(), m_VPValue(Step))) ||
757-
!Step->isLiveIn() || !IVStep->isLiveIn())
757+
if (!match(VPV, m_Sub(m_VPValue(), m_VPValue(Step))))
758758
return false;
759-
auto *StepCI = dyn_cast<ConstantInt>(Step->getLiveInIRValue());
760-
auto *IVStepCI = dyn_cast<ConstantInt>(IVStep->getLiveInIRValue());
761-
return StepCI && IVStepCI &&
762-
StepCI->getValue() == (-1 * IVStepCI->getValue());
759+
const SCEV *IVStepSCEV = vputils::getSCEVExprForVPValue(IVStep, SE);
760+
const SCEV *StepSCEV = vputils::getSCEVExprForVPValue(Step, SE);
761+
return !isa<SCEVCouldNotCompute>(IVStepSCEV) &&
762+
!isa<SCEVCouldNotCompute>(StepSCEV) &&
763+
IVStepSCEV == SE.getNegativeSCEV(StepSCEV);
763764
}
764765
default:
765766
return ID.getKind() == InductionDescriptor::IK_PtrInduction &&
@@ -776,15 +777,16 @@ static VPWidenInductionRecipe *getOptimizableIVOf(VPValue *VPV) {
776777
static VPValue *optimizeEarlyExitInductionUser(VPlan &Plan,
777778
VPTypeAnalysis &TypeInfo,
778779
VPBlockBase *PredVPBB,
779-
VPValue *Op) {
780+
VPValue *Op,
781+
ScalarEvolution &SE) {
780782
VPValue *Incoming, *Mask;
781783
if (!match(Op, m_VPInstruction<VPInstruction::ExtractLane>(
782784
m_VPInstruction<VPInstruction::FirstActiveLane>(
783785
m_VPValue(Mask)),
784786
m_VPValue(Incoming))))
785787
return nullptr;
786788

787-
auto *WideIV = getOptimizableIVOf(Incoming);
789+
auto *WideIV = getOptimizableIVOf(Incoming, SE);
788790
if (!WideIV)
789791
return nullptr;
790792

@@ -827,15 +829,14 @@ static VPValue *optimizeEarlyExitInductionUser(VPlan &Plan,
827829

828830
/// Attempts to optimize the induction variable exit values for users in the
829831
/// exit block coming from the latch in the original scalar loop.
830-
static VPValue *
831-
optimizeLatchExitInductionUser(VPlan &Plan, VPTypeAnalysis &TypeInfo,
832-
VPBlockBase *PredVPBB, VPValue *Op,
833-
DenseMap<VPValue *, VPValue *> &EndValues) {
832+
static VPValue *optimizeLatchExitInductionUser(
833+
VPlan &Plan, VPTypeAnalysis &TypeInfo, VPBlockBase *PredVPBB, VPValue *Op,
834+
DenseMap<VPValue *, VPValue *> &EndValues, ScalarEvolution &SE) {
834835
VPValue *Incoming;
835836
if (!match(Op, m_ExtractLastElement(m_VPValue(Incoming))))
836837
return nullptr;
837838

838-
auto *WideIV = getOptimizableIVOf(Incoming);
839+
auto *WideIV = getOptimizableIVOf(Incoming, SE);
839840
if (!WideIV)
840841
return nullptr;
841842

@@ -874,7 +875,8 @@ optimizeLatchExitInductionUser(VPlan &Plan, VPTypeAnalysis &TypeInfo,
874875
}
875876

876877
void VPlanTransforms::optimizeInductionExitUsers(
877-
VPlan &Plan, DenseMap<VPValue *, VPValue *> &EndValues) {
878+
VPlan &Plan, DenseMap<VPValue *, VPValue *> &EndValues,
879+
ScalarEvolution &SE) {
878880
VPBlockBase *MiddleVPBB = Plan.getMiddleBlock();
879881
VPTypeAnalysis TypeInfo(Plan);
880882
for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks()) {
@@ -884,11 +886,12 @@ void VPlanTransforms::optimizeInductionExitUsers(
884886
for (auto [Idx, PredVPBB] : enumerate(ExitVPBB->getPredecessors())) {
885887
VPValue *Escape = nullptr;
886888
if (PredVPBB == MiddleVPBB)
887-
Escape = optimizeLatchExitInductionUser(
888-
Plan, TypeInfo, PredVPBB, ExitIRI->getOperand(Idx), EndValues);
889+
Escape = optimizeLatchExitInductionUser(Plan, TypeInfo, PredVPBB,
890+
ExitIRI->getOperand(Idx),
891+
EndValues, SE);
889892
else
890893
Escape = optimizeEarlyExitInductionUser(Plan, TypeInfo, PredVPBB,
891-
ExitIRI->getOperand(Idx));
894+
ExitIRI->getOperand(Idx), SE);
892895
if (Escape)
893896
ExitIRI->setOperand(Idx, Escape);
894897
}

llvm/lib/Transforms/Vectorize/VPlanTransforms.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ struct VPlanTransforms {
247247
/// one step backwards.
248248
static void
249249
optimizeInductionExitUsers(VPlan &Plan,
250-
DenseMap<VPValue *, VPValue *> &EndValues);
250+
DenseMap<VPValue *, VPValue *> &EndValues,
251+
ScalarEvolution &SE);
251252

252253
/// Add explicit broadcasts for live-ins and VPValues defined in \p Plan's entry block if they are used as vectors.
253254
static void materializeBroadcasts(VPlan &Plan);

llvm/test/Transforms/LoopVectorize/X86/induction-step.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ define i16 @wide_sub_induction_step_live_in(ptr %dst, i64 %N, i16 %off) {
111111
; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
112112
; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
113113
; CHECK: middle.block:
114-
; CHECK-NEXT: [[TMP11:%.*]] = extractelement <4 x i16> [[TMP10]], i32 3
115114
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
116115
; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]
117116
; CHECK: scalar.ph:
@@ -128,7 +127,7 @@ define i16 @wide_sub_induction_step_live_in(ptr %dst, i64 %N, i16 %off) {
128127
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
129128
; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]
130129
; CHECK: exit:
131-
; CHECK-NEXT: [[SUB_LCSSA:%.*]] = phi i16 [ [[SUB]], [[LOOP]] ], [ [[TMP11]], [[MIDDLE_BLOCK]] ]
130+
; CHECK-NEXT: [[SUB_LCSSA:%.*]] = phi i16 [ [[SUB]], [[LOOP]] ], [ [[TMP1]], [[MIDDLE_BLOCK]] ]
132131
; CHECK-NEXT: ret i16 [[SUB_LCSSA]]
133132
;
134133
entry:

0 commit comments

Comments
 (0)