https://github.com/el-ev updated 
https://github.com/llvm/llvm-project/pull/135785

>From b5cac9cccc305a6af33bc0bc30d01965c5e7e333 Mon Sep 17 00:00:00 2001
From: Iris Shi <0...@owo.li>
Date: Tue, 15 Apr 2025 20:20:45 +0800
Subject: [PATCH] [ConstraintElim] Simplify `usub_with_overflow` when A uge B

---
 .../Scalar/ConstraintElimination.cpp          | 11 ++++
 .../usub-with-overflow.ll                     | 54 +++++++++++--------
 2 files changed, 44 insertions(+), 21 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp 
b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 15aba43721e57..71afd7a2203ef 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1124,6 +1124,7 @@ void State::addInfoFor(BasicBlock &BB) {
     // Enqueue overflow intrinsics for simplification.
     case Intrinsic::sadd_with_overflow:
     case Intrinsic::ssub_with_overflow:
+    case Intrinsic::usub_with_overflow:
     case Intrinsic::ucmp:
     case Intrinsic::scmp:
       WorkList.push_back(
@@ -1765,6 +1766,16 @@ tryToSimplifyOverflowMath(IntrinsicInst *II, 
ConstraintInfo &Info,
     Changed = true;
     break;
   }
+  case Intrinsic::usub_with_overflow: {
+    // usub overflows iff A < B
+    // TODO: If the operation is guaranteed to overflow, we could
+    // also apply some simplifications.
+    if (DoesConditionHold(CmpInst::ICMP_UGE, A, B, Info)) {
+      replaceAddOrSubOverflowUses(II, A, B, ToRemove);
+      Changed = true;
+    }
+    break;
+  }
   }
 
   return Changed;
diff --git a/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll 
b/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll
index 06bfd8269d97d..722116cc6ebd0 100644
--- a/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll
+++ b/llvm/test/Transforms/ConstraintElimination/usub-with-overflow.ll
@@ -9,12 +9,14 @@ define i8 @usub_no_overflow_due_to_cmp_condition(i8 %a, i8 
%b) {
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]]
 ; CHECK-NEXT:    br i1 [[C_1]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
 ; CHECK:       math:
-; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } 
@llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
-; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
+; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[B]], [[A]]
+; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i8, i1 } poison, i8 [[RES]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i8, i1 } [[TMP1]], i1 false, 1
+; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[TMP2]], 1
 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
 ; CHECK:       exit.ok:
-; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
-; CHECK-NEXT:    ret i8 [[RES]]
+; CHECK-NEXT:    [[RES1:%.*]] = extractvalue { i8, i1 } [[TMP2]], 0
+; CHECK-NEXT:    ret i8 [[RES1]]
 ; CHECK:       exit.fail:
 ; CHECK-NEXT:    ret i8 0
 ;
@@ -41,12 +43,14 @@ define i8 @usub_no_overflow_due_to_cmp_condition2(i8 %a, i8 
%b) {
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]]
 ; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
 ; CHECK:       math:
-; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } 
@llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
-; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
+; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[B]], [[A]]
+; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i8, i1 } poison, i8 [[RES]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i8, i1 } [[TMP1]], i1 false, 1
+; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[TMP2]], 1
 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
 ; CHECK:       exit.ok:
-; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
-; CHECK-NEXT:    ret i8 [[RES]]
+; CHECK-NEXT:    [[RES1:%.*]] = extractvalue { i8, i1 } [[TMP2]], 0
+; CHECK-NEXT:    ret i8 [[RES1]]
 ; CHECK:       exit.fail:
 ; CHECK-NEXT:    ret i8 0
 ;
