@@ -306,7 +306,8 @@ class ConstraintInfo {
306306 bool doesHold (CmpInst::Predicate Pred, Value *A, Value *B) const ;
307307
308308 void addFact (CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
309- unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack);
309+ unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack,
310+ bool IsWellDefined);
310311
311312 // / Turn a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
312313 // / constraints, using indices from the corresponding constraint system.
@@ -329,7 +330,8 @@ class ConstraintInfo {
329330 // / system if \p Pred is signed/unsigned.
330331 void transferToOtherSystem (CmpInst::Predicate Pred, Value *A, Value *B,
331332 unsigned NumIn, unsigned NumOut,
332- SmallVectorImpl<StackEntry> &DFSInStack);
333+ SmallVectorImpl<StackEntry> &DFSInStack,
334+ bool IsWellDefined);
333335};
334336
335337// / Represents a (Coefficient * Variable) entry after IR decomposition.
@@ -819,7 +821,8 @@ bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A,
819821
820822void ConstraintInfo::transferToOtherSystem (
821823 CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
822- unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack) {
824+ unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack,
825+ bool IsWellDefined) {
823826 auto IsKnownNonNegative = [this ](Value *V) {
824827 return doesHold (CmpInst::ICMP_SGE, V, ConstantInt::get (V->getType (), 0 )) ||
825828 isKnownNonNegative (V, DL, /* Depth=*/ MaxAnalysisRecursionDepth - 1 );
@@ -839,37 +842,40 @@ void ConstraintInfo::transferToOtherSystem(
839842 // If B is a signed positive constant, then A >=s 0 and A <s (or <=s) B.
840843 if (IsKnownNonNegative (B)) {
841844 addFact (CmpInst::ICMP_SGE, A, ConstantInt::get (B->getType (), 0 ), NumIn,
842- NumOut, DFSInStack);
845+ NumOut, DFSInStack, IsWellDefined );
843846 addFact (CmpInst::getSignedPredicate (Pred), A, B, NumIn, NumOut,
844- DFSInStack);
847+ DFSInStack, IsWellDefined );
845848 }
846849 break ;
847850 case CmpInst::ICMP_UGE:
848851 case CmpInst::ICMP_UGT:
849852 // If A is a signed positive constant, then B >=s 0 and A >s (or >=s) B.
850853 if (IsKnownNonNegative (A)) {
851854 addFact (CmpInst::ICMP_SGE, B, ConstantInt::get (B->getType (), 0 ), NumIn,
852- NumOut, DFSInStack);
855+ NumOut, DFSInStack, IsWellDefined );
853856 addFact (CmpInst::getSignedPredicate (Pred), A, B, NumIn, NumOut,
854- DFSInStack);
857+ DFSInStack, IsWellDefined );
855858 }
856859 break ;
857860 case CmpInst::ICMP_SLT:
858861 if (IsKnownNonNegative (A))
859- addFact (CmpInst::ICMP_ULT, A, B, NumIn, NumOut, DFSInStack);
862+ addFact (CmpInst::ICMP_ULT, A, B, NumIn, NumOut, DFSInStack,
863+ IsWellDefined);
860864 break ;
861865 case CmpInst::ICMP_SGT: {
862866 if (doesHold (CmpInst::ICMP_SGE, B, ConstantInt::get (B->getType (), -1 )))
863867 addFact (CmpInst::ICMP_UGE, A, ConstantInt::get (B->getType (), 0 ), NumIn,
864- NumOut, DFSInStack);
868+ NumOut, DFSInStack, IsWellDefined );
865869 if (IsKnownNonNegative (B))
866- addFact (CmpInst::ICMP_UGT, A, B, NumIn, NumOut, DFSInStack);
870+ addFact (CmpInst::ICMP_UGT, A, B, NumIn, NumOut, DFSInStack,
871+ IsWellDefined);
867872
868873 break ;
869874 }
870875 case CmpInst::ICMP_SGE:
871876 if (IsKnownNonNegative (B))
872- addFact (CmpInst::ICMP_UGE, A, B, NumIn, NumOut, DFSInStack);
877+ addFact (CmpInst::ICMP_UGE, A, B, NumIn, NumOut, DFSInStack,
878+ IsWellDefined);
873879 break ;
874880 }
875881}
@@ -1068,10 +1074,6 @@ void State::addInfoFor(BasicBlock &BB) {
10681074 // TODO: handle llvm.abs as well
10691075 WorkList.push_back (
10701076 FactOrCheck::getCheck (DT.getNode (&BB), cast<CallInst>(&I)));
1071- // TODO: Check if it is possible to instead only added the min/max facts
1072- // when simplifying uses of the min/max intrinsics.
1073- if (!isGuaranteedNotToBePoison (&I))
1074- break ;
10751077 [[fallthrough]];
10761078 case Intrinsic::abs:
10771079 WorkList.push_back (FactOrCheck::getInstFact (DT.getNode (&BB), &I));
@@ -1464,7 +1466,8 @@ static bool checkOrAndOpImpliedByOther(
14641466
14651467 // Optimistically add fact from first condition.
14661468 unsigned OldSize = DFSInStack.size ();
1467- Info.addFact (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack);
1469+ Info.addFact (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack,
1470+ /* IsWellDefined*/ true );
14681471 if (OldSize == DFSInStack.size ())
14691472 return false ;
14701473
@@ -1496,7 +1499,8 @@ static bool checkOrAndOpImpliedByOther(
14961499
14971500void ConstraintInfo::addFact (CmpInst::Predicate Pred, Value *A, Value *B,
14981501 unsigned NumIn, unsigned NumOut,
1499- SmallVectorImpl<StackEntry> &DFSInStack) {
1502+ SmallVectorImpl<StackEntry> &DFSInStack,
1503+ bool IsWellDefined) {
15001504 // If the constraint has a pre-condition, skip the constraint if it does not
15011505 // hold.
15021506 SmallVector<Value *> NewVariables;
@@ -1513,7 +1517,7 @@ void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
15131517 if (R.Coefficients .empty ())
15141518 return ;
15151519
1516- Added |= CSToUse.addVariableRowFill (R.Coefficients );
1520+ Added |= CSToUse.addVariableRowFill (R.Coefficients , IsWellDefined );
15171521
15181522 // If R has been added to the system, add the new variables and queue it for
15191523 // removal once it goes out-of-scope.
@@ -1539,7 +1543,7 @@ void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
15391543 ConstraintTy VarPos (SmallVector<int64_t , 8 >(Value2Index.size () + 1 , 0 ),
15401544 false , false , false );
15411545 VarPos.Coefficients [Value2Index[V]] = -1 ;
1542- CSToUse.addVariableRow (VarPos.Coefficients );
1546+ CSToUse.addVariableRow (VarPos.Coefficients , IsWellDefined );
15431547 DFSInStack.emplace_back (NumIn, NumOut, R.IsSigned ,
15441548 SmallVector<Value *, 2 >());
15451549 }
@@ -1549,7 +1553,7 @@ void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
15491553 // Also add the inverted constraint for equality constraints.
15501554 for (auto &Coeff : R.Coefficients )
15511555 Coeff *= -1 ;
1552- CSToUse.addVariableRowFill (R.Coefficients );
1556+ CSToUse.addVariableRowFill (R.Coefficients , IsWellDefined );
15531557
15541558 DFSInStack.emplace_back (NumIn, NumOut, R.IsSigned ,
15551559 SmallVector<Value *, 2 >());
@@ -1724,7 +1728,8 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
17241728 continue ;
17251729 }
17261730
1727- auto AddFact = [&](CmpInst::Predicate Pred, Value *A, Value *B) {
1731+ auto AddFact = [&](CmpInst::Predicate Pred, Value *A, Value *B,
1732+ bool IsWellDefined) {
17281733 LLVM_DEBUG (dbgs () << " Processing fact to add to the system: " ;
17291734 dumpUnpackedICmp (dbgs (), Pred, A, B); dbgs () << " \n " );
17301735 if (Info.getCS (CmpInst::isSigned (Pred)).size () > MaxRows) {
@@ -1734,11 +1739,12 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
17341739 return ;
17351740 }
17361741
1737- Info.addFact (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack);
1742+ Info.addFact (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack, IsWellDefined );
17381743 if (ReproducerModule && DFSInStack.size () > ReproducerCondStack.size ())
17391744 ReproducerCondStack.emplace_back (Pred, A, B);
17401745
1741- Info.transferToOtherSystem (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack);
1746+ Info.transferToOtherSystem (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack,
1747+ IsWellDefined);
17421748 if (ReproducerModule && DFSInStack.size () > ReproducerCondStack.size ()) {
17431749 // Add dummy entries to ReproducerCondStack to keep it in sync with
17441750 // DFSInStack.
@@ -1755,18 +1761,20 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
17551761 if (!CB.isConditionFact ()) {
17561762 Value *X;
17571763 if (match (CB.Inst , m_Intrinsic<Intrinsic::abs>(m_Value (X)))) {
1764+ bool IsWellDefined = isGuaranteedNotToBePoison (CB.Inst );
17581765 // If is_int_min_poison is true then we may assume llvm.abs >= 0.
17591766 if (cast<ConstantInt>(CB.Inst ->getOperand (1 ))->isOne ())
17601767 AddFact (CmpInst::ICMP_SGE, CB.Inst ,
1761- ConstantInt::get (CB.Inst ->getType (), 0 ));
1762- AddFact (CmpInst::ICMP_SGE, CB.Inst , X);
1768+ ConstantInt::get (CB.Inst ->getType (), 0 ), IsWellDefined );
1769+ AddFact (CmpInst::ICMP_SGE, CB.Inst , X, IsWellDefined );
17631770 continue ;
17641771 }
17651772
17661773 if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst )) {
17671774 Pred = ICmpInst::getNonStrictPredicate (MinMax->getPredicate ());
1768- AddFact (Pred, MinMax, MinMax->getLHS ());
1769- AddFact (Pred, MinMax, MinMax->getRHS ());
1775+ bool IsWellDefined = isGuaranteedNotToBePoison (CB.Inst );
1776+ AddFact (Pred, MinMax, MinMax->getLHS (), IsWellDefined);
1777+ AddFact (Pred, MinMax, MinMax->getRHS (), IsWellDefined);
17701778 continue ;
17711779 }
17721780 }
@@ -1794,7 +1802,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
17941802 (void )Matched;
17951803 assert (Matched && " Must have an assume intrinsic with a icmp operand" );
17961804 }
1797- AddFact (Pred, A, B);
1805+ AddFact (Pred, A, B, /* IsWellDefined */ true );
17981806 }
17991807
18001808 if (ReproducerModule && !ReproducerModule->functions ().empty ()) {
0 commit comments