-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[ValueTracking] Simplify uaddo pattern #65910
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
Conversation
@llvm/pr-subscribers-llvm-analysis ChangesThis patch simplifies the overflow check of unsigned addition.
Alive2: https://alive2.llvm.org/ce/z/H8oK8n -- 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index c4153b824c37e0a..e77310ca1fdf01c 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8291,6 +8291,26 @@ static std::optional isImpliedCondICmps(const ICmpInst *LHS, if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC))) return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC); + // L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 |
e9c7e08
to
9bb817a
Compare
Please can you pre-commit the tests to show the IR diff? |
@llvm/pr-subscribers-llvm-transforms ChangesThis patch simplifies the overflow check of unsigned addition.
Alive2: https://alive2.llvm.org/ce/z/H8oK8n Full diff: https://github.com/llvm/llvm-project/pull/65910.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index c4153b824c37e0a..5aaff4ee81be969 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8291,6 +8291,29 @@ static std::optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC)))
return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC);
+ // L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 <u L1 implies R0 <u R1
+ if (ICmpInst::isUnsigned(LPred) && ICmpInst::isUnsigned(RPred)) {
+ if (L0 == R1) {
+ std::swap(R0, R1);
+ RPred = ICmpInst::getSwappedPredicate(RPred);
+ }
+ if (L1 == R0) {
+ std::swap(L0, L1);
+ LPred = ICmpInst::getSwappedPredicate(LPred);
+ }
+ if (L1 == R1) {
+ std::swap(L0, L1);
+ LPred = ICmpInst::getSwappedPredicate(LPred);
+ std::swap(R0, R1);
+ RPred = ICmpInst::getSwappedPredicate(RPred);
+ }
+ if (L0 == R0 &&
+ (LPred == ICmpInst::ICMP_UGE || LPred == ICmpInst::ICMP_ULT) &&
+ (RPred == ICmpInst::ICMP_ULT || RPred == ICmpInst::ICMP_UGE) &&
+ match(L0, m_c_Add(m_Specific(L1), m_Specific(R1))))
+ return LPred == RPred;
+ }
+
if (LPred == RPred)
return isImpliedCondOperands(LPred, L0, L1, R0, R1, DL, Depth);
diff --git a/llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll b/llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll
index 4a6610250df559a..df442dd8f185c81 100644
--- a/llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll
+++ b/llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll
@@ -131,9 +131,7 @@ define i1 @uaddo_and(i64 %a, i64 %b){
; CHECK-LABEL: @uaddo_and(
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[COND_A:%.*]] = icmp uge i64 [[S]], [[A]]
-; CHECK-NEXT: [[COND_B:%.*]] = icmp uge i64 [[S]], [[B]]
-; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
-; CHECK-NEXT: ret i1 [[COND]]
+; CHECK-NEXT: ret i1 [[COND_A]]
;
%s = add i64 %a, %b
%cond_a = icmp uge i64 %s, %a
@@ -146,9 +144,7 @@ define i1 @uaddo_and_commuted1(i64 %a, i64 %b){
; CHECK-LABEL: @uaddo_and_commuted1(
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[COND_A:%.*]] = icmp ule i64 [[A]], [[S]]
-; CHECK-NEXT: [[COND_B:%.*]] = icmp uge i64 [[S]], [[B]]
-; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
-; CHECK-NEXT: ret i1 [[COND]]
+; CHECK-NEXT: ret i1 [[COND_A]]
;
%s = add i64 %a, %b
%cond_a = icmp ule i64 %a, %s
@@ -161,9 +157,7 @@ define i1 @uaddo_and_commuted2(i64 %a, i64 %b){
; CHECK-LABEL: @uaddo_and_commuted2(
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[COND_A:%.*]] = icmp uge i64 [[S]], [[A]]
-; CHECK-NEXT: [[COND_B:%.*]] = icmp ule i64 [[B]], [[S]]
-; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
-; CHECK-NEXT: ret i1 [[COND]]
+; CHECK-NEXT: ret i1 [[COND_A]]
;
%s = add i64 %a, %b
%cond_a = icmp uge i64 %s, %a
@@ -176,9 +170,7 @@ define i1 @uaddo_and_commuted3(i64 %a, i64 %b){
; CHECK-LABEL: @uaddo_and_commuted3(
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[COND_A:%.*]] = icmp ule i64 [[A]], [[S]]
-; CHECK-NEXT: [[COND_B:%.*]] = icmp ule i64 [[B]], [[S]]
-; CHECK-NEXT: [[COND:%.*]] = and i1 [[COND_A]], [[COND_B]]
-; CHECK-NEXT: ret i1 [[COND]]
+; CHECK-NEXT: ret i1 [[COND_A]]
;
%s = add i64 %a, %b
%cond_a = icmp ule i64 %a, %s
@@ -191,9 +183,7 @@ define i1 @uaddo_or(i64 %a, i64 %b){
; CHECK-LABEL: @uaddo_or(
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[COND_A:%.*]] = icmp ult i64 [[S]], [[A]]
-; CHECK-NEXT: [[COND_B:%.*]] = icmp ult i64 [[S]], [[B]]
-; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
-; CHECK-NEXT: ret i1 [[COND]]
+; CHECK-NEXT: ret i1 [[COND_A]]
;
%s = add i64 %a, %b
%cond_a = icmp ult i64 %s, %a
@@ -206,9 +196,7 @@ define i1 @uaddo_or_commuted1(i64 %a, i64 %b){
; CHECK-LABEL: @uaddo_or_commuted1(
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[COND_A:%.*]] = icmp ugt i64 [[A]], [[S]]
-; CHECK-NEXT: [[COND_B:%.*]] = icmp ult i64 [[S]], [[B]]
-; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
-; CHECK-NEXT: ret i1 [[COND]]
+; CHECK-NEXT: ret i1 [[COND_A]]
;
%s = add i64 %a, %b
%cond_a = icmp ugt i64 %a, %s
@@ -221,9 +209,7 @@ define i1 @uaddo_or_commuted2(i64 %a, i64 %b){
; CHECK-LABEL: @uaddo_or_commuted2(
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[COND_A:%.*]] = icmp ult i64 [[S]], [[A]]
-; CHECK-NEXT: [[COND_B:%.*]] = icmp ugt i64 [[B]], [[S]]
-; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
-; CHECK-NEXT: ret i1 [[COND]]
+; CHECK-NEXT: ret i1 [[COND_A]]
;
%s = add i64 %a, %b
%cond_a = icmp ult i64 %s, %a
@@ -236,9 +222,7 @@ define i1 @uaddo_or_commuted3(i64 %a, i64 %b){
; CHECK-LABEL: @uaddo_or_commuted3(
; CHECK-NEXT: [[S:%.*]] = add i64 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[COND_A:%.*]] = icmp ugt i64 [[A]], [[S]]
-; CHECK-NEXT: [[COND_B:%.*]] = icmp ugt i64 [[B]], [[S]]
-; CHECK-NEXT: [[COND:%.*]] = or i1 [[COND_A]], [[COND_B]]
-; CHECK-NEXT: ret i1 [[COND]]
+; CHECK-NEXT: ret i1 [[COND_A]]
;
%s = add i64 %a, %b
%cond_a = icmp ugt i64 %a, %s
|
Ping. |
LGTM. |
This patch simplifies the overflow check of unsigned addition. `a + b <u a` implies `a + b <u b` `a + b >=u a` implies `a + b >=u b` Alive2: https://alive2.llvm.org/ce/z/H8oK8n Fixes llvm#65863.
This patch simplifies the overflow check of unsigned addition.
a + b <u a
impliesa + b <u b
a + b >=u a
impliesa + b >=u b
Alive2: https://alive2.llvm.org/ce/z/H8oK8n
Fixes #65863.