[llvm] f6a8775 - [InstSimplify] Fold icmp of uadd.sat/usub.sat (PR63381)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 19 02:49:48 PDT 2023
Author: Nikita Popov
Date: 2023-06-19T11:49:38+02:00
New Revision: f6a8775c5d9fa6cd49f404da70982f2e7b91c88c
URL: https://github.com/llvm/llvm-project/commit/f6a8775c5d9fa6cd49f404da70982f2e7b91c88c
DIFF: https://github.com/llvm/llvm-project/commit/f6a8775c5d9fa6cd49f404da70982f2e7b91c88c.diff
LOG: [InstSimplify] Fold icmp of uadd.sat/usub.sat (PR63381)
Fold uadd.sat(X, Y) uge X and usub.sat(X, Y) ule X to true.
Proof: https://alive2.llvm.org/ce/z/596m9X
Fixes https://github.com/llvm/llvm-project/issues/63381.
Added:
Modified:
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/saturating-add-sub.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 616873f87f313..48ffa83d45cee 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3682,6 +3682,36 @@ static Value *simplifyICmpWithDominatingAssume(CmpInst::Predicate Predicate,
return nullptr;
}
+static Value *simplifyICmpWithIntrinsicOnLHS(CmpInst::Predicate Pred,
+ Value *LHS, Value *RHS) {
+ auto *II = dyn_cast<IntrinsicInst>(LHS);
+ if (!II)
+ return nullptr;
+
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::uadd_sat:
+ // uadd.sat(X, Y) uge X, uadd.sat(X, Y) uge Y
+ if (II->getArgOperand(0) == RHS || II->getArgOperand(1) == RHS) {
+ if (Pred == ICmpInst::ICMP_UGE)
+ return ConstantInt::getTrue(getCompareTy(II));
+ if (Pred == ICmpInst::ICMP_ULT)
+ return ConstantInt::getFalse(getCompareTy(II));
+ }
+ return nullptr;
+ case Intrinsic::usub_sat:
+ // usub.sat(X, Y) ule X
+ if (II->getArgOperand(0) == RHS) {
+ if (Pred == ICmpInst::ICMP_ULE)
+ return ConstantInt::getTrue(getCompareTy(II));
+ if (Pred == ICmpInst::ICMP_UGT)
+ return ConstantInt::getFalse(getCompareTy(II));
+ }
+ return nullptr;
+ default:
+ return nullptr;
+ }
+}
+
/// Given operands for an ICmpInst, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
@@ -3946,6 +3976,12 @@ static Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
if (Value *V = simplifyICmpWithMinMax(Pred, LHS, RHS, Q, MaxRecurse))
return V;
+ if (Value *V = simplifyICmpWithIntrinsicOnLHS(Pred, LHS, RHS))
+ return V;
+ if (Value *V = simplifyICmpWithIntrinsicOnLHS(
+ ICmpInst::getSwappedPredicate(Pred), RHS, LHS))
+ return V;
+
if (Value *V = simplifyICmpWithDominatingAssume(Pred, LHS, RHS, Q))
return V;
diff --git a/llvm/test/Transforms/InstSimplify/saturating-add-sub.ll b/llvm/test/Transforms/InstSimplify/saturating-add-sub.ll
index 616a2060e5339..6fb12612f2f72 100644
--- a/llvm/test/Transforms/InstSimplify/saturating-add-sub.ll
+++ b/llvm/test/Transforms/InstSimplify/saturating-add-sub.ll
@@ -797,9 +797,7 @@ define i1 @ssub_icmp_op1_smin(i8 %a) {
define i1 @uadd_uge(i8 %x, i8 %y) {
; CHECK-LABEL: @uadd_uge(
-; CHECK-NEXT: [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[SAT]], [[X]]
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 true
;
%sat = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
%cmp = icmp uge i8 %sat, %x
@@ -808,9 +806,7 @@ define i1 @uadd_uge(i8 %x, i8 %y) {
define i1 @uadd_uge_rhs(i8 %x, i8 %y) {
; CHECK-LABEL: @uadd_uge_rhs(
-; CHECK-NEXT: [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[SAT]], [[Y]]
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 true
;
%sat = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
%cmp = icmp uge i8 %sat, %y
@@ -819,9 +815,7 @@ define i1 @uadd_uge_rhs(i8 %x, i8 %y) {
define i1 @uadd_uge_commuted(i8 %x, i8 %y) {
; CHECK-LABEL: @uadd_uge_commuted(
-; CHECK-NEXT: [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[X]], [[SAT]]
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 true
;
%sat = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
%cmp = icmp ule i8 %x, %sat
@@ -830,9 +824,7 @@ define i1 @uadd_uge_commuted(i8 %x, i8 %y) {
define i1 @uadd_ult(i8 %x, i8 %y) {
; CHECK-LABEL: @uadd_ult(
-; CHECK-NEXT: [[SAT:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[SAT]], [[X]]
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%sat = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
%cmp = icmp ult i8 %sat, %x
@@ -841,9 +833,7 @@ define i1 @uadd_ult(i8 %x, i8 %y) {
define <2 x i1> @uadd_uge_vec(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @uadd_uge_vec(
-; CHECK-NEXT: [[SAT:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp uge <2 x i8> [[SAT]], [[X]]
-; CHECK-NEXT: ret <2 x i1> [[CMP]]
+; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
;
%sat = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %x, <2 x i8> %y)
%cmp = icmp uge <2 x i8> %sat, %x
@@ -885,9 +875,7 @@ define i1 @uadd_uge_unrelated_op_fail(i8 %x, i8 %y, i8 %z) {
define i1 @usub_ule(i8 %x, i8 %y) {
; CHECK-LABEL: @usub_ule(
-; CHECK-NEXT: [[SAT:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ule i8 [[SAT]], [[X]]
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 true
;
%sat = call i8 @llvm.usub.sat.i8(i8 %x, i8 %y)
%cmp = icmp ule i8 %sat, %x
@@ -907,9 +895,7 @@ define i1 @usub_ule_rhs_fail(i8 %x, i8 %y) {
define i1 @usub_ule_commuted(i8 %x, i8 %y) {
; CHECK-LABEL: @usub_ule_commuted(
-; CHECK-NEXT: [[SAT:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[X]], [[SAT]]
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 true
;
%sat = call i8 @llvm.usub.sat.i8(i8 %x, i8 %y)
%cmp = icmp uge i8 %x, %sat
@@ -918,9 +904,7 @@ define i1 @usub_ule_commuted(i8 %x, i8 %y) {
define i1 @usub_ugt(i8 %x, i8 %y) {
; CHECK-LABEL: @usub_ugt(
-; CHECK-NEXT: [[SAT:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[SAT]], [[X]]
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%sat = call i8 @llvm.usub.sat.i8(i8 %x, i8 %y)
%cmp = icmp ugt i8 %sat, %x
More information about the llvm-commits
mailing list