@@ -1132,6 +1132,7 @@ void State::addInfoFor(BasicBlock &BB) {
1132
1132
case Intrinsic::umax:
1133
1133
case Intrinsic::smin:
1134
1134
case Intrinsic::smax:
1135
+ case Intrinsic::usub_sat:
1135
1136
// TODO: handle llvm.abs as well
1136
1137
WorkList.push_back (
1137
1138
FactOrCheck::getCheck (DT.getNode (&BB), cast<CallInst>(&I)));
@@ -1142,7 +1143,6 @@ void State::addInfoFor(BasicBlock &BB) {
1142
1143
[[fallthrough]];
1143
1144
case Intrinsic::abs:
1144
1145
case Intrinsic::uadd_sat:
1145
- case Intrinsic::usub_sat:
1146
1146
WorkList.push_back (FactOrCheck::getInstFact (DT.getNode (&BB), &I));
1147
1147
break ;
1148
1148
}
@@ -1519,6 +1519,24 @@ static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info,
1519
1519
return false ;
1520
1520
}
1521
1521
1522
+ static bool checkAndReplaceUSubSat (SaturatingInst *I, ConstraintInfo &Info,
1523
+ SmallVectorImpl<Instruction *> &ToRemove) {
1524
+ Value *LHS = I->getOperand (0 );
1525
+ Value *RHS = I->getOperand (1 );
1526
+ if (checkCondition (ICmpInst::ICMP_UGT, LHS, RHS, I, Info).value_or (false )) {
1527
+ IRBuilder<> Builder (I->getParent (), I->getIterator ());
1528
+ I->replaceAllUsesWith (Builder.CreateSub (LHS, RHS));
1529
+ ToRemove.push_back (I);
1530
+ return true ;
1531
+ }
1532
+ if (checkCondition (ICmpInst::ICMP_ULE, LHS, RHS, I, Info).value_or (false )) {
1533
+ I->replaceAllUsesWith (ConstantInt::get (I->getType (), 0 ));
1534
+ ToRemove.push_back (I);
1535
+ return true ;
1536
+ }
1537
+ return false ;
1538
+ }
1539
+
1522
1540
static void
1523
1541
removeEntryFromStack (const StackEntry &E, ConstraintInfo &Info,
1524
1542
Module *ReproducerModule,
@@ -1840,6 +1858,11 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
1840
1858
Changed |= checkAndReplaceMinMax (MinMax, Info, ToRemove);
1841
1859
} else if (auto *CmpIntr = dyn_cast<CmpIntrinsic>(Inst)) {
1842
1860
Changed |= checkAndReplaceCmp (CmpIntr, Info, ToRemove);
1861
+ } else if (auto *SatIntr = dyn_cast<SaturatingInst>(Inst)) {
1862
+ if (SatIntr->getIntrinsicID () == Intrinsic::usub_sat)
1863
+ Changed |= checkAndReplaceUSubSat (SatIntr, Info, ToRemove);
1864
+ else
1865
+ llvm_unreachable (" Unexpected intrinsic." );
1843
1866
}
1844
1867
continue ;
1845
1868
}
0 commit comments