[llvm] Fold `icmp samesign u{gt/ge/lt/le} (X +nsw C2), C` -> `icmp s{gt/ge/lt/le} X, (C - C2)` (PR #169960)

Tirthankar Mazumder via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 28 12:53:04 PST 2025


https://github.com/wermos updated https://github.com/llvm/llvm-project/pull/169960

>From c0f9b14f4ff739fcee6bb4057e4335522ca04493 Mon Sep 17 00:00:00 2001
From: wermos <63574588+wermos at users.noreply.github.com>
Date: Sat, 29 Nov 2025 01:55:58 +0530
Subject: [PATCH 1/2] Pre-commit test

---
 llvm/test/Transforms/InstCombine/icmp-add.ll | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll
index 8449c7c5ea935..b2e6c876be66c 100644
--- a/llvm/test/Transforms/InstCombine/icmp-add.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -3440,3 +3440,16 @@ define i1 @val_is_aligend_pred_mismatch(i32 %num) {
   %_0 = icmp sge i32 %num.masked, %num
   ret i1 %_0
 }
+
+define i1 @icmp_samesign_with_nsw_add(i32 %arg0) {
+; CHECK-LABEL: @icmp_samesign_with_nsw_add(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[ARG0:%.*]], -26
+; CHECK-NEXT:    [[V1:%.*]] = icmp ult i32 [[TMP0]], -8
+; CHECK-NEXT:    ret i1 [[V1]]
+;
+entry:
+  %v0 = add nsw i32 %arg0, -18
+  %v1 = icmp samesign ugt i32 %v0, 7
+  ret i1 %v1
+}

>From 46fdc59748646dcbee6eff708081c0272522a295 Mon Sep 17 00:00:00 2001
From: wermos <63574588+wermos at users.noreply.github.com>
Date: Sat, 29 Nov 2025 02:02:43 +0530
Subject: [PATCH 2/2] Fold `icmp samesign u{gt/ge/lt/le} (add nsw X, C2), C` ->
 `icmp s{gt/ge/lt/le} X, (C - C2)`

---
 llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 7 +++++++
 llvm/test/Transforms/InstCombine/icmp-add.ll            | 3 +--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 33eee8e059486..21fdc93494a98 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3189,6 +3189,13 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
     return new ICmpInst(ICmpInst::getSignedPredicate(Pred), X,
                         ConstantInt::get(Ty, C - *C2));
 
+  // Fold icmp samesign u{gt/ge/lt/le} (add nsw X, C2), C
+  //      -> icmp s{gt/ge/lt/le} X, (C - C2)
+  CmpPredicate CP(Pred, Cmp.hasSameSign());
+  if (CP.hasSameSign() && Add->hasNoSignedWrap())
+    return new ICmpInst(CP.getPreferredSignedPredicate(), X,
+                        ConstantInt::get(Ty, C - *C2));
+
   auto CR = ConstantRange::makeExactICmpRegion(Pred, C).subtract(*C2);
   const APInt &Upper = CR.getUpper();
   const APInt &Lower = CR.getLower();
diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll
index b2e6c876be66c..7c30337126b2b 100644
--- a/llvm/test/Transforms/InstCombine/icmp-add.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-add.ll
@@ -3444,8 +3444,7 @@ define i1 @val_is_aligend_pred_mismatch(i32 %num) {
 define i1 @icmp_samesign_with_nsw_add(i32 %arg0) {
 ; CHECK-LABEL: @icmp_samesign_with_nsw_add(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[ARG0:%.*]], -26
-; CHECK-NEXT:    [[V1:%.*]] = icmp ult i32 [[TMP0]], -8
+; CHECK-NEXT:    [[V1:%.*]] = icmp sgt i32 [[ARG0:%.*]], 25
 ; CHECK-NEXT:    ret i1 [[V1]]
 ;
 entry:



More information about the llvm-commits mailing list