[llvm] [InstCombine] Use samesign constraints in unsigned known-bits folds (PR #209675)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 16 18:36:11 PDT 2026


https://github.com/imkiva updated https://github.com/llvm/llvm-project/pull/209675

>From 936180c26324dc9079d62b9499dd99857908713d Mon Sep 17 00:00:00 2001
From: imkiva <zengtao at iscas.ac.cn>
Date: Wed, 15 Jul 2026 11:16:13 +0800
Subject: [PATCH 1/2] [InstCombine] Use samesign constraints in unsigned
 known-bits folds

---
 .../InstCombine/InstCombineCompares.cpp       | 16 ++++++
 .../InstCombine/icmp-samesign-known-bits.ll   | 51 +++++++++++++++++++
 2 files changed, 67 insertions(+)
 create mode 100644 llvm/test/Transforms/InstCombine/icmp-samesign-known-bits.ll

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index e186eed92e3e5..5f0b3fb888ecf 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -7100,6 +7100,22 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
       return &I;
   }
 
+  // If an unsigned samesign comparison is not poison, both operands have the
+  // same sign bit. Propagate a known sign bit between the temporary KnownBits
+  // values so the existing range folds can use that constraint.
+  if (I.hasSameSign() && I.isUnsigned()) {
+    auto PropagateSignBit = [](const KnownBits &From, KnownBits &To) {
+      if (To.isNegative() || To.isNonNegative())
+        return;
+      if (From.isNegative())
+        To.makeNegative();
+      else if (From.isNonNegative())
+        To.makeNonNegative();
+    };
+    PropagateSignBit(Op0Known, Op1Known);
+    PropagateSignBit(Op1Known, Op0Known);
+  }
+
   if (!isa<Constant>(Op0) && Op0Known.isConstant())
     return new ICmpInst(
         Pred, ConstantExpr::getIntegerValue(Ty, Op0Known.getConstant()), Op1);
diff --git a/llvm/test/Transforms/InstCombine/icmp-samesign-known-bits.ll b/llvm/test/Transforms/InstCombine/icmp-samesign-known-bits.ll
new file mode 100644
index 0000000000000..798e4066c4976
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/icmp-samesign-known-bits.ll
@@ -0,0 +1,51 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i1 @ugt_smax_minus_one(i8 %x) {
+; CHECK-LABEL: define i1 @ugt_smax_minus_one(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], 127
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp samesign ugt i8 %x, 126
+  ret i1 %cmp
+}
+
+define i1 @ult_smax(i8 %x) {
+; CHECK-LABEL: define i1 @ult_smax(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[X]], 127
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp samesign ult i8 %x, 127
+  ret i1 %cmp
+}
+
+define i1 @ugt_smax(i8 %x) {
+; CHECK-LABEL: define i1 @ugt_smax(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp samesign ugt i8 %x, 127
+  ret i1 %cmp
+}
+
+define i1 @ult_negative_endpoint(i8 %x) {
+; CHECK-LABEL: define i1 @ult_negative_endpoint(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], -128
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp samesign ult i8 %x, -127
+  ret i1 %cmp
+}
+
+define <2 x i1> @ugt_smax_minus_one_vec(<2 x i8> %x) {
+; CHECK-LABEL: define <2 x i1> @ugt_smax_minus_one_vec(
+; CHECK-SAME: <2 x i8> [[X:%.*]]) {
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[X]], splat (i8 127)
+; CHECK-NEXT:    ret <2 x i1> [[CMP]]
+;
+  %cmp = icmp samesign ugt <2 x i8> %x, splat (i8 126)
+  ret <2 x i1> %cmp
+}

>From a5883cd4ad1cc95bc02511a3598dea66a5c57f05 Mon Sep 17 00:00:00 2001
From: imkiva <zengtao at iscas.ac.cn>
Date: Thu, 16 Jul 2026 12:57:11 +0800
Subject: [PATCH 2/2] Update samesign endpoint checks for known-bits fold

---
 .../Transforms/InstCombine/icmp-samesign-canonicalize.ll  | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/icmp-samesign-canonicalize.ll b/llvm/test/Transforms/InstCombine/icmp-samesign-canonicalize.ll
index e0d8073dcbe6d..67b12a1943929 100644
--- a/llvm/test/Transforms/InstCombine/icmp-samesign-canonicalize.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-samesign-canonicalize.ll
@@ -24,8 +24,7 @@ define <2 x i1> @ule_non_endpoint_vec(<2 x i8> %x) {
 define i1 @ule_smax(i8 %x) {
 ; CHECK-LABEL: define i1 @ule_smax(
 ; CHECK-SAME: i8 [[X:%.*]]) {
-; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ule i8 [[X]], 127
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp samesign ule i8 %x, 127
   ret i1 %cmp
@@ -34,7 +33,7 @@ define i1 @ule_smax(i8 %x) {
 define i1 @uge_smax(i8 %x) {
 ; CHECK-LABEL: define i1 @uge_smax(
 ; CHECK-SAME: i8 [[X:%.*]]) {
-; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i8 [[X]], 126
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], 127
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %cmp = icmp samesign uge i8 %x, 127
@@ -44,8 +43,7 @@ define i1 @uge_smax(i8 %x) {
 define i1 @uge_smin(i8 %x) {
 ; CHECK-LABEL: define i1 @uge_smin(
 ; CHECK-SAME: i8 [[X:%.*]]) {
-; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign uge i8 [[X]], -128
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp samesign uge i8 %x, -128
   ret i1 %cmp



More information about the llvm-commits mailing list