[llvm-branch-commits] [llvm] [ConstraintElim] Opimize abs based on known constraints (PR #135754)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Apr 18 03:26:56 PDT 2025
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/135754
>From 49fa9b3b040a8ff9ee7ba9a0f082dcb5916c962c Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 15 Apr 2025 15:00:58 +0800
Subject: [PATCH 1/4] [ConstraintElim] Opimize abs based on known constraints
---
.../Scalar/ConstraintElimination.cpp | 28 +++++++++++-
.../Transforms/ConstraintElimination/abs.ll | 43 +++++++++++++++++++
2 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 8a05d0c1ddf5a..9930b3ea106d9 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1128,6 +1128,7 @@ void State::addInfoFor(BasicBlock &BB) {
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:
@@ -1139,7 +1140,6 @@ void State::addInfoFor(BasicBlock &BB) {
// TODO: Check if it is possible to instead only added the min/max facts
// when simplifying uses of the min/max intrinsics.
[[fallthrough]];
- case Intrinsic::abs:
case Intrinsic::uadd_sat:
if (!isGuaranteedNotToBePoison(&I))
break;
@@ -1537,6 +1537,28 @@ static bool checkAndReplaceUSubSat(SaturatingInst *I, ConstraintInfo &Info,
return false;
}
+static bool checkAndReplaceAbs(IntrinsicInst *I, ConstraintInfo &Info,
+ SmallVectorImpl<Instruction *> &ToRemove) {
+ assert(I->getIntrinsicID() == Intrinsic::abs && "Expected abs intrinsic");
+ Value *Op = I->getOperand(0);
+ if (checkCondition(ICmpInst::ICMP_SGE, Op, ConstantInt::get(Op->getType(), 0),
+ I, Info)
+ .value_or(false)) {
+ I->replaceAllUsesWith(Op);
+ ToRemove.push_back(I);
+ return true;
+ }
+ if (checkCondition(ICmpInst::ICMP_SLT, Op, ConstantInt::get(Op->getType(), 0),
+ I, Info)
+ .value_or(false)) {
+ IRBuilder<> Builder(I->getParent(), I->getIterator());
+ I->replaceAllUsesWith(Builder.CreateNeg(Op));
+ ToRemove.push_back(I);
+ return true;
+ }
+ return false;
+}
+
static void
removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
Module *ReproducerModule,
@@ -1863,6 +1885,10 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
Changed |= checkAndReplaceUSubSat(SatIntr, Info, ToRemove);
else
llvm_unreachable("Unexpected intrinsic.");
+ } else if (auto *II = dyn_cast<IntrinsicInst>(Inst)) {
+ if (II->getIntrinsicID() == Intrinsic::abs) {
+ Changed |= checkAndReplaceAbs(II, Info, ToRemove);
+ }
}
continue;
}
diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll
index a0c22d9f03c28..001d2cf3c2120 100644
--- a/llvm/test/Transforms/ConstraintElimination/abs.ll
+++ b/llvm/test/Transforms/ConstraintElimination/abs.ll
@@ -167,5 +167,48 @@ define i1 @abs_is_nonnegative_constant_arg() {
ret i1 %cmp
}
+define i64 @abs_assume_nonnegative(i64 %arg) {
+; CHECK-LABEL: define i64 @abs_assume_nonnegative(
+; CHECK-SAME: i64 [[ARG:%.*]]) {
+; CHECK-NEXT: [[PRECOND:%.*]] = icmp sge i64 [[ARG]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]])
+; CHECK-NEXT: [[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false)
+; CHECK-NEXT: ret i64 [[ABS]]
+;
+ %precond = icmp sge i64 %arg, 0
+ call void @llvm.assume(i1 %precond)
+ %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false)
+ ret i64 %abs
+}
+
+define i64 @abs_assume_negative(i64 %arg) {
+; CHECK-LABEL: define i64 @abs_assume_negative(
+; CHECK-SAME: i64 [[ARG:%.*]]) {
+; CHECK-NEXT: [[PRECOND:%.*]] = icmp slt i64 [[ARG]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]])
+; CHECK-NEXT: [[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false)
+; CHECK-NEXT: ret i64 [[ABS]]
+;
+ %precond = icmp slt i64 %arg, 0
+ call void @llvm.assume(i1 %precond)
+ %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false)
+ ret i64 %abs
+}
+
+; Negative test
+define i64 @abs_assume_unrelated(i64 %arg) {
+; CHECK-LABEL: define i64 @abs_assume_unrelated(
+; CHECK-SAME: i64 [[ARG:%.*]]) {
+; CHECK-NEXT: [[PRECOND:%.*]] = icmp slt i64 [[ARG]], 3
+; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]])
+; CHECK-NEXT: [[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false)
+; CHECK-NEXT: ret i64 [[ABS]]
+;
+ %precond = icmp slt i64 %arg, 3
+ call void @llvm.assume(i1 %precond)
+ %abs = tail call i64 @llvm.abs.i64(i64 %arg, i1 false)
+ ret i64 %abs
+}
+
declare i32 @llvm.abs.i32(i32, i1 immarg)
declare void @llvm.assume(i1)
>From 7484739aeae59f3521869eaf51927724bc074272 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 15 Apr 2025 15:03:08 +0800
Subject: [PATCH 2/4] update test
---
llvm/test/Transforms/ConstraintElimination/abs.ll | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll
index 001d2cf3c2120..637fc49b01437 100644
--- a/llvm/test/Transforms/ConstraintElimination/abs.ll
+++ b/llvm/test/Transforms/ConstraintElimination/abs.ll
@@ -101,9 +101,7 @@ define i1 @abs_plus_one_unsigned_greater_or_equal_cannot_be_simplified(i32 %arg)
define i1 @abs_constant_negative_arg() {
; CHECK-LABEL: define i1 @abs_constant_negative_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
@@ -112,7 +110,6 @@ 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: ret i1 true
;
%abs = tail call i32 @llvm.abs.i32(i32 3, i1 false)
@@ -172,8 +169,7 @@ define i64 @abs_assume_nonnegative(i64 %arg) {
; CHECK-SAME: i64 [[ARG:%.*]]) {
; CHECK-NEXT: [[PRECOND:%.*]] = icmp sge i64 [[ARG]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]])
-; CHECK-NEXT: [[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false)
-; CHECK-NEXT: ret i64 [[ABS]]
+; CHECK-NEXT: ret i64 [[ARG]]
;
%precond = icmp sge i64 %arg, 0
call void @llvm.assume(i1 %precond)
@@ -186,7 +182,7 @@ define i64 @abs_assume_negative(i64 %arg) {
; CHECK-SAME: i64 [[ARG:%.*]]) {
; CHECK-NEXT: [[PRECOND:%.*]] = icmp slt i64 [[ARG]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]])
-; CHECK-NEXT: [[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[ARG]], i1 false)
+; CHECK-NEXT: [[ABS:%.*]] = sub i64 0, [[ARG]]
; CHECK-NEXT: ret i64 [[ABS]]
;
%precond = icmp slt i64 %arg, 0
>From 5127b51d16cee63f3ff2fbdc52128e0a41c76293 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 15 Apr 2025 16:58:39 +0800
Subject: [PATCH 3/4] match abs only
---
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 9930b3ea106d9..ed46e125e1f68 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1880,15 +1880,14 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove);
} else if (auto *CmpIntr = dyn_cast<CmpIntrinsic>(Inst)) {
Changed |= checkAndReplaceCmp(CmpIntr, Info, ToRemove);
+ } else if (match(Inst, m_Intrinsic<Intrinsic::abs>(m_Value()))) {
+ Changed |=
+ checkAndReplaceAbs(dyn_cast<IntrinsicInst>(Inst), Info, ToRemove);
} else if (auto *SatIntr = dyn_cast<SaturatingInst>(Inst)) {
if (SatIntr->getIntrinsicID() == Intrinsic::usub_sat)
Changed |= checkAndReplaceUSubSat(SatIntr, Info, ToRemove);
else
llvm_unreachable("Unexpected intrinsic.");
- } else if (auto *II = dyn_cast<IntrinsicInst>(Inst)) {
- if (II->getIntrinsicID() == Intrinsic::abs) {
- Changed |= checkAndReplaceAbs(II, Info, ToRemove);
- }
}
continue;
}
>From 157aa8acd5180e333b717428f7e1e567b28240ab Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 15 Apr 2025 21:29:43 +0800
Subject: [PATCH 4/4] add nopoison back
---
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp | 1 -
llvm/test/Transforms/ConstraintElimination/abs.ll | 10 +++-------
2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index ed46e125e1f68..d62fae410ce21 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1134,7 +1134,6 @@ void State::addInfoFor(BasicBlock &BB) {
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<CallInst>(&I)));
// TODO: Check if it is possible to instead only added the min/max facts
diff --git a/llvm/test/Transforms/ConstraintElimination/abs.ll b/llvm/test/Transforms/ConstraintElimination/abs.ll
index 637fc49b01437..a49b4643ab92c 100644
--- a/llvm/test/Transforms/ConstraintElimination/abs.ll
+++ b/llvm/test/Transforms/ConstraintElimination/abs.ll
@@ -72,10 +72,8 @@ define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg(i32 %arg) {
; CHECK-SAME: i32 [[ARG:%.*]]) {
; CHECK-NEXT: [[CMP_ARG_NONNEGATIVE:%.*]] = icmp sge i32 [[ARG]], 0
; 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: [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ARG]], 1
+; CHECK-NEXT: ret i1 true
;
%cmp_arg_nonnegative = icmp sge i32 %arg, 0
call void @llvm.assume(i1 %cmp_arg_nonnegative)
@@ -155,9 +153,7 @@ 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: [[CMP:%.*]] = icmp sge i32 [[ABS]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 true
;
%abs = tail call i32 @llvm.abs.i32(i32 -3, i1 true)
%cmp = icmp sge i32 %abs, 0
More information about the llvm-branch-commits
mailing list