[llvm] [ConstraintElim] Simplify `MinMaxIntrinsic` (PR #75306)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 30 22:03:57 PST 2024
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/75306
>From 9b982f665e8a5a1ada473e9e82a9d4bb59b4d76f Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 9 Jan 2024 02:01:53 +0800
Subject: [PATCH 1/4] [ConstraintElim] Add pre-commit tests. NFC.
---
.../ConstraintElimination/minmax.ll | 265 ++++++++++++++++++
1 file changed, 265 insertions(+)
diff --git a/llvm/test/Transforms/ConstraintElimination/minmax.ll b/llvm/test/Transforms/ConstraintElimination/minmax.ll
index 82b932f14c4ff..94779e02b5d04 100644
--- a/llvm/test/Transforms/ConstraintElimination/minmax.ll
+++ b/llvm/test/Transforms/ConstraintElimination/minmax.ll
@@ -343,6 +343,271 @@ end:
ret i32 0
}
+; Test from PR75155
+define i32 @simplify_slt_smax_val(i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @simplify_slt_smax_val
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])
+; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 -1
+;
+start:
+ %cmp = icmp slt i32 %a, %b
+ br i1 %cmp, label %then, label %else
+then:
+ %add = add nsw i32 %a, 1
+ %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)
+ ret i32 %max
+else:
+ ret i32 -1
+}
+
+define i32 @simplify_slt_smax_val_commuted(i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @simplify_slt_smax_val_commuted
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[ADD]], i32 [[B]])
+; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 -1
+;
+start:
+ %cmp = icmp slt i32 %a, %b
+ br i1 %cmp, label %then, label %else
+then:
+ %add = add nsw i32 %a, 1
+ %max = call i32 @llvm.smax.i32(i32 %add, i32 %b)
+ ret i32 %max
+else:
+ ret i32 -1
+}
+
+define i32 @simplify_slt_smax_val_at_use(i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @simplify_slt_smax_val_at_use
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 -1
+;
+start:
+ %cmp = icmp slt i32 %a, %b
+ %add = add nsw i32 %a, 1
+ %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)
+ br i1 %cmp, label %then, label %else
+then:
+ ret i32 %max
+else:
+ ret i32 -1
+}
+
+define i32 @simplify_sgt_smax_val(i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @simplify_sgt_smax_val
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])
+; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 -1
+;
+start:
+ %cmp = icmp sgt i32 %a, %b
+ br i1 %cmp, label %then, label %else
+then:
+ %add = add nsw i32 %a, 1
+ %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)
+ ret i32 %max
+else:
+ ret i32 -1
+}
+
+define i32 @simplify_sle_smax_val(i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @simplify_sle_smax_val
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])
+; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 -1
+;
+start:
+ %cmp = icmp sle i32 %a, %b
+ br i1 %cmp, label %then, label %else
+then:
+ %add = add nsw i32 %a, 1
+ %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)
+ ret i32 %max
+else:
+ ret i32 -1
+}
+
+define i32 @simplify_sge_smax_val(i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @simplify_sge_smax_val
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])
+; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 -1
+;
+start:
+ %cmp = icmp sge i32 %a, %b
+ br i1 %cmp, label %then, label %else
+then:
+ %add = add nsw i32 %a, 1
+ %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)
+ ret i32 %max
+else:
+ ret i32 -1
+}
+
+define i32 @simplify_ult_umax_val(i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @simplify_ult_umax_val
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[B]], i32 [[ADD]])
+; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 -1
+;
+start:
+ %cmp = icmp ult i32 %a, %b
+ br i1 %cmp, label %then, label %else
+then:
+ %add = add nuw i32 %a, 1
+ %max = call i32 @llvm.umax.i32(i32 %b, i32 %add)
+ ret i32 %max
+else:
+ ret i32 -1
+}
+
+define i32 @simplify_slt_smin_val(i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @simplify_slt_smin_val
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smin.i32(i32 [[B]], i32 [[ADD]])
+; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 -1
+;
+start:
+ %cmp = icmp slt i32 %a, %b
+ br i1 %cmp, label %then, label %else
+then:
+ %add = add nsw i32 %a, 1
+ %max = call i32 @llvm.smin.i32(i32 %b, i32 %add)
+ ret i32 %max
+else:
+ ret i32 -1
+}
+
+define i32 @simplify_ult_umin_val(i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @simplify_ult_umin_val
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umin.i32(i32 [[B]], i32 [[ADD]])
+; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 -1
+;
+start:
+ %cmp = icmp ult i32 %a, %b
+ br i1 %cmp, label %then, label %else
+then:
+ %add = add nuw i32 %a, 1
+ %max = call i32 @llvm.umin.i32(i32 %b, i32 %add)
+ ret i32 %max
+else:
+ ret i32 -1
+}
+
+define i32 @simplify_slt_smax_val_fail1(i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @simplify_slt_smax_val_fail1
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 2
+; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])
+; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 -1
+;
+start:
+ %cmp = icmp slt i32 %a, %b
+ br i1 %cmp, label %then, label %else
+then:
+ %add = add nsw i32 %a, 2
+ %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)
+ ret i32 %max
+else:
+ ret i32 -1
+}
+
+define i32 @simplify_ult_smax_val_fail2(i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @simplify_ult_smax_val_fail2
+; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
+; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])
+; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 -1
+;
+start:
+ %cmp = icmp ult i32 %a, %b
+ br i1 %cmp, label %then, label %else
+then:
+ %add = add nsw i32 %a, 1
+ %max = call i32 @llvm.smax.i32(i32 %b, i32 %add)
+ ret i32 %max
+else:
+ ret i32 -1
+}
+
declare i32 @llvm.smin.i32(i32, i32)
declare i32 @llvm.smax.i32(i32, i32)
declare i32 @llvm.umin.i32(i32, i32)
>From 944cef078fe1ac8c3a46cd34526da17b5e67050f Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 9 Jan 2024 02:02:21 +0800
Subject: [PATCH 2/4] [ConstraintElim] Simplify `MinMaxIntrinsic`
---
.../Scalar/ConstraintElimination.cpp | 30 +++++++++++++++++++
.../ConstraintElimination/minmax.ll | 21 +++++--------
2 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index ae8e2292519cb..b4d3996e03567 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1072,6 +1072,8 @@ void State::addInfoFor(BasicBlock &BB) {
[[fallthrough]];
case Intrinsic::abs:
WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
+ WorkList.push_back(
+ FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
break;
}
@@ -1395,6 +1397,31 @@ static bool checkAndReplaceCondition(
return false;
}
+static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info,
+ unsigned NumIn, unsigned NumOut,
+ Instruction *ContextInst, DominatorTree &DT,
+ SmallVectorImpl<Instruction *> &ToRemove) {
+ auto ReplaceMinMaxWithOperand = [&](MinMaxIntrinsic *MinMax, bool UseLHS) {
+ // TODO: generate reproducer for min/max.
+ MinMax->replaceAllUsesWith(MinMax->getOperand(UseLHS ? 0 : 1));
+ if (MinMax->use_empty())
+ ToRemove.push_back(MinMax);
+ return true;
+ };
+
+ ICmpInst::Predicate Pred =
+ ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
+ if (auto ImpliedCondition =
+ checkCondition(Pred, MinMax->getOperand(0), MinMax->getOperand(1),
+ MinMax, Info, NumIn, NumOut, ContextInst))
+ return ReplaceMinMaxWithOperand(MinMax, *ImpliedCondition);
+ if (auto ImpliedCondition =
+ checkCondition(Pred, MinMax->getOperand(1), MinMax->getOperand(0),
+ MinMax, Info, NumIn, NumOut, ContextInst))
+ return ReplaceMinMaxWithOperand(MinMax, !*ImpliedCondition);
+ return false;
+}
+
static void
removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
Module *ReproducerModule,
@@ -1695,6 +1722,9 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
ReproducerCondStack, DFSInStack);
}
Changed |= Simplified;
+ } else if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(Inst)) {
+ Changed |= checkAndReplaceMinMax(MinMax, Info, CB.NumIn, CB.NumOut,
+ CB.getContextInst(), S.DT, ToRemove);
}
continue;
}
diff --git a/llvm/test/Transforms/ConstraintElimination/minmax.ll b/llvm/test/Transforms/ConstraintElimination/minmax.ll
index 94779e02b5d04..68513ea10ad0f 100644
--- a/llvm/test/Transforms/ConstraintElimination/minmax.ll
+++ b/llvm/test/Transforms/ConstraintElimination/minmax.ll
@@ -352,8 +352,7 @@ define i32 @simplify_slt_smax_val(i32 %a, i32 %b) {
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
-; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])
-; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK-NEXT: ret i32 [[B]]
; CHECK: else:
; CHECK-NEXT: ret i32 -1
;
@@ -376,8 +375,7 @@ define i32 @simplify_slt_smax_val_commuted(i32 %a, i32 %b) {
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
-; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[ADD]], i32 [[B]])
-; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK-NEXT: ret i32 [[B]]
; CHECK: else:
; CHECK-NEXT: ret i32 -1
;
@@ -424,8 +422,7 @@ define i32 @simplify_sgt_smax_val(i32 %a, i32 %b) {
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
-; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])
-; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK-NEXT: ret i32 [[ADD]]
; CHECK: else:
; CHECK-NEXT: ret i32 -1
;
@@ -472,8 +469,7 @@ define i32 @simplify_sge_smax_val(i32 %a, i32 %b) {
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
-; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[ADD]])
-; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK-NEXT: ret i32 [[ADD]]
; CHECK: else:
; CHECK-NEXT: ret i32 -1
;
@@ -496,8 +492,7 @@ define i32 @simplify_ult_umax_val(i32 %a, i32 %b) {
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], 1
-; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[B]], i32 [[ADD]])
-; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK-NEXT: ret i32 [[B]]
; CHECK: else:
; CHECK-NEXT: ret i32 -1
;
@@ -520,8 +515,7 @@ define i32 @simplify_slt_smin_val(i32 %a, i32 %b) {
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
-; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smin.i32(i32 [[B]], i32 [[ADD]])
-; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK-NEXT: ret i32 [[ADD]]
; CHECK: else:
; CHECK-NEXT: ret i32 -1
;
@@ -544,8 +538,7 @@ define i32 @simplify_ult_umin_val(i32 %a, i32 %b) {
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], 1
-; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umin.i32(i32 [[B]], i32 [[ADD]])
-; CHECK-NEXT: ret i32 [[MAX]]
+; CHECK-NEXT: ret i32 [[ADD]]
; CHECK: else:
; CHECK-NEXT: ret i32 -1
;
>From 83589925655efff3ed66e67c1ce08a5b15708d16 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 22 Jan 2024 11:30:12 +0800
Subject: [PATCH 3/4] fixup! [ConstraintElim] Simplify `MinMaxIntrinsic`
---
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index b4d3996e03567..7b92905ce96ee 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1072,8 +1072,10 @@ void State::addInfoFor(BasicBlock &BB) {
[[fallthrough]];
case Intrinsic::abs:
WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
- WorkList.push_back(
- FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
+ // TODO: handle llvm.abs as well
+ if (ID != Intrinsic::abs)
+ WorkList.push_back(
+ FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
break;
}
>From 5f8a748fa7858ae8b0718be785d4ada6ea5094c6 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 31 Jan 2024 14:02:24 +0800
Subject: [PATCH 4/4] fixup! [ConstraintElim] Simplify `MinMaxIntrinsic`
---
.../Scalar/ConstraintElimination.cpp | 25 +++++++------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 7b92905ce96ee..97cf5ebe3ca06 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1065,6 +1065,9 @@ 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
// when simplifying uses of the min/max intrinsics.
if (!isGuaranteedNotToBePoison(&I))
@@ -1072,10 +1075,6 @@ void State::addInfoFor(BasicBlock &BB) {
[[fallthrough]];
case Intrinsic::abs:
WorkList.push_back(FactOrCheck::getInstFact(DT.getNode(&BB), &I));
- // TODO: handle llvm.abs as well
- if (ID != Intrinsic::abs)
- WorkList.push_back(
- FactOrCheck::getCheck(DT.getNode(&BB), cast<CallInst>(&I)));
break;
}
@@ -1400,26 +1399,21 @@ static bool checkAndReplaceCondition(
}
static bool checkAndReplaceMinMax(MinMaxIntrinsic *MinMax, ConstraintInfo &Info,
- unsigned NumIn, unsigned NumOut,
- Instruction *ContextInst, DominatorTree &DT,
SmallVectorImpl<Instruction *> &ToRemove) {
auto ReplaceMinMaxWithOperand = [&](MinMaxIntrinsic *MinMax, bool UseLHS) {
// TODO: generate reproducer for min/max.
MinMax->replaceAllUsesWith(MinMax->getOperand(UseLHS ? 0 : 1));
- if (MinMax->use_empty())
- ToRemove.push_back(MinMax);
+ ToRemove.push_back(MinMax);
return true;
};
ICmpInst::Predicate Pred =
ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
- if (auto ImpliedCondition =
- checkCondition(Pred, MinMax->getOperand(0), MinMax->getOperand(1),
- MinMax, Info, NumIn, NumOut, ContextInst))
+ if (auto ImpliedCondition = checkCondition(
+ Pred, MinMax->getOperand(0), MinMax->getOperand(1), MinMax, Info))
return ReplaceMinMaxWithOperand(MinMax, *ImpliedCondition);
- if (auto ImpliedCondition =
- checkCondition(Pred, MinMax->getOperand(1), MinMax->getOperand(0),
- MinMax, Info, NumIn, NumOut, ContextInst))
+ if (auto ImpliedCondition = checkCondition(
+ Pred, MinMax->getOperand(1), MinMax->getOperand(0), MinMax, Info))
return ReplaceMinMaxWithOperand(MinMax, !*ImpliedCondition);
return false;
}
@@ -1725,8 +1719,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
}
Changed |= Simplified;
} else if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(Inst)) {
- Changed |= checkAndReplaceMinMax(MinMax, Info, CB.NumIn, CB.NumOut,
- CB.getContextInst(), S.DT, ToRemove);
+ Changed |= checkAndReplaceMinMax(MinMax, Info, ToRemove);
}
continue;
}
More information about the llvm-commits
mailing list