@@ -1083,6 +1083,44 @@ void State::addInfoForInductions(BasicBlock &BB) {
10831083 }
10841084}
10851085
1086+ static void addNonPoisonIntrinsicInstFact (
1087+ IntrinsicInst *II,
1088+ function_ref<void (CmpPredicate, Value *, Value *)> AddFact) {
1089+ Intrinsic::ID IID = II->getIntrinsicID ();
1090+ switch (IID) {
1091+ case Intrinsic::umin:
1092+ case Intrinsic::umax:
1093+ case Intrinsic::smin:
1094+ case Intrinsic::smax: {
1095+ ICmpInst::Predicate Pred =
1096+ ICmpInst::getNonStrictPredicate (MinMaxIntrinsic::getPredicate (IID));
1097+ AddFact (Pred, II, II->getArgOperand (0 ));
1098+ AddFact (Pred, II, II->getArgOperand (1 ));
1099+ break ;
1100+ }
1101+ case Intrinsic::abs: {
1102+ if (cast<ConstantInt>(II->getArgOperand (1 ))->isOne ())
1103+ AddFact (CmpInst::ICMP_SGE, II, ConstantInt::get (II->getType (), 0 ));
1104+ AddFact (CmpInst::ICMP_SGE, II, II->getArgOperand (0 ));
1105+ break ;
1106+ }
1107+ default :
1108+ break ;
1109+ }
1110+ }
1111+
1112+ static void addNonPoisonValueFactRecursive (
1113+ Value *V, function_ref<void (CmpPredicate, Value *, Value *)> AddFact) {
1114+ if (auto *II = dyn_cast<IntrinsicInst>(V))
1115+ addNonPoisonIntrinsicInstFact (II, AddFact);
1116+
1117+ if (auto *I = dyn_cast<Instruction>(V)) {
1118+ for (auto &Op : I->operands ())
1119+ if (propagatesPoison (Op))
1120+ addNonPoisonValueFactRecursive (Op.get (), AddFact);
1121+ }
1122+ }
1123+
10861124void State::addInfoFor (BasicBlock &BB) {
10871125 addInfoForInductions (BB);
10881126
@@ -1134,6 +1172,18 @@ void State::addInfoFor(BasicBlock &BB) {
11341172 break ;
11351173 }
11361174
1175+ if (GuaranteedToExecute) {
1176+ auto AddFact = [&](CmpPredicate Pred, Value *A, Value *B) {
1177+ WorkList.emplace_back (
1178+ FactOrCheck::getConditionFact (DT.getNode (&BB), Pred, A, B));
1179+ };
1180+
1181+ handleGuaranteedWellDefinedOps (&I, [&](const Value *Op) {
1182+ addNonPoisonValueFactRecursive (const_cast <Value *>(Op), AddFact);
1183+ return false ;
1184+ });
1185+ }
1186+
11371187 GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor (&I);
11381188 }
11391189
@@ -1374,32 +1424,6 @@ static void generateReproducer(CmpInst *Cond, Module *M,
13741424 assert (!verifyFunction (*F, &dbgs ()));
13751425}
13761426
1377- static void addNonPoisonIntrinsicInstFact (
1378- IntrinsicInst *II,
1379- function_ref<void (CmpPredicate, Value *, Value *)> AddFact) {
1380- Intrinsic::ID IID = II->getIntrinsicID ();
1381- switch (IID) {
1382- case Intrinsic::umin:
1383- case Intrinsic::umax:
1384- case Intrinsic::smin:
1385- case Intrinsic::smax: {
1386- ICmpInst::Predicate Pred =
1387- ICmpInst::getNonStrictPredicate (MinMaxIntrinsic::getPredicate (IID));
1388- AddFact (Pred, II, II->getArgOperand (0 ));
1389- AddFact (Pred, II, II->getArgOperand (1 ));
1390- break ;
1391- }
1392- case Intrinsic::abs: {
1393- if (cast<ConstantInt>(II->getArgOperand (1 ))->isOne ())
1394- AddFact (CmpInst::ICMP_SGE, II, ConstantInt::get (II->getType (), 0 ));
1395- AddFact (CmpInst::ICMP_SGE, II, II->getArgOperand (0 ));
1396- break ;
1397- }
1398- default :
1399- break ;
1400- }
1401- }
1402-
14031427static void
14041428removeEntryFromStack (const StackEntry &E, ConstraintInfo &Info,
14051429 SmallVectorImpl<StackEntry> &DFSInStack,
@@ -1426,12 +1450,12 @@ static std::optional<bool> checkCondition(CmpInst::Predicate Pred, Value *A,
14261450 });
14271451 auto AddFact = [&](CmpPredicate Pred, Value *A, Value *B) {
14281452 Info.addFact (Pred, A, B, 0 , 0 , DFSInStack);
1453+ if (ICmpInst::isRelational (Pred))
1454+ Info.transferToOtherSystem (Pred, A, B, 0 , 0 , DFSInStack);
14291455 };
14301456
1431- if (auto *II = dyn_cast<IntrinsicInst>(A))
1432- addNonPoisonIntrinsicInstFact (II, AddFact);
1433- if (auto *II = dyn_cast<IntrinsicInst>(B))
1434- addNonPoisonIntrinsicInstFact (II, AddFact);
1457+ addNonPoisonValueFactRecursive (A, AddFact);
1458+ addNonPoisonValueFactRecursive (B, AddFact);
14351459
14361460 auto R = Info.getConstraintForSolving (Pred, A, B);
14371461 if (R.empty () || !R.isValid (Info)){
@@ -1600,12 +1624,13 @@ static bool checkOrAndOpImpliedByOther(
16001624 Info.addFact (Pred, LHS, RHS, CB.NumIn , CB.NumOut , DFSInStack);
16011625 auto AddFact = [&](CmpPredicate Pred, Value *A, Value *B) {
16021626 Info.addFact (Pred, A, B, CB.NumIn , CB.NumOut , DFSInStack);
1627+ if (ICmpInst::isRelational (Pred))
1628+ Info.transferToOtherSystem (Pred, A, B, CB.NumIn , CB.NumOut ,
1629+ DFSInStack);
16031630 };
16041631
1605- if (auto *II = dyn_cast<IntrinsicInst>(LHS))
1606- addNonPoisonIntrinsicInstFact (II, AddFact);
1607- if (auto *II = dyn_cast<IntrinsicInst>(RHS))
1608- addNonPoisonIntrinsicInstFact (II, AddFact);
1632+ addNonPoisonValueFactRecursive (LHS, AddFact);
1633+ addNonPoisonValueFactRecursive (RHS, AddFact);
16091634 continue ;
16101635 }
16111636 if (IsOr ? match (Val, m_LogicalOr (m_Value (LHS), m_Value (RHS)))
@@ -1939,10 +1964,8 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
19391964 }
19401965 AddFact (Pred, A, B);
19411966 // Now both A and B is guaranteed not to be poison.
1942- if (auto *II = dyn_cast<IntrinsicInst>(A))
1943- addNonPoisonIntrinsicInstFact (II, AddFact);
1944- if (auto *II = dyn_cast<IntrinsicInst>(B))
1945- addNonPoisonIntrinsicInstFact (II, AddFact);
1967+ addNonPoisonValueFactRecursive (A, AddFact);
1968+ addNonPoisonValueFactRecursive (B, AddFact);
19461969 }
19471970
19481971 if (ReproducerModule && !ReproducerModule->functions ().empty ()) {
0 commit comments