[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:50:43 PST 2025


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

Fixes #166973

>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 74114245766cd66d499c17cc9b566c6e4b7a8ebf 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 | 8 ++++++++
 llvm/test/Transforms/InstCombine/icmp-add.ll            | 3 +--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 33eee8e059486..a707f1d2a056c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -28,6 +28,7 @@
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/IntrinsicsX86.h"
 #include "llvm/IR/PatternMatch.h"
 #include "llvm/Support/KnownBits.h"
 #include "llvm/Transforms/InstCombine/InstCombiner.h"
@@ -3189,6 +3190,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