@@ -75,13 +79,15 @@ define i8 
@sub_no_overflow_due_to_cmp_condition_result_used(i8 %a, i8 %b) {
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i8 [[B:%.*]], [[A:%.*]]
 ; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
 ; CHECK:       math:
-; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } 
@llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
+; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[B]], [[A]]
+; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i8, i1 } poison, i8 [[RES]], 0
+; CHECK-NEXT:    [[OP:%.*]] = insertvalue { i8, i1 } [[TMP1]], i1 false, 1
 ; CHECK-NEXT:    call void @use_res({ i8, i1 } [[OP]])
 ; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
 ; CHECK:       exit.ok:
-; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
-; CHECK-NEXT:    ret i8 [[RES]]
+; CHECK-NEXT:    [[RES1:%.*]] = extractvalue { i8, i1 } [[OP]], 0
+; CHECK-NEXT:    ret i8 [[RES1]]
 ; CHECK:       exit.fail:
 ; CHECK-NEXT:    ret i8 0
 ;
@@ -111,12 +117,14 @@ define i8 @usub_no_overflow_due_to_or_conds(i8 %a, i8 %b) 
{
 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_2]], [[C_1]]
 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
 ; CHECK:       math:
-; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } 
@llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
-; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
+; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[B]], [[A]]
+; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i8, i1 } poison, i8 [[RES]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i8, i1 } [[TMP1]], i1 false, 1
+; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[TMP2]], 1
 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
 ; CHECK:       exit.ok:
-; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
-; CHECK-NEXT:    ret i8 [[RES]]
+; CHECK-NEXT:    [[RES1:%.*]] = extractvalue { i8, i1 } [[TMP2]], 0
+; CHECK-NEXT:    ret i8 [[RES1]]
 ; CHECK:       exit.fail:
 ; CHECK-NEXT:    ret i8 0
 ;
@@ -147,8 +155,10 @@ define i8 
@usub_no_overflow_due_to_or_conds_sub_result_not_used(i8 %a, i8 %b) {
 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[C_2]], [[C_1]]
 ; CHECK-NEXT:    br i1 [[OR]], label [[EXIT_FAIL:%.*]], label [[MATH:%.*]]
 ; CHECK:       math:
-; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } 
@llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
-; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
+; CHECK-NEXT:    [[TMP0:%.*]] = sub i8 [[B]], [[A]]
+; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i8, i1 } poison, i8 [[TMP0]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i8, i1 } [[TMP1]], i1 false, 1
+; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[TMP2]], 1
 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
 ; CHECK:       exit.ok:
 ; CHECK-NEXT:    ret i8 20
@@ -181,12 +191,14 @@ define i8 @usub_no_overflow_due_to_and_conds(i8 %a, i8 
%b) {
 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
 ; CHECK-NEXT:    br i1 [[AND]], label [[MATH:%.*]], label [[EXIT_FAIL:%.*]]
 ; CHECK:       math:
-; CHECK-NEXT:    [[OP:%.*]] = tail call { i8, i1 } 
@llvm.usub.with.overflow.i8(i8 [[B]], i8 [[A]])
-; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[OP]], 1
+; CHECK-NEXT:    [[RES:%.*]] = sub i8 [[B]], [[A]]
+; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i8, i1 } poison, i8 [[RES]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { i8, i1 } [[TMP1]], i1 false, 1
+; CHECK-NEXT:    [[STATUS:%.*]] = extractvalue { i8, i1 } [[TMP2]], 1
 ; CHECK-NEXT:    br i1 [[STATUS]], label [[EXIT_FAIL]], label [[EXIT_OK:%.*]]
 ; CHECK:       exit.ok:
-; CHECK-NEXT:    [[RES:%.*]] = extractvalue { i8, i1 } [[OP]], 0
-; CHECK-NEXT:    ret i8 [[RES]]
+; CHECK-NEXT:    [[RES1:%.*]] = extractvalue { i8, i1 } [[TMP2]], 0
+; CHECK-NEXT:    ret i8 [[RES1]]
 ; CHECK:       exit.fail:
 ; CHECK-NEXT:    ret i8 0
 ;

_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to