Skip to content

[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

Merged
merged 3 commits into from
Sep 28, 2023
Merged

Conversation

dtcxzyw
Copy link
Member

@dtcxzyw dtcxzyw commented Sep 10, 2023

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 #65863.

@llvmbot
Copy link
Member

llvmbot commented Sep 10, 2023

@llvm/pr-subscribers-llvm-analysis

Changes

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 #65863.

--
Full diff: https://github.com/llvm/llvm-project/pull/65910.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/ValueTracking.cpp (+20)
  • (modified) llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll (+104)
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 

@RKSimon
Copy link
Collaborator

RKSimon commented Sep 13, 2023

Please can you pre-commit the tests to show the IR diff?

@llvmbot
Copy link
Member

llvmbot commented Sep 16, 2023

@llvm/pr-subscribers-llvm-transforms

Changes

This patch simplifies the overflow check of unsigned addition.

a + b &lt;u a implies a + b &lt;u b
a + b &gt;=u a implies a + b &gt;=u b

Alive2: https://alive2.llvm.org/ce/z/H8oK8n
Fixes #65863.


Full diff: https://github.com/llvm/llvm-project/pull/65910.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/ValueTracking.cpp (+23)
  • (modified) llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll (+8-24)
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

@dtcxzyw
Copy link
Member Author

dtcxzyw commented Sep 19, 2023

Ping.

@dtcxzyw dtcxzyw requested a review from goldsteinn September 24, 2023 09:09
@goldsteinn
Copy link
Contributor

LGTM.

@dtcxzyw dtcxzyw merged commit 9f2fc88 into llvm:main Sep 28, 2023
@dtcxzyw dtcxzyw deleted the uaddo-check-imply branch September 28, 2023 17:59
legrosbuffle pushed a commit to legrosbuffle/llvm-project that referenced this pull request Sep 29, 2023
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Simplify add-with-overflow pattern (uaddo)
4 participants