[llvm] 10b4fa5 - [InstCombine] Don't assert on samesign ule/uge of sext (#216079)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 14 11:16:41 PDT 2026


Author: Arron Zou
Date: 2026-08-15T02:16:36+08:00
New Revision: 10b4fa5b79eb9d27b4928ad82afa3847762bc72f

URL: https://github.com/llvm/llvm-project/commit/10b4fa5b79eb9d27b4928ad82afa3847762bc72f
DIFF: https://github.com/llvm/llvm-project/commit/10b4fa5b79eb9d27b4928ad82afa3847762bc72f.diff

LOG: [InstCombine] Don't assert on samesign ule/uge of sext (#216079)

`foldICmpWithZextOrSext` asserted leftover unsigned icmp of `sext` vs an
unrepresentable constant was `ugt`. `icmp samesign ule/uge` is not
always canonicalized to `ult/ugt`.

Fold these in InstSimplify by converting samesign unsigned predicates to
signed ones with `getPreferredSignedPredicate()`.

Fixes #216058

AI tool usage: an AI coding assistant helped write the tests and iterate
on the InstSimplify fold.

Added: 
    llvm/test/Transforms/InstCombine/pr216058.ll
    llvm/test/Transforms/InstSimplify/pr216058.ll

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 10b159192c4be..c76f4d2e9f327 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4087,7 +4087,7 @@ static Value *simplifyICmpInst(CmpPredicate Pred, Value *LHS, Value *RHS,
         // Otherwise the upper bits of LHS are all equal, while RHS has varying
         // bits there.  Use this to work out the result of the comparison.
         if (AnyEq->isNullValue()) {
-          switch (Pred) {
+          switch (Pred.getPreferredSignedPredicate()) {
           default:
             llvm_unreachable("Unknown ICmp predicate!");
           case ICmpInst::ICMP_EQ:

diff  --git a/llvm/test/Transforms/InstCombine/pr216058.ll b/llvm/test/Transforms/InstCombine/pr216058.ll
new file mode 100644
index 0000000000000..4d9d958b10fe6
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/pr216058.ll
@@ -0,0 +1,15 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+; icmp samesign ule of a sext vs a dest-width SMAX is not canonicalized to ugt,
+; which used to assert in foldICmpWithZextOrSext.
+; https://github.com/llvm/llvm-project/issues/216058
+
+define i1 @samesign_ule_sext_i16_smax(i16 %x) {
+; CHECK-LABEL: @samesign_ule_sext_i16_smax(
+; CHECK-NEXT:    ret i1 true
+;
+  %e = sext i16 %x to i32
+  %c = icmp samesign ule i32 %e, 2147483647
+  ret i1 %c
+}

diff  --git a/llvm/test/Transforms/InstSimplify/pr216058.ll b/llvm/test/Transforms/InstSimplify/pr216058.ll
new file mode 100644
index 0000000000000..72d5a4ed6bda8
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/pr216058.ll
@@ -0,0 +1,72 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
+
+; Fold icmp samesign of a sext vs a constant not representable in the source
+; type. Poison from a sign mismatch may be refined to the matching-sign result.
+; https://github.com/llvm/llvm-project/issues/216058
+
+define i1 @samesign_ule_sext_i16_smax(i16 %x) {
+; CHECK-LABEL: @samesign_ule_sext_i16_smax(
+; CHECK-NEXT:    ret i1 true
+;
+  %e = sext i16 %x to i32
+  %c = icmp samesign ule i32 %e, 2147483647
+  ret i1 %c
+}
+
+define i1 @samesign_ult_sext_i16_smax(i16 %x) {
+; CHECK-LABEL: @samesign_ult_sext_i16_smax(
+; CHECK-NEXT:    ret i1 true
+;
+  %e = sext i16 %x to i32
+  %c = icmp samesign ult i32 %e, 2147483647
+  ret i1 %c
+}
+
+define i1 @samesign_uge_sext_i16_smin(i16 %x) {
+; CHECK-LABEL: @samesign_uge_sext_i16_smin(
+; CHECK-NEXT:    ret i1 true
+;
+  %e = sext i16 %x to i32
+  %c = icmp samesign uge i32 %e, -2147483648
+  ret i1 %c
+}
+
+define i1 @samesign_ugt_sext_i16_smin(i16 %x) {
+; CHECK-LABEL: @samesign_ugt_sext_i16_smin(
+; CHECK-NEXT:    ret i1 true
+;
+  %e = sext i16 %x to i32
+  %c = icmp samesign ugt i32 %e, -2147483648
+  ret i1 %c
+}
+
+define i1 @samesign_uge_sext_i16_smax(i16 %x) {
+; CHECK-LABEL: @samesign_uge_sext_i16_smax(
+; CHECK-NEXT:    ret i1 false
+;
+  %e = sext i16 %x to i32
+  %c = icmp samesign uge i32 %e, 2147483647
+  ret i1 %c
+}
+
+define i1 @samesign_ule_sext_i16_smin(i16 %x) {
+; CHECK-LABEL: @samesign_ule_sext_i16_smin(
+; CHECK-NEXT:    ret i1 false
+;
+  %e = sext i16 %x to i32
+  %c = icmp samesign ule i32 %e, -2147483648
+  ret i1 %c
+}
+
+; Without samesign the unsigned compare still depends on the sign of X.
+define i1 @ule_sext_i16_smax(i16 %x) {
+; CHECK-LABEL: @ule_sext_i16_smax(
+; CHECK-NEXT:    [[E:%.*]] = sext i16 [[X:%.*]] to i32
+; CHECK-NEXT:    [[C:%.*]] = icmp ule i32 [[E]], 2147483647
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %e = sext i16 %x to i32
+  %c = icmp ule i32 %e, 2147483647
+  ret i1 %c
+}


        


More information about the llvm-commits mailing list