[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