@@ -6000,7 +6000,9 @@ static bool BrPHIToSelect(DominatorTree &DT, BranchInst *BI, PHINode *Merge,
6000
6000
return false;
6001
6001
}
6002
6002
6003
- const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
6003
+ static bool getOperandsForSelectLikePHI(DominatorTree &DT, PHINode *PN,
6004
+ Value *&Cond, Value *&LHS,
6005
+ Value *&RHS) {
6004
6006
auto IsReachable =
6005
6007
[&](BasicBlock *BB) { return DT.isReachableFromEntry(BB); };
6006
6008
if (PN->getNumIncomingValues() == 2 && all_of(PN->blocks(), IsReachable)) {
@@ -6020,29 +6022,23 @@ const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
6020
6022
assert(IDom && "At least the entry block should dominate PN");
6021
6023
6022
6024
auto *BI = dyn_cast<BranchInst>(IDom->getTerminator());
6023
- Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
6024
-
6025
- if (BI && BI->isConditional() &&
6026
- BrPHIToSelect(DT, BI, PN, Cond, LHS, RHS) &&
6027
- properlyDominates(getSCEV(LHS), PN->getParent()) &&
6028
- properlyDominates(getSCEV(RHS), PN->getParent()))
6029
- return createNodeForSelectOrPHI(PN, Cond, LHS, RHS);
6025
+ return BI && BI->isConditional() &&
6026
+ BrPHIToSelect(DT, BI, PN, Cond, LHS, RHS);
6030
6027
}
6028
+ return false;
6029
+ }
6030
+
6031
+ const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
6032
+ Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
6033
+ if (getOperandsForSelectLikePHI(DT, PN, Cond, LHS, RHS) &&
6034
+ properlyDominates(getSCEV(LHS), PN->getParent()) &&
6035
+ properlyDominates(getSCEV(RHS), PN->getParent()))
6036
+ return createNodeForSelectOrPHI(PN, Cond, LHS, RHS);
6031
6037
6032
6038
return nullptr;
6033
6039
}
6034
6040
6035
- /// Returns SCEV for the first operand of a phi if all phi operands have
6036
- /// identical opcodes and operands
6037
- /// eg.
6038
- /// a: %add = %a + %b
6039
- /// br %c
6040
- /// b: %add1 = %a + %b
6041
- /// br %c
6042
- /// c: %phi = phi [%add, a], [%add1, b]
6043
- /// scev(%phi) => scev(%add)
6044
- const SCEV *
6045
- ScalarEvolution::createNodeForPHIWithIdenticalOperands(PHINode *PN) {
6041
+ static BinaryOperator *getCommonInstForPHI(PHINode *PN) {
6046
6042
BinaryOperator *CommonInst = nullptr;
6047
6043
// Check if instructions are identical.
6048
6044
for (Value *Incoming : PN->incoming_values()) {
@@ -6057,6 +6053,21 @@ ScalarEvolution::createNodeForPHIWithIdenticalOperands(PHINode *PN) {
6057
6053
CommonInst = IncomingInst;
6058
6054
}
6059
6055
}
6056
+ return CommonInst;
6057
+ }
6058
+
6059
+ /// Returns SCEV for the first operand of a phi if all phi operands have
6060
+ /// identical opcodes and operands
6061
+ /// eg.
6062
+ /// a: %add = %a + %b
6063
+ /// br %c
6064
+ /// b: %add1 = %a + %b
6065
+ /// br %c
6066
+ /// c: %phi = phi [%add, a], [%add1, b]
6067
+ /// scev(%phi) => scev(%add)
6068
+ const SCEV *
6069
+ ScalarEvolution::createNodeForPHIWithIdenticalOperands(PHINode *PN) {
6070
+ BinaryOperator *CommonInst = getCommonInstForPHI(PN);
6060
6071
if (!CommonInst)
6061
6072
return nullptr;
6062
6073
@@ -6581,6 +6592,28 @@ getRangeForUnknownRecurrence(const SCEVUnknown *U) {
6581
6592
return FullSet;
6582
6593
}
6583
6594
6595
+ // The goal of this function is to check if recursively visiting the operands
6596
+ // of this PHI might lead to an infinite loop. If we do see such a loop,
6597
+ // there's no good way to break it, so we avoid analyzing such cases.
6598
+ //
6599
+ // getRangeRef previously used a visited set to avoid infinite loops, but this
6600
+ // caused other issues: the result was dependent on the order of getRangeRef
6601
+ // calls, and the interaction with createSCEVIter could cause a stack overflow
6602
+ // in some cases (see issue #148253).
6603
+ //
6604
+ // FIXME: The way this is implemented is overly conservative.
6605
+ static bool RangeRefPHIAllowedOperands(DominatorTree &DT, PHINode *PH) {
6606
+ Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
6607
+ if (getOperandsForSelectLikePHI(DT, PH, Cond, LHS, RHS))
6608
+ return true;
6609
+
6610
+ if (all_of(PH->operands(),
6611
+ [&](Value *Operand) { return DT.dominates(Operand, PH); }))
6612
+ return true;
6613
+
6614
+ return false;
6615
+ }
6616
+
6584
6617
const ConstantRange &
6585
6618
ScalarEvolution::getRangeRefIter(const SCEV *S,
6586
6619
ScalarEvolution::RangeSignHint SignHint) {
@@ -6636,8 +6669,8 @@ ScalarEvolution::getRangeRefIter(const SCEV *S,
6636
6669
continue;
6637
6670
}
6638
6671
// `SCEVUnknown`'s require special treatment.
6639
- if (const PHINode *P = dyn_cast<PHINode>(UnknownS->getValue())) {
6640
- if (!PendingPhiRangesIter.insert(P).second )
6672
+ if (PHINode *P = dyn_cast<PHINode>(UnknownS->getValue())) {
6673
+ if (!RangeRefPHIAllowedOperands(DT, P) )
6641
6674
continue;
6642
6675
for (auto &Op : reverse(P->operands()))
6643
6676
AddToWorklist(getSCEV(Op));
@@ -6650,10 +6683,6 @@ ScalarEvolution::getRangeRefIter(const SCEV *S,
6650
6683
// their users in most cases.
6651
6684
for (const SCEV *P : reverse(drop_begin(WorkList))) {
6652
6685
getRangeRef(P, SignHint);
6653
-
6654
- if (auto *UnknownS = dyn_cast<SCEVUnknown>(P))
6655
- if (const PHINode *P = dyn_cast<PHINode>(UnknownS->getValue()))
6656
- PendingPhiRangesIter.erase(P);
6657
6686
}
6658
6687
}
6659
6688
@@ -6963,8 +6992,13 @@ const ConstantRange &ScalarEvolution::getRangeRef(
6963
6992
6964
6993
// A range of Phi is a subset of union of all ranges of its input.
6965
6994
if (PHINode *Phi = dyn_cast<PHINode>(V)) {
6995
+ // SCEVExpander sometimes creates SCEVUnknowns that are secretly
6996
+ // AddRecs; return the range for the corresponding AddRec.
6997
+ if (auto *AR = dyn_cast<SCEVAddRecExpr>(getSCEV(V)))
6998
+ return getRangeRef(AR, SignHint, Depth + 1);
6999
+
6966
7000
// Make sure that we do not run over cycled Phis.
6967
- if (PendingPhiRanges.insert( Phi).second ) {
7001
+ if (RangeRefPHIAllowedOperands(DT, Phi)) {
6968
7002
ConstantRange RangeFromOps(BitWidth, /*isFullSet=*/false);
6969
7003
6970
7004
for (const auto &Op : Phi->operands()) {
@@ -6976,9 +7010,6 @@ const ConstantRange &ScalarEvolution::getRangeRef(
6976
7010
}
6977
7011
ConservativeResult =
6978
7012
ConservativeResult.intersectWith(RangeFromOps, RangeType);
6979
- bool Erased = PendingPhiRanges.erase(Phi);
6980
- assert(Erased && "Failed to erase Phi properly?");
6981
- (void)Erased;
6982
7013
}
6983
7014
}
6984
7015
@@ -7657,7 +7688,55 @@ ScalarEvolution::getOperandsToCreate(Value *V, SmallVectorImpl<Value *> &Ops) {
7657
7688
return getUnknown(V);
7658
7689
7659
7690
case Instruction::PHI:
7660
- // Keep constructing SCEVs' for phis recursively for now.
7691
+ // getNodeForPHI has four ways to turn a PHI into a SCEV; retrieve the
7692
+ // relevant nodes for each of them.
7693
+ //
7694
+ // The first is just to call simplifyInstruction, and get something back
7695
+ // that isn't a PHI.
7696
+ if (Value *V = simplifyInstruction(
7697
+ cast<PHINode>(U),
7698
+ {getDataLayout(), &TLI, &DT, &AC, /*CtxI=*/nullptr,
7699
+ /*UseInstrInfo=*/true, /*CanUseUndef=*/false})) {
7700
+ assert(V);
7701
+ Ops.push_back(V);
7702
+ return nullptr;
7703
+ }
7704
+ // The second is createNodeForPHIWithIdenticalOperands: this looks for
7705
+ // operands which all perform the same operation, but haven't been
7706
+ // CSE'ed for whatever reason.
7707
+ if (BinaryOperator *BO = getCommonInstForPHI(cast<PHINode>(U))) {
7708
+ assert(BO);
7709
+ Ops.push_back(BO);
7710
+ return nullptr;
7711
+ }
7712
+ // The third is createNodeFromSelectLikePHI; this takes a PHI which
7713
+ // is equivalent to a select, and analyzes it like a select.
7714
+ {
7715
+ Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
7716
+ if (getOperandsForSelectLikePHI(DT, cast<PHINode>(U), Cond, LHS, RHS)) {
7717
+ assert(Cond);
7718
+ assert(LHS);
7719
+ assert(RHS);
7720
+ if (auto *CondICmp = dyn_cast<ICmpInst>(Cond)) {
7721
+ Ops.push_back(CondICmp->getOperand(0));
7722
+ Ops.push_back(CondICmp->getOperand(1));
7723
+ }
7724
+ Ops.push_back(Cond);
7725
+ Ops.push_back(LHS);
7726
+ Ops.push_back(RHS);
7727
+ return nullptr;
7728
+ }
7729
+ }
7730
+ // The fourth way is createAddRecFromPHI. It's complicated to handle here,
7731
+ // so just construct it recursively.
7732
+ //
7733
+ // In addition to getNodeForPHI, also construct nodes which might be needed
7734
+ // by getRangeRef.
7735
+ if (RangeRefPHIAllowedOperands(DT, cast<PHINode>(U))) {
7736
+ for (Value *V : cast<PHINode>(U)->operands())
7737
+ Ops.push_back(V);
7738
+ return nullptr;
7739
+ }
7661
7740
return nullptr;
7662
7741
7663
7742
case Instruction::Select: {
@@ -13728,7 +13807,6 @@ ScalarEvolution::ScalarEvolution(ScalarEvolution &&Arg)
13728
13807
DT(Arg.DT), LI(Arg.LI), CouldNotCompute(std::move(Arg.CouldNotCompute)),
13729
13808
ValueExprMap(std::move(Arg.ValueExprMap)),
13730
13809
PendingLoopPredicates(std::move(Arg.PendingLoopPredicates)),
13731
- PendingPhiRanges(std::move(Arg.PendingPhiRanges)),
13732
13810
PendingMerges(std::move(Arg.PendingMerges)),
13733
13811
ConstantMultipleCache(std::move(Arg.ConstantMultipleCache)),
13734
13812
BackedgeTakenCounts(std::move(Arg.BackedgeTakenCounts)),
@@ -13771,7 +13849,6 @@ ScalarEvolution::~ScalarEvolution() {
13771
13849
PredicatedBackedgeTakenCounts.clear();
13772
13850
13773
13851
assert(PendingLoopPredicates.empty() && "isImpliedCond garbage");
13774
- assert(PendingPhiRanges.empty() && "getRangeRef garbage");
13775
13852
assert(PendingMerges.empty() && "isImpliedViaMerge garbage");
13776
13853
assert(!WalkingBEDominatingConds && "isLoopBackedgeGuardedByCond garbage!");
13777
13854
assert(!ProvingSplitPredicate && "ProvingSplitPredicate garbage!");
0 commit comments