Skip to content

Commit 0014eaf

Browse files
[ConstraintElim] Add facts implied by llvm.abs
1 parent 69bc371 commit 0014eaf

File tree

2 files changed

+38
-30
lines changed

2 files changed

+38
-30
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,22 +1010,14 @@ void State::addInfoFor(BasicBlock &BB) {
10101010
continue;
10111011
}
10121012

1013-
if (match(&I, m_Intrinsic<Intrinsic::ssub_with_overflow>())) {
1014-
WorkList.push_back(
1015-
FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1016-
continue;
1017-
}
1018-
1019-
if (isa<MinMaxIntrinsic>(&I)) {
1020-
WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
1021-
continue;
1022-
}
1023-
1024-
Value *A, *B;
1025-
CmpInst::Predicate Pred;
1026-
// For now, just handle assumes with a single compare as condition.
1027-
if (match(&I, m_Intrinsic<Intrinsic::assume>(
1028-
m_ICmp(Pred, m_Value(A), m_Value(B))))) {
1013+
auto *II = dyn_cast<IntrinsicInst>(&I);
1014+
Intrinsic::ID ID = II ? II->getIntrinsicID() : Intrinsic::not_intrinsic;
1015+
switch (ID) {
1016+
case Intrinsic::assume: {
1017+
Value *A, *B;
1018+
CmpInst::Predicate Pred;
1019+
if (!match(I.getOperand(0), m_ICmp(Pred, m_Value(A), m_Value(B))))
1020+
break;
10291021
if (GuaranteedToExecute) {
10301022
// The assume is guaranteed to execute when BB is entered, hence Cond
10311023
// holds on entry to BB.
@@ -1035,7 +1027,23 @@ void State::addInfoFor(BasicBlock &BB) {
10351027
WorkList.emplace_back(
10361028
FactOrCheck::getInstFact(DT.getNode(I.getParent()), &I));
10371029
}
1030+
break;
10381031
}
1032+
// Enqueue ssub_with_overflow for simplification.
1033+
case Intrinsic::ssub_with_overflow:
1034+
WorkList.push_back(
1035+
FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
1036+
break;
1037+
// Enqueue the intrinsics to add extra info.
1038+
case Intrinsic::abs:
1039+
case Intrinsic::umin:
1040+
case Intrinsic::umax:
1041+
case Intrinsic::smin:
1042+
case Intrinsic::smax:
1043+
WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
1044+
break;
1045+
}
1046+
10391047
GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor(&I);
10401048
}
10411049

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

16941702
ICmpInst::Predicate Pred;
16951703
if (!CB.isConditionFact()) {
1704+
Value *X;
1705+
if (match(CB.Inst, m_Intrinsic<Intrinsic::abs>(m_Value(X)))) {
1706+
// TODO: Add CB.Inst >= 0 fact.
1707+
AddFact(CmpInst::ICMP_SGE, CB.Inst, X);
1708+
continue;
1709+
}
1710+
16961711
if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(CB.Inst)) {
16971712
Pred = ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
16981713
AddFact(Pred, MinMax, MinMax->getLHS());

llvm/test/Transforms/ConstraintElimination/abs.ll

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ define i1 @abs_int_min_is_not_poison(i32 %arg) {
55
; CHECK-LABEL: define i1 @abs_int_min_is_not_poison(
66
; CHECK-SAME: i32 [[ARG:%.*]]) {
77
; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)
8-
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], [[ARG]]
9-
; CHECK-NEXT: ret i1 [[CMP]]
8+
; CHECK-NEXT: ret i1 true
109
;
1110
%abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)
1211
%cmp = icmp sge i32 %abs, %arg
@@ -17,8 +16,7 @@ define i1 @abs_int_min_is_poison(i32 %arg) {
1716
; CHECK-LABEL: define i1 @abs_int_min_is_poison(
1817
; CHECK-SAME: i32 [[ARG:%.*]]) {
1918
; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
20-
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], [[ARG]]
21-
; CHECK-NEXT: ret i1 [[CMP]]
19+
; CHECK-NEXT: ret i1 true
2220
;
2321
%abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
2422
%cmp = icmp sge i32 %abs, %arg
@@ -30,8 +28,7 @@ define i1 @abs_plus_one(i32 %arg) {
3028
; CHECK-SAME: i32 [[ARG:%.*]]) {
3129
; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
3230
; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nsw i32 [[ABS]], 1
33-
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS_PLUS_ONE]], [[ARG]]
34-
; CHECK-NEXT: ret i1 [[CMP]]
31+
; CHECK-NEXT: ret i1 true
3532
;
3633
%abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
3734
%abs_plus_one = add nsw i32 %abs, 1
@@ -44,8 +41,7 @@ define i1 @arg_minus_one_strict_less(i32 %arg) {
4441
; CHECK-SAME: i32 [[ARG:%.*]]) {
4542
; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
4643
; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1
47-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ARG_MINUS_ONE]], [[ABS]]
48-
; CHECK-NEXT: ret i1 [[CMP]]
44+
; CHECK-NEXT: ret i1 true
4945
;
5046
%abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
5147
%arg_minus_one = add nsw i32 %arg, -1
@@ -58,8 +54,7 @@ define i1 @arg_minus_one_strict_greater(i32 %arg) {
5854
; CHECK-SAME: i32 [[ARG:%.*]]) {
5955
; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
6056
; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1
61-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ARG_MINUS_ONE]], [[ABS]]
62-
; CHECK-NEXT: ret i1 [[CMP]]
57+
; CHECK-NEXT: ret i1 false
6358
;
6459
%abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
6560
%arg_minus_one = add nsw i32 %arg, -1
@@ -74,8 +69,7 @@ define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg(i32 %arg) {
7469
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ARG_NONNEGATIVE]])
7570
; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
7671
; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ABS]], 1
77-
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ABS_PLUS_ONE]], [[ARG]]
78-
; CHECK-NEXT: ret i1 [[CMP]]
72+
; CHECK-NEXT: ret i1 true
7973
;
8074
%cmp_arg_nonnegative = icmp sge i32 %arg, 0
8175
call void @llvm.assume(i1 %cmp_arg_nonnegative)
@@ -113,8 +107,7 @@ define i1 @abs_constant_negative_arg() {
113107
define i1 @abs_constant_positive_arg() {
114108
; CHECK-LABEL: define i1 @abs_constant_positive_arg() {
115109
; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 3, i1 false)
116-
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], 3
117-
; CHECK-NEXT: ret i1 [[CMP]]
110+
; CHECK-NEXT: ret i1 true
118111
;
119112
%abs = tail call i32 @llvm.abs.i32(i32 3, i1 false)
120113
%cmp = icmp sge i32 %abs, 3

0 commit comments

Comments
 (0)