Skip to content

Commit

Permalink
[ConstraintElim] Add facts implied by llvm.abs (#73189)
Browse files Browse the repository at this point in the history
Add  "abs(x) >=s x" fact.

https://alive2.llvm.org/ce/z/gOrrU3

Test plan: ninja check-all
  • Loading branch information
alexander-shaposhnikov committed Jan 2, 2024
1 parent d6c4d4c commit 3af59cf
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 30 deletions.
47 changes: 31 additions & 16 deletions llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1010,22 +1010,14 @@ void State::addInfoFor(BasicBlock &BB) {
continue;
}

if (match(&I, m_Intrinsic<Intrinsic::ssub_with_overflow>())) {
WorkList.push_back(
FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
continue;
}

if (isa<MinMaxIntrinsic>(&I)) {
WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
continue;
}

Value *A, *B;
CmpInst::Predicate Pred;
// For now, just handle assumes with a single compare as condition.
if (match(&I, m_Intrinsic<Intrinsic::assume>(
m_ICmp(Pred, m_Value(A), m_Value(B))))) {
auto *II = dyn_cast<IntrinsicInst>(&I);
Intrinsic::ID ID = II ? II->getIntrinsicID() : Intrinsic::not_intrinsic;
switch (ID) {
case Intrinsic::assume: {
Value *A, *B;
CmpInst::Predicate Pred;
if (!match(I.getOperand(0), m_ICmp(Pred, m_Value(A), m_Value(B))))
break;
if (GuaranteedToExecute) {
// The assume is guaranteed to execute when BB is entered, hence Cond
// holds on entry to BB.
Expand All @@ -1035,7 +1027,23 @@ void State::addInfoFor(BasicBlock &BB) {
WorkList.emplace_back(
FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
}
break;
}
// Enqueue ssub_with_overflow for simplification.
case Intrinsic::ssub_with_overflow:
WorkList.push_back(
FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
break;
// Enqueue the intrinsics to add extra info.
case Intrinsic::abs:
case Intrinsic::umin:
case Intrinsic::umax:
case Intrinsic::smin:
case Intrinsic::smax:
WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
break;
}

GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I);
}

Expand Down Expand Up @@ -1693,6 +1701,13 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,

ICmpInst::Predicate Pred;
if (!CB.isConditionFact()) {
Value *X;
if (match(CB.Inst, m_Intrinsic<Intrinsic::abs>(m_Value(X)))) {
// TODO: Add CB.Inst >= 0 fact.
AddFact(CmpInst::ICMP_SGE, CB.Inst, X);
continue;
}

if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst)) {
Pred = ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
AddFact(Pred, MinMax, MinMax->getLHS());
Expand Down
21 changes: 7 additions & 14 deletions llvm/test/Transforms/ConstraintElimination/abs.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ 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: [[CMP:%.*]] = icmp sge i32 [[ABS]], [[ARG]]
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK-NEXT: ret i1 true
;
%abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)
%cmp = icmp sge i32 %abs, %arg
Expand All @@ -17,8 +16,7 @@ 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: [[CMP:%.*]] = icmp sge i32 [[ABS]], [[ARG]]
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK-NEXT: ret i1 true
;
%abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
%cmp = icmp sge i32 %abs, %arg
Expand All @@ -30,8 +28,7 @@ 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: [[CMP:%.*]] = icmp sge i32 [[ABS_PLUS_ONE]], [[ARG]]
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK-NEXT: ret i1 true
;
%abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
%abs_plus_one = add nsw i32 %abs, 1
Expand All @@ -44,8 +41,7 @@ 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: [[CMP:%.*]] = icmp slt i32 [[ARG_MINUS_ONE]], [[ABS]]
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK-NEXT: ret i1 true
;
%abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
%arg_minus_one = add nsw i32 %arg, -1
Expand All @@ -58,8 +54,7 @@ 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: [[CMP:%.*]] = icmp sgt i32 [[ARG_MINUS_ONE]], [[ABS]]
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK-NEXT: ret i1 false
;
%abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
%arg_minus_one = add nsw i32 %arg, -1
Expand All @@ -74,8 +69,7 @@ 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: [[CMP:%.*]] = icmp uge i32 [[ABS_PLUS_ONE]], [[ARG]]
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK-NEXT: ret i1 true
;
%cmp_arg_nonnegative = icmp sge i32 %arg, 0
call void @llvm.assume(i1 %cmp_arg_nonnegative)
Expand Down Expand Up @@ -113,8 +107,7 @@ define i1 @abs_constant_negative_arg() {
define i1 @abs_constant_positive_arg() {
; CHECK-LABEL: define i1 @abs_constant_positive_arg() {
; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 3, i1 false)
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], 3
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK-NEXT: ret i1 true
;
%abs = tail call i32 @llvm.abs.i32(i32 3, i1 false)
%cmp = icmp sge i32 %abs, 3
Expand Down

0 comments on commit 3af59cf

Please sign in to comment.