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

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 15 22:15:32 PDT 2026


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

>From 40045f98945dfb5c54a38f612caa2f71c8cd44e0 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] [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 42c2983034e22..fc0704140dbce 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -6991,6 +6991,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
+}



More information about the llvm-commits mailing list