-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[ConstraintElim] Opimize abs based on known constraints #135754
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/el-ev/04-15-_constraintelim_optimize_usub.sat_intrinsic_based_on_known_constraints
Are you sure you want to change the base?
Conversation
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
✅ With the latest revision this PR passed the C/C++ code formatter. |
@llvm/pr-subscribers-llvm-transforms Author: Iris (el-ev) Changes[ConstraintElim] Opimize abs based on known constraints update test Full diff: https://github.com/llvm/llvm-project/pull/135754.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 6608d65f797c5..9eedd701b5e00 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1132,7 +1132,6 @@ void State::addInfoFor(BasicBlock &BB) {
case Intrinsic::umax:
case Intrinsic::smin:
case Intrinsic::smax:
- // 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
@@ -1140,11 +1139,11 @@ void State::addInfoFor(BasicBlock &BB) {
if (isGuaranteedNotToBePoison(&I))
WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
break;
+ case Intrinsic::abs:
case Intrinsic::usub_sat:
WorkList.push_back(
FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
[[fallthrough]];
- case Intrinsic::abs:
case Intrinsic::uadd_sat:
WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
break;
@@ -1540,6 +1539,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,
@@ -1866,6 +1887,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 9fc68b0e72663..e09a061410f48 100644
--- a/llvm/test/Transforms/ConstraintElimination/abs.ll
+++ b/llvm/test/Transforms/ConstraintElimination/abs.ll
@@ -67,8 +67,7 @@ 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: [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ARG]], 1
; CHECK-NEXT: ret i1 true
;
%cmp_arg_nonnegative = icmp sge i32 %arg, 0
@@ -95,9 +94,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
@@ -106,7 +103,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)
@@ -151,7 +147,6 @@ 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
;
%abs = tail call i32 @llvm.abs.i32(i32 -3, i1 true)
@@ -159,5 +154,47 @@ 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: ret i64 [[ARG]]
+;
+ %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:%.*]] = sub i64 0, [[ARG]]
+; 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)
|
76b4b28
to
dcd5cf9
Compare
aac90e1
to
d2dd4c4
Compare
6e3bb61
to
079a353
Compare
d2dd4c4
to
b705cbc
Compare
079a353
to
f051f42
Compare
b705cbc
to
beee270
Compare
beee270
to
33ba7e5
Compare
f051f42
to
1c0a426
Compare
33ba7e5
to
9b486eb
Compare
1c0a426
to
157aa8a
Compare
[ConstraintElim] Opimize abs based on known constraints
update test