@@ -197,6 +197,8 @@ struct State {
197197 // / controlling the loop header.
198198 void addInfoForInductions (BasicBlock &BB);
199199
200+ void addConditionFactsIntoLoopHeader (BasicBlock &BB);
201+
200202 // / Returns true if we can add a known condition from BB to its successor
201203 // / block Succ.
202204 bool canAddSuccessor (BasicBlock &BB, BasicBlock *Succ) const {
@@ -900,7 +902,60 @@ static void dumpConstraint(ArrayRef<int64_t> C,
900902}
901903#endif
902904
905+ // For monotonically decreasing/increasing variables in the loop,
906+ // this will insert ConditionFact PN >= StartingValue or PN <= StartingValue
907+ // associated with the loop header, where PN is the corresponding PHi node.
908+ void State::addConditionFactsIntoLoopHeader (BasicBlock &BB) {
909+ auto *L = LI.getLoopFor (&BB);
910+ if (!L || L->getHeader () != &BB)
911+ return ;
912+ DomTreeNode *DTN = DT.getNode (&BB);
913+ for (PHINode &PN :L->getHeader ()->phis ()){
914+ if (PN.getNumIncomingValues () != 2 || PN.getParent () != &BB || !SE.isSCEVable (PN.getType ()))
915+ continue ;
916+ auto *AR = dyn_cast_or_null<SCEVAddRecExpr>(SE.getSCEV (&PN));
917+ BasicBlock *LoopPred = L->getLoopPredecessor ();
918+ if (!AR || AR->getLoop () != L || !LoopPred)
919+ return ;
920+ const SCEV *StartSCEV = AR->getStart ();
921+ Value *StartValue = nullptr ;
922+ if (auto *C = dyn_cast<SCEVConstant>(StartSCEV)) {
923+ StartValue = C->getValue ();
924+ } else {
925+ StartValue = PN.getIncomingValueForBlock (LoopPred);
926+ assert (SE.getSCEV (StartValue) == StartSCEV && " inconsistent start value" );
927+ }
928+ auto IncUnsigned = SE.getMonotonicPredicateType (AR, CmpInst::ICMP_UGT);
929+ auto IncSigned = SE.getMonotonicPredicateType (AR, CmpInst::ICMP_SGT);
930+
931+ // Monotonically Increasing
932+ bool MonotonicallyIncreasingUnsigned =
933+ IncUnsigned && *IncUnsigned == ScalarEvolution::MonotonicallyIncreasing;
934+ bool MonotonicallyIncreasingSigned =
935+ IncSigned && *IncSigned == ScalarEvolution::MonotonicallyIncreasing;
936+ if (MonotonicallyIncreasingUnsigned)
937+ WorkList.push_back (
938+ FactOrCheck::getConditionFact (DTN, CmpInst::ICMP_UGE, &PN, StartValue));
939+ if (MonotonicallyIncreasingSigned)
940+ WorkList.push_back (
941+ FactOrCheck::getConditionFact (DTN, CmpInst::ICMP_SGE, &PN, StartValue));
942+
943+ // Monotonically Decreasing
944+ bool MonotonicallyDecreasingUnsigned =
945+ IncUnsigned && *IncUnsigned == ScalarEvolution::MonotonicallyDecreasing;
946+ bool MonotonicallyDecreasingSigned =
947+ IncSigned && *IncSigned == ScalarEvolution::MonotonicallyDecreasing;
948+ if (MonotonicallyDecreasingUnsigned)
949+ WorkList.push_back (
950+ FactOrCheck::getConditionFact (DTN, CmpInst::ICMP_ULE, &PN, StartValue));
951+ if (MonotonicallyDecreasingSigned)
952+ WorkList.push_back (
953+ FactOrCheck::getConditionFact (DTN, CmpInst::ICMP_SLE, &PN, StartValue));
954+ }
955+ }
956+
903957void State::addInfoForInductions (BasicBlock &BB) {
958+ addConditionFactsIntoLoopHeader (BB);
904959 auto *L = LI.getLoopFor (&BB);
905960 if (!L || L->getHeader () != &BB)
906961 return ;
0 commit comments