From fc2a35c3b91fe995ecde2874618ed0eabcdecbc0 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Tue, 15 Apr 2025 12:22:59 +0800 Subject: [PATCH 1/6] [ConstraintElim] Optimize usub.sat intrinsic based on known constraints --- .../Scalar/ConstraintElimination.cpp | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 31e057baee2bf..f426c4ca9bc02 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1132,6 +1132,7 @@ void State::addInfoFor(BasicBlock &BB) { case Intrinsic::umax: case Intrinsic::smin: case Intrinsic::smax: + case Intrinsic::usub_sat: // TODO: handle llvm.abs as well WorkList.push_back( FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); @@ -1142,7 +1143,6 @@ void State::addInfoFor(BasicBlock &BB) { [[fallthrough]]; case Intrinsic::abs: case Intrinsic::uadd_sat: - case Intrinsic::usub_sat: WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); break; } @@ -1519,6 +1519,24 @@ static bool checkAndReplaceCmp(CmpIntrinsic *I, ConstraintInfo &Info, return false; } +static bool checkAndReplaceUSubSat(SaturatingInst *I, ConstraintInfo &Info, + SmallVectorImpl &ToRemove) { + Value *LHS = I->getOperand(0); + Value *RHS = I->getOperand(1); + if (checkCondition(ICmpInst::ICMP_UGT, LHS, RHS, I, Info).value_or(false)) { + IRBuilder<> Builder(I->getParent(), I->getIterator()); + I->replaceAllUsesWith(Builder.CreateSub(LHS, RHS)); + ToRemove.push_back(I); + return true; + } + if (checkCondition(ICmpInst::ICMP_ULE, LHS, RHS, I, Info).value_or(false)) { + I->replaceAllUsesWith(ConstantInt::get(I->getType(), 0)); + ToRemove.push_back(I); + return true; + } + return false; +} + static void removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info, Module *ReproducerModule, @@ -1840,6 +1858,11 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI, Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove); } else if (auto *CmpIntr = dyn_cast(Inst)) { Changed |= checkAndReplaceCmp(CmpIntr, Info, ToRemove); + } else if (auto *SatIntr = dyn_cast(Inst)) { + if (SatIntr->getIntrinsicID() == Intrinsic::usub_sat) + Changed |= checkAndReplaceUSubSat(SatIntr, Info, ToRemove); + else + llvm_unreachable("Unexpected intrinsic."); } continue; } From ace4e18a38ab064b983e851c00d5850a55e277d7 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Tue, 15 Apr 2025 12:23:41 +0800 Subject: [PATCH 2/6] pre-commit test --- .../ConstraintElimination/uadd-usub-sat.ll | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll b/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll index b0db89dcfdab8..0ef17d40a07a7 100644 --- a/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll +++ b/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll @@ -8,7 +8,9 @@ define i1 @uadd_sat_uge(i64 %a, i64 %b) { ; CHECK-LABEL: define i1 @uadd_sat_uge( ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[ADD_SAT:%.*]] = call i64 @llvm.uadd.sat.i64(i64 [[A]], i64 [[B]]) -; CHECK-NEXT: [[CMP:%.*]] = and i1 true, true +; 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: ret i1 [[CMP]] ; %add.sat = call i64 @llvm.uadd.sat.i64(i64 %a, i64 %b) @@ -22,13 +24,42 @@ define i1 @usub_sat_ule_lhs(i64 %a, i64 %b) { ; CHECK-LABEL: define i1 @usub_sat_ule_lhs( ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[SUB_SAT]], [[A]] +; CHECK-NEXT: ret i1 [[CMP]] ; %sub.sat = call i64 @llvm.usub.sat.i64(i64 %a, i64 %b) %cmp = icmp ule i64 %sub.sat, %a ret i1 %cmp } +define i64 @usub_sat_when_lhs_ugt_rhs(i64 %a, i64 %b) { +; CHECK-LABEL: define i64 @usub_sat_when_lhs_ugt_rhs( +; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { +; CHECK-NEXT: [[PRECOND:%.*]] = icmp ugt i64 [[A]], [[B]] +; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) +; CHECK-NEXT: ret i64 [[SUB_SAT]] +; + %precond = icmp ugt i64 %a, %b + call void @llvm.assume(i1 %precond) + %sub.sat = call i64 @llvm.usub.sat.i64(i64 %a, i64 %b) + ret i64 %sub.sat +} + +define i64 @usub_sat_when_lhs_ule_rhs(i64 %a, i64 %b) { +; CHECK-LABEL: define i64 @usub_sat_when_lhs_ule_rhs( +; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { +; CHECK-NEXT: [[PRECOND:%.*]] = icmp ule i64 [[A]], [[B]] +; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]]) +; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) +; CHECK-NEXT: ret i64 [[SUB_SAT]] +; + %precond = icmp ule i64 %a, %b + call void @llvm.assume(i1 %precond) + %sub.sat = call i64 @llvm.usub.sat.i64(i64 %a, i64 %b) + ret i64 %sub.sat +} + ; Negative test define i1 @usub_sat_not_ule_rhs(i64 %a, i64 %b) { ; CHECK-LABEL: define i1 @usub_sat_not_ule_rhs( @@ -41,3 +72,13 @@ define i1 @usub_sat_not_ule_rhs(i64 %a, i64 %b) { %cmp = icmp ule i64 %sub.sat, %b ret i1 %cmp } + +define i64 @usub_sat_without_precond(i64 %a, i64 %b) { +; CHECK-LABEL: define i64 @usub_sat_without_precond( +; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { +; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) +; CHECK-NEXT: ret i64 [[SUB_SAT]] +; + %sub.sat = call i64 @llvm.usub.sat.i64(i64 %a, i64 %b) + ret i64 %sub.sat +} From dbe385b5fd4f6636eaba890751357fc857ccfac5 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Tue, 15 Apr 2025 12:24:37 +0800 Subject: [PATCH 3/6] update test --- .../Transforms/ConstraintElimination/uadd-usub-sat.ll | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll b/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll index 0ef17d40a07a7..567b5ce6c3a3f 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 %a, i64 %b) { ; CHECK-LABEL: define i1 @uadd_sat_uge( ; CHECK-SAME: i64 [[A:%.*]], i64 [[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) @@ -37,7 +35,7 @@ define i64 @usub_sat_when_lhs_ugt_rhs(i64 %a, i64 %b) { ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[PRECOND:%.*]] = icmp ugt i64 [[A]], [[B]] ; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]]) -; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) +; CHECK-NEXT: [[SUB_SAT:%.*]] = sub i64 [[A]], [[B]] ; CHECK-NEXT: ret i64 [[SUB_SAT]] ; %precond = icmp ugt i64 %a, %b @@ -51,8 +49,7 @@ define i64 @usub_sat_when_lhs_ule_rhs(i64 %a, i64 %b) { ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[PRECOND:%.*]] = icmp ule i64 [[A]], [[B]] ; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]]) -; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) -; CHECK-NEXT: ret i64 [[SUB_SAT]] +; CHECK-NEXT: ret i64 0 ; %precond = icmp ule i64 %a, %b call void @llvm.assume(i1 %precond) From 8071ab24ecf1f69ff39ad26e8e1011ff8bdf529c Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Tue, 15 Apr 2025 14:52:38 +0800 Subject: [PATCH 4/6] bypass poison check for usub.sat --- llvm/lib/Transforms/Scalar/ConstraintElimination.cpp | 9 ++++++--- .../Transforms/ConstraintElimination/uadd-usub-sat.ll | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index f426c4ca9bc02..4f41cefad8cd1 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1132,14 +1132,17 @@ void State::addInfoFor(BasicBlock &BB) { case Intrinsic::umax: case Intrinsic::smin: case Intrinsic::smax: - case Intrinsic::usub_sat: // TODO: handle llvm.abs as well WorkList.push_back( FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); // 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)) - break; + if (isGuaranteedNotToBePoison(&I)) + WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); + break; + case Intrinsic::usub_sat: + WorkList.push_back( + FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); [[fallthrough]]; case Intrinsic::abs: case Intrinsic::uadd_sat: diff --git a/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll b/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll index 567b5ce6c3a3f..0ef17d40a07a7 100644 --- a/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll +++ b/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll @@ -8,7 +8,9 @@ define i1 @uadd_sat_uge(i64 %a, i64 %b) { ; CHECK-LABEL: define i1 @uadd_sat_uge( ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[ADD_SAT:%.*]] = call i64 @llvm.uadd.sat.i64(i64 [[A]], i64 [[B]]) -; CHECK-NEXT: [[CMP:%.*]] = and i1 true, true +; 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: ret i1 [[CMP]] ; %add.sat = call i64 @llvm.uadd.sat.i64(i64 %a, i64 %b) @@ -35,7 +37,7 @@ define i64 @usub_sat_when_lhs_ugt_rhs(i64 %a, i64 %b) { ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[PRECOND:%.*]] = icmp ugt i64 [[A]], [[B]] ; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]]) -; CHECK-NEXT: [[SUB_SAT:%.*]] = sub i64 [[A]], [[B]] +; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) ; CHECK-NEXT: ret i64 [[SUB_SAT]] ; %precond = icmp ugt i64 %a, %b @@ -49,7 +51,8 @@ define i64 @usub_sat_when_lhs_ule_rhs(i64 %a, i64 %b) { ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[PRECOND:%.*]] = icmp ule i64 [[A]], [[B]] ; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]]) -; CHECK-NEXT: ret i64 0 +; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) +; CHECK-NEXT: ret i64 [[SUB_SAT]] ; %precond = icmp ule i64 %a, %b call void @llvm.assume(i1 %precond) From 5624d79dff6c41847ed53ffaf9d6c3a6167acc26 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Tue, 15 Apr 2025 14:53:55 +0800 Subject: [PATCH 5/6] update test --- .../ConstraintElimination/uadd-usub-sat.ll | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll b/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll index 0ef17d40a07a7..ea0d0d42eb081 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 %a, i64 %b) { ; CHECK-LABEL: define i1 @uadd_sat_uge( ; CHECK-SAME: i64 [[A:%.*]], i64 [[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 %a, i64 %b) { ; CHECK-LABEL: define i1 @usub_sat_ule_lhs( ; CHECK-SAME: i64 [[A:%.*]], i64 [[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 @@ -37,7 +34,7 @@ define i64 @usub_sat_when_lhs_ugt_rhs(i64 %a, i64 %b) { ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[PRECOND:%.*]] = icmp ugt i64 [[A]], [[B]] ; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]]) -; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) +; CHECK-NEXT: [[SUB_SAT:%.*]] = sub i64 [[A]], [[B]] ; CHECK-NEXT: ret i64 [[SUB_SAT]] ; %precond = icmp ugt i64 %a, %b @@ -51,8 +48,7 @@ define i64 @usub_sat_when_lhs_ule_rhs(i64 %a, i64 %b) { ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[PRECOND:%.*]] = icmp ule i64 [[A]], [[B]] ; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]]) -; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) -; CHECK-NEXT: ret i64 [[SUB_SAT]] +; CHECK-NEXT: ret i64 0 ; %precond = icmp ule i64 %a, %b call void @llvm.assume(i1 %precond) From 9b486ebfd565e45abd72e78fd569dfb29b989b27 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Tue, 15 Apr 2025 21:20:57 +0800 Subject: [PATCH 6/6] add nopoison back --- .../Scalar/ConstraintElimination.cpp | 9 +++---- .../Transforms/ConstraintElimination/abs.ll | 24 ++++++++++++------- .../ConstraintElimination/uadd-usub-sat.ll | 7 ++++-- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 4f41cefad8cd1..8a05d0c1ddf5a 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1132,20 +1132,17 @@ void State::addInfoFor(BasicBlock &BB) { case Intrinsic::umax: case Intrinsic::smin: case Intrinsic::smax: + case Intrinsic::usub_sat: // TODO: handle llvm.abs as well WorkList.push_back( FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); // 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)) - WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); - break; - case Intrinsic::usub_sat: - WorkList.push_back( - FactOrCheck::getCheck(DT.getNode(&BB), cast(&I))); [[fallthrough]]; case Intrinsic::abs: case Intrinsic::uadd_sat: + if (!isGuaranteedNotToBePoison(&I)) + break; WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I)); break; } diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll index 9fc68b0e72663..a0c22d9f03c28 100644 --- a/llvm/test/Transforms/ConstraintElimination/abs.ll +++ b/llvm/test/Transforms/ConstraintElimination/abs.ll @@ -5,7 +5,8 @@ define i1 @abs_int_min_is_not_poison(i32 %arg) { ; CHECK-LABEL: define i1 @abs_int_min_is_not_poison( ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false) -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], [[ARG]] +; CHECK-NEXT: ret i1 [[CMP]] ; %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false) %cmp = icmp sge i32 %abs, %arg @@ -16,7 +17,8 @@ define i1 @abs_int_min_is_poison(i32 %arg) { ; CHECK-LABEL: define i1 @abs_int_min_is_poison( ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], [[ARG]] +; CHECK-NEXT: ret i1 [[CMP]] ; %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true) %cmp = icmp sge i32 %abs, %arg @@ -28,7 +30,8 @@ define i1 @abs_plus_one(i32 %arg) { ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) ; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nsw i32 [[ABS]], 1 -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS_PLUS_ONE]], [[ARG]] +; CHECK-NEXT: ret i1 [[CMP]] ; %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true) %abs_plus_one = add nsw i32 %abs, 1 @@ -41,7 +44,8 @@ define i1 @arg_minus_one_strict_less(i32 %arg) { ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) ; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1 -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ARG_MINUS_ONE]], [[ABS]] +; CHECK-NEXT: ret i1 [[CMP]] ; %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true) %arg_minus_one = add nsw i32 %arg, -1 @@ -54,7 +58,8 @@ define i1 @arg_minus_one_strict_greater(i32 %arg) { ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) ; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1 -; CHECK-NEXT: ret i1 false +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ARG_MINUS_ONE]], [[ABS]] +; CHECK-NEXT: ret i1 [[CMP]] ; %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true) %arg_minus_one = add nsw i32 %arg, -1 @@ -69,7 +74,8 @@ define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg(i32 %arg) { ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ARG_NONNEGATIVE]]) ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) ; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ABS]], 1 -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ABS_PLUS_ONE]], [[ARG]] +; CHECK-NEXT: ret i1 [[CMP]] ; %cmp_arg_nonnegative = icmp sge i32 %arg, 0 call void @llvm.assume(i1 %cmp_arg_nonnegative) @@ -142,7 +148,8 @@ define i1 @abs_is_nonnegative_int_min_is_poison(i32 %arg) { ; CHECK-LABEL: define i1 @abs_is_nonnegative_int_min_is_poison( ; CHECK-SAME: i32 [[ARG:%.*]]) { ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true) -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], 0 +; CHECK-NEXT: ret i1 [[CMP]] ; %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true) %cmp = icmp sge i32 %abs, 0 @@ -152,7 +159,8 @@ define i1 @abs_is_nonnegative_int_min_is_poison(i32 %arg) { define i1 @abs_is_nonnegative_constant_arg() { ; CHECK-LABEL: define i1 @abs_is_nonnegative_constant_arg() { ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 -3, i1 true) -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], 0 +; CHECK-NEXT: ret i1 [[CMP]] ; %abs = tail call i32 @llvm.abs.i32(i32 -3, i1 true) %cmp = icmp sge i32 %abs, 0 diff --git a/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll b/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll index ea0d0d42eb081..53d2f75964127 100644 --- a/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll +++ b/llvm/test/Transforms/ConstraintElimination/uadd-usub-sat.ll @@ -8,7 +8,9 @@ define i1 @uadd_sat_uge(i64 %a, i64 %b) { ; CHECK-LABEL: define i1 @uadd_sat_uge( ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[ADD_SAT:%.*]] = call i64 @llvm.uadd.sat.i64(i64 [[A]], i64 [[B]]) -; CHECK-NEXT: [[CMP:%.*]] = and i1 true, true +; 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: ret i1 [[CMP]] ; %add.sat = call i64 @llvm.uadd.sat.i64(i64 %a, i64 %b) @@ -22,7 +24,8 @@ define i1 @usub_sat_ule_lhs(i64 %a, i64 %b) { ; CHECK-LABEL: define i1 @usub_sat_ule_lhs( ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) { ; CHECK-NEXT: [[SUB_SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]]) -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[SUB_SAT]], [[A]] +; CHECK-NEXT: ret i1 [[CMP]] ; %sub.sat = call i64 @llvm.usub.sat.i64(i64 %a, i64 %b) %cmp = icmp ule i64 %sub.sat, %a