@@ -306,7 +306,8 @@ class ConstraintInfo {
306
306
bool doesHold (CmpInst::Predicate Pred, Value *A, Value *B) const ;
307
307
308
308
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);
310
311
311
312
// / Turn a comparison of the form \p Op0 \p Pred \p Op1 into a vector of
312
313
// / constraints, using indices from the corresponding constraint system.
@@ -329,7 +330,8 @@ class ConstraintInfo {
329
330
// / system if \p Pred is signed/unsigned.
330
331
void transferToOtherSystem (CmpInst::Predicate Pred, Value *A, Value *B,
331
332
unsigned NumIn, unsigned NumOut,
332
- SmallVectorImpl<StackEntry> &DFSInStack);
333
+ SmallVectorImpl<StackEntry> &DFSInStack,
334
+ bool IsWellDefined);
333
335
};
334
336
335
337
// / Represents a (Coefficient * Variable) entry after IR decomposition.
@@ -819,7 +821,8 @@ bool ConstraintInfo::doesHold(CmpInst::Predicate Pred, Value *A,
819
821
820
822
void ConstraintInfo::transferToOtherSystem (
821
823
CmpInst::Predicate Pred, Value *A, Value *B, unsigned NumIn,
822
- unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack) {
824
+ unsigned NumOut, SmallVectorImpl<StackEntry> &DFSInStack,
825
+ bool IsWellDefined) {
823
826
auto IsKnownNonNegative = [this ](Value *V) {
824
827
return doesHold (CmpInst::ICMP_SGE, V, ConstantInt::get (V->getType (), 0 )) ||
825
828
isKnownNonNegative (V, DL, /* Depth=*/ MaxAnalysisRecursionDepth - 1 );
@@ -839,37 +842,40 @@ void ConstraintInfo::transferToOtherSystem(
839
842
// If B is a signed positive constant, then A >=s 0 and A <s (or <=s) B.
840
843
if (IsKnownNonNegative (B)) {
841
844
addFact (CmpInst::ICMP_SGE, A, ConstantInt::get (B->getType (), 0 ), NumIn,
842
- NumOut, DFSInStack);
845
+ NumOut, DFSInStack, IsWellDefined );
843
846
addFact (CmpInst::getSignedPredicate (Pred), A, B, NumIn, NumOut,
844
- DFSInStack);
847
+ DFSInStack, IsWellDefined );
845
848
}
846
849
break ;
847
850
case CmpInst::ICMP_UGE:
848
851
case CmpInst::ICMP_UGT:
849
852
// If A is a signed positive constant, then B >=s 0 and A >s (or >=s) B.
850
853
if (IsKnownNonNegative (A)) {
851
854
addFact (CmpInst::ICMP_SGE, B, ConstantInt::get (B->getType (), 0 ), NumIn,
852
- NumOut, DFSInStack);
855
+ NumOut, DFSInStack, IsWellDefined );
853
856
addFact (CmpInst::getSignedPredicate (Pred), A, B, NumIn, NumOut,
854
- DFSInStack);
857
+ DFSInStack, IsWellDefined );
855
858
}
856
859
break ;
857
860
case CmpInst::ICMP_SLT:
858
861
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);
860
864
break ;
861
865
case CmpInst::ICMP_SGT: {
862
866
if (doesHold (CmpInst::ICMP_SGE, B, ConstantInt::get (B->getType (), -1 )))
863
867
addFact (CmpInst::ICMP_UGE, A, ConstantInt::get (B->getType (), 0 ), NumIn,
864
- NumOut, DFSInStack);
868
+ NumOut, DFSInStack, IsWellDefined );
865
869
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);
867
872
868
873
break ;
869
874
}
870
875
case CmpInst::ICMP_SGE:
871
876
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);
873
879
break ;
874
880
}
875
881
}
@@ -1068,10 +1074,6 @@ void State::addInfoFor(BasicBlock &BB) {
1068
1074
// TODO: handle llvm.abs as well
1069
1075
WorkList.push_back (
1070
1076
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 ;
1075
1077
[[fallthrough]];
1076
1078
case Intrinsic::abs:
1077
1079
WorkList.push_back (FactOrCheck::getInstFact (DT.getNode (&BB), &I));
@@ -1464,7 +1466,8 @@ static bool checkOrAndOpImpliedByOther(
1464
1466
1465
1467
// Optimistically add fact from first condition.
1466
1468
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 );
1468
1471
if (OldSize == DFSInStack.size ())
1469
1472
return false ;
1470
1473
@@ -1496,7 +1499,8 @@ static bool checkOrAndOpImpliedByOther(
1496
1499
1497
1500
void ConstraintInfo::addFact (CmpInst::Predicate Pred, Value *A, Value *B,
1498
1501
unsigned NumIn, unsigned NumOut,
1499
- SmallVectorImpl<StackEntry> &DFSInStack) {
1502
+ SmallVectorImpl<StackEntry> &DFSInStack,
1503
+ bool IsWellDefined) {
1500
1504
// If the constraint has a pre-condition, skip the constraint if it does not
1501
1505
// hold.
1502
1506
SmallVector<Value *> NewVariables;
@@ -1513,7 +1517,7 @@ void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
1513
1517
if (R.Coefficients .empty ())
1514
1518
return ;
1515
1519
1516
- Added |= CSToUse.addVariableRowFill (R.Coefficients );
1520
+ Added |= CSToUse.addVariableRowFill (R.Coefficients , IsWellDefined );
1517
1521
1518
1522
// If R has been added to the system, add the new variables and queue it for
1519
1523
// removal once it goes out-of-scope.
@@ -1539,7 +1543,7 @@ void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
1539
1543
ConstraintTy VarPos (SmallVector<int64_t , 8 >(Value2Index.size () + 1 , 0 ),
1540
1544
false , false , false );
1541
1545
VarPos.Coefficients [Value2Index[V]] = -1 ;
1542
- CSToUse.addVariableRow (VarPos.Coefficients );
1546
+ CSToUse.addVariableRow (VarPos.Coefficients , IsWellDefined );
1543
1547
DFSInStack.emplace_back (NumIn, NumOut, R.IsSigned ,
1544
1548
SmallVector<Value *, 2 >());
1545
1549
}
@@ -1549,7 +1553,7 @@ void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B,
1549
1553
// Also add the inverted constraint for equality constraints.
1550
1554
for (auto &Coeff : R.Coefficients )
1551
1555
Coeff *= -1 ;
1552
- CSToUse.addVariableRowFill (R.Coefficients );
1556
+ CSToUse.addVariableRowFill (R.Coefficients , IsWellDefined );
1553
1557
1554
1558
DFSInStack.emplace_back (NumIn, NumOut, R.IsSigned ,
1555
1559
SmallVector<Value *, 2 >());
@@ -1724,7 +1728,8 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
1724
1728
continue ;
1725
1729
}
1726
1730
1727
- auto AddFact = [&](CmpInst::Predicate Pred, Value *A, Value *B) {
1731
+ auto AddFact = [&](CmpInst::Predicate Pred, Value *A, Value *B,
1732
+ bool IsWellDefined) {
1728
1733
LLVM_DEBUG (dbgs () << " Processing fact to add to the system: " ;
1729
1734
dumpUnpackedICmp (dbgs (), Pred, A, B); dbgs () << " \n " );
1730
1735
if (Info.getCS (CmpInst::isSigned (Pred)).size () > MaxRows) {
@@ -1734,11 +1739,12 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
1734
1739
return ;
1735
1740
}
1736
1741
1737
- Info.addFact (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack);
1742
+ Info.addFact (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack, IsWellDefined );
1738
1743
if (ReproducerModule && DFSInStack.size () > ReproducerCondStack.size ())
1739
1744
ReproducerCondStack.emplace_back (Pred, A, B);
1740
1745
1741
- Info.transferToOtherSystem (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack);
1746
+ Info.transferToOtherSystem (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack,
1747
+ IsWellDefined);
1742
1748
if (ReproducerModule && DFSInStack.size () > ReproducerCondStack.size ()) {
1743
1749
// Add dummy entries to ReproducerCondStack to keep it in sync with
1744
1750
// DFSInStack.
@@ -1756,14 +1762,16 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
1756
1762
Value *X;
1757
1763
if (match (CB.Inst , m_Intrinsic<Intrinsic::abs>(m_Value (X)))) {
1758
1764
// TODO: Add CB.Inst >= 0 fact.
1759
- AddFact (CmpInst::ICMP_SGE, CB.Inst , X);
1765
+ bool IsWellDefined = isGuaranteedNotToBePoison (CB.Inst );
1766
+ AddFact (CmpInst::ICMP_SGE, CB.Inst , X, IsWellDefined);
1760
1767
continue ;
1761
1768
}
1762
1769
1763
1770
if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst )) {
1764
1771
Pred = ICmpInst::getNonStrictPredicate (MinMax->getPredicate ());
1765
- AddFact (Pred, MinMax, MinMax->getLHS ());
1766
- AddFact (Pred, MinMax, MinMax->getRHS ());
1772
+ bool IsWellDefined = isGuaranteedNotToBePoison (CB.Inst );
1773
+ AddFact (Pred, MinMax, MinMax->getLHS (), IsWellDefined);
1774
+ AddFact (Pred, MinMax, MinMax->getRHS (), IsWellDefined);
1767
1775
continue ;
1768
1776
}
1769
1777
}
@@ -1791,7 +1799,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
1791
1799
(void )Matched;
1792
1800
assert (Matched && " Must have an assume intrinsic with a icmp operand" );
1793
1801
}
1794
- AddFact (Pred, A, B);
1802
+ AddFact (Pred, A, B, /* IsWellDefined */ true );
1795
1803
}
1796
1804
1797
1805
if (ReproducerModule && !ReproducerModule->functions ().empty ()) {
0 commit comments