@@ -716,7 +716,8 @@ static void legalizeAndOptimizeInductions(VPlan &Plan) {
716
716
// / Check if \p VPV is an untruncated wide induction, either before or after the
717
717
// / increment. If so return the header IV (before the increment), otherwise
718
718
// / return null.
719
- static VPWidenInductionRecipe *getOptimizableIVOf (VPValue *VPV) {
719
+ static VPWidenInductionRecipe *getOptimizableIVOf (VPValue *VPV,
720
+ ScalarEvolution &SE) {
720
721
auto *WideIV = dyn_cast<VPWidenInductionRecipe>(VPV);
721
722
if (WideIV) {
722
723
// VPV itself is a wide induction, separately compute the end value for exit
@@ -753,13 +754,13 @@ static VPWidenInductionRecipe *getOptimizableIVOf(VPValue *VPV) {
753
754
// IVStep will be the negated step of the subtraction. Check if Step == -1
754
755
// * IVStep.
755
756
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))))
758
758
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);
763
764
}
764
765
default :
765
766
return ID.getKind () == InductionDescriptor::IK_PtrInduction &&
@@ -776,15 +777,16 @@ static VPWidenInductionRecipe *getOptimizableIVOf(VPValue *VPV) {
776
777
static VPValue *optimizeEarlyExitInductionUser (VPlan &Plan,
777
778
VPTypeAnalysis &TypeInfo,
778
779
VPBlockBase *PredVPBB,
779
- VPValue *Op) {
780
+ VPValue *Op,
781
+ ScalarEvolution &SE) {
780
782
VPValue *Incoming, *Mask;
781
783
if (!match (Op, m_VPInstruction<VPInstruction::ExtractLane>(
782
784
m_VPInstruction<VPInstruction::FirstActiveLane>(
783
785
m_VPValue (Mask)),
784
786
m_VPValue (Incoming))))
785
787
return nullptr ;
786
788
787
- auto *WideIV = getOptimizableIVOf (Incoming);
789
+ auto *WideIV = getOptimizableIVOf (Incoming, SE );
788
790
if (!WideIV)
789
791
return nullptr ;
790
792
@@ -827,15 +829,14 @@ static VPValue *optimizeEarlyExitInductionUser(VPlan &Plan,
827
829
828
830
// / Attempts to optimize the induction variable exit values for users in the
829
831
// / 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) {
834
835
VPValue *Incoming;
835
836
if (!match (Op, m_ExtractLastElement (m_VPValue (Incoming))))
836
837
return nullptr ;
837
838
838
- auto *WideIV = getOptimizableIVOf (Incoming);
839
+ auto *WideIV = getOptimizableIVOf (Incoming, SE );
839
840
if (!WideIV)
840
841
return nullptr ;
841
842
@@ -874,7 +875,8 @@ optimizeLatchExitInductionUser(VPlan &Plan, VPTypeAnalysis &TypeInfo,
874
875
}
875
876
876
877
void VPlanTransforms::optimizeInductionExitUsers (
877
- VPlan &Plan, DenseMap<VPValue *, VPValue *> &EndValues) {
878
+ VPlan &Plan, DenseMap<VPValue *, VPValue *> &EndValues,
879
+ ScalarEvolution &SE) {
878
880
VPBlockBase *MiddleVPBB = Plan.getMiddleBlock ();
879
881
VPTypeAnalysis TypeInfo (Plan);
880
882
for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks ()) {
@@ -884,11 +886,12 @@ void VPlanTransforms::optimizeInductionExitUsers(
884
886
for (auto [Idx, PredVPBB] : enumerate(ExitVPBB->getPredecessors ())) {
885
887
VPValue *Escape = nullptr ;
886
888
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);
889
892
else
890
893
Escape = optimizeEarlyExitInductionUser (Plan, TypeInfo, PredVPBB,
891
- ExitIRI->getOperand (Idx));
894
+ ExitIRI->getOperand (Idx), SE );
892
895
if (Escape)
893
896
ExitIRI->setOperand (Idx, Escape);
894
897
}
0 commit comments