@@ -83,6 +83,16 @@ static Instruction *getContextInstForUse(Use &U) {
8383}
8484
8585namespace {
86+ // / Struct to express a condition of the form %Op0 Pred %Op1.
87+ struct ConditionTy {
88+ CmpInst::Predicate Pred;
89+ Value *Op0;
90+ Value *Op1;
91+
92+ ConditionTy (CmpInst::Predicate Pred, Value *Op0, Value *Op1)
93+ : Pred(Pred), Op0(Op0), Op1(Op1) {}
94+ };
95+
8696// / Represents either
8797// / * a condition that holds on entry to a block (=condition fact)
8898// / * an assume (=assume fact)
@@ -101,37 +111,45 @@ struct FactOrCheck {
101111 union {
102112 Instruction *Inst;
103113 Use *U;
114+ ConditionTy Cond;
104115 };
105116
106117 unsigned NumIn;
107118 unsigned NumOut;
108119 EntryTy Ty;
109- bool Not;
110120
111- FactOrCheck (EntryTy Ty, DomTreeNode *DTN, Instruction *Inst, bool Not )
121+ FactOrCheck (EntryTy Ty, DomTreeNode *DTN, Instruction *Inst)
112122 : Inst(Inst), NumIn(DTN->getDFSNumIn ()), NumOut(DTN->getDFSNumOut ()),
113- Ty(Ty), Not(Not) {}
123+ Ty(Ty) {}
114124
115125 FactOrCheck (DomTreeNode *DTN, Use *U)
116126 : U(U), NumIn(DTN->getDFSNumIn ()), NumOut(DTN->getDFSNumOut ()),
117- Ty(EntryTy::UseCheck), Not( false ) {}
127+ Ty(EntryTy::UseCheck) {}
118128
119- static FactOrCheck getConditionFact (DomTreeNode *DTN, CmpInst *Inst,
120- bool Not = false ) {
121- return FactOrCheck (EntryTy::ConditionFact, DTN, Inst, Not);
129+ FactOrCheck (DomTreeNode *DTN, CmpInst::Predicate Pred, Value *Op0, Value *Op1)
130+ : Cond(Pred, Op0, Op1), NumIn(DTN->getDFSNumIn ()),
131+ NumOut(DTN->getDFSNumOut ()), Ty(EntryTy::ConditionFact) {}
132+
133+ static FactOrCheck getConditionFact (DomTreeNode *DTN, CmpInst::Predicate Pred,
134+ Value *Op0, Value *Op1) {
135+ return FactOrCheck (DTN, Pred, Op0, Op1);
136+ }
137+
138+ static FactOrCheck getInstFact (DomTreeNode *DTN, Instruction *Inst) {
139+ return FactOrCheck (EntryTy::InstFact, DTN, Inst);
122140 }
123141
124- static FactOrCheck getInstFact (DomTreeNode *DTN, Instruction *Inst ,
125- bool Not = false ) {
126- return FactOrCheck (EntryTy::InstFact, DTN, Inst, Not );
142+ static FactOrCheck getFact (DomTreeNode *DTN, CmpInst::Predicate Pred ,
143+ Value *Op0, Value *Op1 ) {
144+ return FactOrCheck (DTN, Pred, Op0, Op1 );
127145 }
128146
129147 static FactOrCheck getCheck (DomTreeNode *DTN, Use *U) {
130148 return FactOrCheck (DTN, U);
131149 }
132150
133151 static FactOrCheck getCheck (DomTreeNode *DTN, CallInst *CI) {
134- return FactOrCheck (EntryTy::InstCheck, DTN, CI, false );
152+ return FactOrCheck (EntryTy::InstCheck, DTN, CI);
135153 }
136154
137155 bool isCheck () const {
@@ -188,19 +206,9 @@ struct StackEntry {
188206 ValuesToRelease (ValuesToRelease) {}
189207};
190208
191- // / Struct to express a pre-condition of the form %Op0 Pred %Op1.
192- struct PreconditionTy {
193- CmpInst::Predicate Pred;
194- Value *Op0;
195- Value *Op1;
196-
197- PreconditionTy (CmpInst::Predicate Pred, Value *Op0, Value *Op1)
198- : Pred(Pred), Op0(Op0), Op1(Op1) {}
199- };
200-
201209struct ConstraintTy {
202210 SmallVector<int64_t , 8 > Coefficients;
203- SmallVector<PreconditionTy , 2 > Preconditions;
211+ SmallVector<ConditionTy , 2 > Preconditions;
204212
205213 SmallVector<SmallVector<int64_t , 8 >> ExtraInfo;
206214
@@ -346,17 +354,17 @@ struct Decomposition {
346354} // namespace
347355
348356static Decomposition decompose (Value *V,
349- SmallVectorImpl<PreconditionTy > &Preconditions,
357+ SmallVectorImpl<ConditionTy > &Preconditions,
350358 bool IsSigned, const DataLayout &DL);
351359
352360static bool canUseSExt (ConstantInt *CI) {
353361 const APInt &Val = CI->getValue ();
354362 return Val.sgt (MinSignedConstraintValue) && Val.slt (MaxConstraintValue);
355363}
356364
357- static Decomposition
358- decomposeGEP (GEPOperator &GEP, SmallVectorImpl<PreconditionTy > &Preconditions,
359- bool IsSigned, const DataLayout &DL) {
365+ static Decomposition decomposeGEP (GEPOperator &GEP,
366+ SmallVectorImpl<ConditionTy > &Preconditions,
367+ bool IsSigned, const DataLayout &DL) {
360368 // Do not reason about pointers where the index size is larger than 64 bits,
361369 // as the coefficients used to encode constraints are 64 bit integers.
362370 if (DL.getIndexTypeSizeInBits (GEP.getPointerOperand ()->getType ()) > 64 )
@@ -417,7 +425,7 @@ decomposeGEP(GEPOperator &GEP, SmallVectorImpl<PreconditionTy> &Preconditions,
417425// Variable } where Coefficient * Variable. The sum of the constant offset and
418426// pairs equals \p V.
419427static Decomposition decompose (Value *V,
420- SmallVectorImpl<PreconditionTy > &Preconditions,
428+ SmallVectorImpl<ConditionTy > &Preconditions,
421429 bool IsSigned, const DataLayout &DL) {
422430
423431 auto MergeResults = [&Preconditions, IsSigned, &DL](Value *A, Value *B,
@@ -560,7 +568,7 @@ ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
560568 Pred != CmpInst::ICMP_SLE && Pred != CmpInst::ICMP_SLT)
561569 return {};
562570
563- SmallVector<PreconditionTy , 4 > Preconditions;
571+ SmallVector<ConditionTy , 4 > Preconditions;
564572 bool IsSigned = CmpInst::isSigned (Pred);
565573 auto &Value2Index = getValue2Index (IsSigned);
566574 auto ADec = decompose (Op0->stripPointerCastsSameRepresentation (),
@@ -670,7 +678,7 @@ ConstraintTy ConstraintInfo::getConstraintForSolving(CmpInst::Predicate Pred,
670678
671679bool ConstraintTy::isValid (const ConstraintInfo &Info) const {
672680 return Coefficients.size () > 0 &&
673- all_of (Preconditions, [&Info](const PreconditionTy &C) {
681+ all_of (Preconditions, [&Info](const ConditionTy &C) {
674682 return Info.doesHold (C.Pred , C.Op0 , C.Op1 );
675683 });
676684}
@@ -805,15 +813,16 @@ void State::addInfoFor(BasicBlock &BB) {
805813 continue ;
806814 }
807815
808- Value *Cond;
816+ Value *A, *B;
817+ CmpInst::Predicate Pred;
809818 // For now, just handle assumes with a single compare as condition.
810- if (match (&I, m_Intrinsic<Intrinsic::assume>(m_Value (Cond))) &&
811- isa<ICmpInst>(Cond )) {
819+ if (match (&I, m_Intrinsic<Intrinsic::assume>(
820+ m_ICmp (Pred, m_Value (A), m_Value (B))) )) {
812821 if (GuaranteedToExecute) {
813822 // The assume is guaranteed to execute when BB is entered, hence Cond
814823 // holds on entry to BB.
815824 WorkList.emplace_back (FactOrCheck::getConditionFact (
816- DT.getNode (I.getParent ()), cast<CmpInst>(Cond) ));
825+ DT.getNode (I.getParent ()), Pred, A, B ));
817826 } else {
818827 WorkList.emplace_back (
819828 FactOrCheck::getInstFact (DT.getNode (I.getParent ()), &I));
@@ -853,8 +862,11 @@ void State::addInfoFor(BasicBlock &BB) {
853862 while (!CondWorkList.empty ()) {
854863 Value *Cur = CondWorkList.pop_back_val ();
855864 if (auto *Cmp = dyn_cast<ICmpInst>(Cur)) {
856- WorkList.emplace_back (
857- FactOrCheck::getConditionFact (DT.getNode (Successor), Cmp, IsOr));
865+ WorkList.emplace_back (FactOrCheck::getConditionFact (
866+ DT.getNode (Successor),
867+ IsOr ? CmpInst::getInversePredicate (Cmp->getPredicate ())
868+ : Cmp->getPredicate (),
869+ Cmp->getOperand (0 ), Cmp->getOperand (1 )));
858870 continue ;
859871 }
860872 if (IsOr && match (Cur, m_LogicalOr (m_Value (Op0), m_Value (Op1)))) {
@@ -876,11 +888,14 @@ void State::addInfoFor(BasicBlock &BB) {
876888 if (!CmpI)
877889 return ;
878890 if (canAddSuccessor (BB, Br->getSuccessor (0 )))
879- WorkList.emplace_back (
880- FactOrCheck::getConditionFact (DT.getNode (Br->getSuccessor (0 )), CmpI));
891+ WorkList.emplace_back (FactOrCheck::getConditionFact (
892+ DT.getNode (Br->getSuccessor (0 )), CmpI->getPredicate (),
893+ CmpI->getOperand (0 ), CmpI->getOperand (1 )));
881894 if (canAddSuccessor (BB, Br->getSuccessor (1 )))
882895 WorkList.emplace_back (FactOrCheck::getConditionFact (
883- DT.getNode (Br->getSuccessor (1 )), CmpI, true ));
896+ DT.getNode (Br->getSuccessor (1 )),
897+ CmpInst::getInversePredicate (CmpI->getPredicate ()), CmpI->getOperand (0 ),
898+ CmpI->getOperand (1 )));
884899}
885900
886901namespace {
@@ -1312,8 +1327,9 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT,
13121327 // transfer logic.
13131328 stable_sort (S.WorkList , [](const FactOrCheck &A, const FactOrCheck &B) {
13141329 auto HasNoConstOp = [](const FactOrCheck &B) {
1315- return !isa<ConstantInt>(B.Inst ->getOperand (0 )) &&
1316- !isa<ConstantInt>(B.Inst ->getOperand (1 ));
1330+ Value *V0 = B.isConditionFact () ? B.Cond .Op0 : B.Inst ->getOperand (0 );
1331+ Value *V1 = B.isConditionFact () ? B.Cond .Op1 : B.Inst ->getOperand (1 );
1332+ return !isa<ConstantInt>(V0) && !isa<ConstantInt>(V1);
13171333 };
13181334 // If both entries have the same In numbers, conditional facts come first.
13191335 // Otherwise use the relative order in the basic block.
@@ -1386,7 +1402,6 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT,
13861402 continue ;
13871403 }
13881404
1389- LLVM_DEBUG (dbgs () << " fact to add to the system: " << *CB.Inst << " \n " );
13901405 auto AddFact = [&](CmpInst::Predicate Pred, Value *A, Value *B) {
13911406 if (Info.getCS (CmpInst::isSigned (Pred)).size () > MaxRows) {
13921407 LLVM_DEBUG (
@@ -1395,6 +1410,14 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT,
13951410 return ;
13961411 }
13971412
1413+ LLVM_DEBUG ({
1414+ dbgs () << " Processing fact to add to the system: " << Pred << " " ;
1415+ A->printAsOperand (dbgs ());
1416+ dbgs () << " , " ;
1417+ B->printAsOperand (dbgs (), false );
1418+ dbgs () << " \n " ;
1419+ });
1420+
13981421 Info.addFact (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack);
13991422 if (ReproducerModule && DFSInStack.size () > ReproducerCondStack.size ())
14001423 ReproducerCondStack.emplace_back (Pred, A, B);
@@ -1413,23 +1436,27 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT,
14131436 };
14141437
14151438 ICmpInst::Predicate Pred;
1416- if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst )) {
1417- Pred = ICmpInst::getNonStrictPredicate (MinMax->getPredicate ());
1418- AddFact (Pred, MinMax, MinMax->getLHS ());
1419- AddFact (Pred, MinMax, MinMax->getRHS ());
1420- continue ;
1439+ if (!CB.isConditionFact ()) {
1440+ if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst )) {
1441+ Pred = ICmpInst::getNonStrictPredicate (MinMax->getPredicate ());
1442+ AddFact (Pred, MinMax, MinMax->getLHS ());
1443+ AddFact (Pred, MinMax, MinMax->getRHS ());
1444+ continue ;
1445+ }
14211446 }
14221447
1423- Value *A, *B;
1424- Value *Cmp = CB.Inst ;
1425- match (Cmp, m_Intrinsic<Intrinsic::assume>(m_Value (Cmp)));
1426- if (match (Cmp, m_ICmp (Pred, m_Value (A), m_Value (B)))) {
1427- // Use the inverse predicate if required.
1428- if (CB.Not )
1429- Pred = CmpInst::getInversePredicate (Pred);
1430-
1431- AddFact (Pred, A, B);
1448+ Value *A = nullptr , *B = nullptr ;
1449+ if (CB.isConditionFact ()) {
1450+ Pred = CB.Cond .Pred ;
1451+ A = CB.Cond .Op0 ;
1452+ B = CB.Cond .Op1 ;
1453+ } else {
1454+ bool Matched = match (CB.Inst , m_Intrinsic<Intrinsic::assume>(
1455+ m_ICmp (Pred, m_Value (A), m_Value (B))));
1456+ (void )Matched;
1457+ assert (Matched && " Must have an assume intrinsic with a icmp operand" );
14321458 }
1459+ AddFact (Pred, A, B);
14331460 }
14341461
14351462 if (ReproducerModule && !ReproducerModule->functions ().empty ()) {
0 commit comments