diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 58d705eb6aa96..152c44a962ee8 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1135,6 +1135,9 @@ void State::addInfoFor(BasicBlock &BB) { // TODO: handle llvm.abs as well WorkList.push_back( FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); + [[fallthrough]]; + case Intrinsic::uadd_sat: + case Intrinsic::usub_sat: // TODO: Check if it is possible to instead only added the min/max facts // when simplifying uses of the min/max intrinsics. if (!isGuaranteedNotToBePoison(&I)) @@ -1896,6 +1899,20 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, AddFact(Pred, MinMax, MinMax->getRHS()); continue; } + if (auto *USatI = dyn_cast(CB.Inst)) { + switch (USatI->getIntrinsicID()) { + default: + llvm_unreachable("Unexpected intrinsic."); + case Intrinsic::uadd_sat: + AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getLHS()); + AddFact(ICmpInst::ICMP_UGE, USatI, USatI->getRHS()); + break; + case Intrinsic::usub_sat: + AddFact(ICmpInst::ICMP_ULE, USatI, USatI->getLHS()); + break; + } + continue; + } } Value *A = nullptr, *B = nullptr; diff --git a/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll b/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll index 42bbe67024e58..c19a0548d78b2 100644 --- a/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll +++ b/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll @@ -8,9 +8,7 @@ define i1 @uadd_sat_uge(i64 noundef %a, i64 noundef %b) { ; CHECK-LABEL: define i1 @uadd_sat_uge( ; CHECK-SAME: i64 noundef [[A:%.*]], i64 noundef [[B:%.*]]) { ; CHECK-NEXT: [[ADD_SAT:%.*]] = call i64 @llvm.uadd.sat.i64(i64 [[A]], i64 [[B]]) -; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i64 [[ADD_SAT]], [[A]] -; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i64 [[ADD_SAT]], [[B]] -; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP1]], [[CMP2]] +; CHECK-NEXT: [[CMP:%.*]] = and i1 true, true ; CHECK-NEXT: ret i1 [[CMP]] ; %add.sat = call i64 @llvm.uadd.sat.i64(i64 %a, i64 %b) @@ -24,8 +22,7 @@ define i1 @usub_sat_ule_lhs(i64 noundef %a, i64 noundef %b) { ; CHECK-LABEL: define i1 @usub_sat_ule_lhs( ; CHECK-SAME: i64 noundef [[A:%.*]], i64 noundef [[B:%.*]]) { ; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) -; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[SUB_SAT]], [[A]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %sub.sat = call i64 @llvm.usub.sat.i64(i64 %a, i64 %b) %cmp = icmp ule i64 %sub.sat, %a