[llvm] [InstCombine] Fold npos select around umin (PR #202748)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 11:49:50 PDT 2026
https://github.com/robertvirany updated https://github.com/llvm/llvm-project/pull/202748
>From 6e3a0c266fcaa68987e7087d2856cb7eaac0d7de Mon Sep 17 00:00:00 2001
From: Robert Virany <robertvirany at gmail.com>
Date: Tue, 9 Jun 2026 15:28:14 -0400
Subject: [PATCH] [InstCombine] Fold npos select around umin
---
llvm/lib/Analysis/InstructionSimplify.cpp | 23 +++++++
llvm/test/Transforms/InstCombine/umin-icmp.ll | 61 +++++++++++++++++++
2 files changed, 84 insertions(+)
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 81debece796b1..12db58be4d224 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4526,6 +4526,29 @@ static Value *simplifyWithOpsReplaced(Value *V,
return ConstantInt::get(I->getType(), 0);
}
+
+ // umin(-1, x) -> x
+ // umin(x, -1) -> x
+ if (auto *MMI = dyn_cast<MinMaxIntrinsic>(II)) {
+ if (MMI->getIntrinsicID() == Intrinsic::umin) {
+ Value *Result = nullptr;
+ if (match(NewOps[0], m_AllOnes()))
+ Result = NewOps[1];
+ else if (match(NewOps[1], m_AllOnes()))
+ Result = NewOps[0];
+
+ if (Result) {
+ if (II->hasPoisonGeneratingAnnotations()) {
+ if (!DropFlags)
+ return nullptr;
+
+ DropFlags->push_back(II);
+ }
+
+ return Result;
+ }
+ }
+ }
}
if (isa<GetElementPtrInst>(I)) {
diff --git a/llvm/test/Transforms/InstCombine/umin-icmp.ll b/llvm/test/Transforms/InstCombine/umin-icmp.ll
index cb23b2f00d292..7a1591e098b2b 100644
--- a/llvm/test/Transforms/InstCombine/umin-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/umin-icmp.ll
@@ -805,3 +805,64 @@ end:
}
declare i32 @llvm.umin.i32(i32, i32)
+declare i64 @llvm.umin.i64(i64, i64)
+declare i64 @llvm.umax.i64(i64, i64)
+
+define i64 @select_npos_umin(i64 %pos, i64 %len) {
+; CHECK-LABEL: @select_npos_umin(
+; CHECK-NEXT: [[CLAMPED:%.*]] = call i64 @llvm.umin.i64(i64 [[POS:%.*]], i64 [[LEN:%.*]])
+; CHECK-NEXT: ret i64 [[CLAMPED]]
+;
+ %is_npos = icmp eq i64 %pos, -1
+ %clamped = call i64 @llvm.umin.i64(i64 %pos, i64 %len)
+ %out = select i1 %is_npos, i64 %len, i64 %clamped
+ ret i64 %out
+}
+
+define i64 @select_not_npos_umin(i64 %pos, i64 %len) {
+; CHECK-LABEL: @select_not_npos_umin(
+; CHECK-NEXT: [[CLAMPED:%.*]] = call i64 @llvm.umin.i64(i64 [[POS:%.*]], i64 [[LEN:%.*]])
+; CHECK-NEXT: ret i64 [[CLAMPED]]
+;
+ %is_not_npos = icmp ne i64 %pos, -1
+ %clamped = call i64 @llvm.umin.i64(i64 %pos, i64 %len)
+ %out = select i1 %is_not_npos, i64 %clamped, i64 %len
+ ret i64 %out
+}
+
+define i64 @select_npos_umin_commuted(i64 %pos, i64 %len) {
+; CHECK-LABEL: @select_npos_umin_commuted(
+; CHECK-NEXT: [[CLAMPED:%.*]] = call i64 @llvm.umin.i64(i64 [[LEN:%.*]], i64 [[POS:%.*]])
+; CHECK-NEXT: ret i64 [[CLAMPED]]
+;
+ %is_npos = icmp eq i64 %pos, -1
+ %clamped = call i64 @llvm.umin.i64(i64 %len, i64 %pos)
+ %out = select i1 %is_npos, i64 %len, i64 %clamped
+ ret i64 %out
+}
+
+define i64 @select_npos_umax_negative(i64 %pos, i64 %len) {
+; CHECK-LABEL: @select_npos_umax_negative(
+; CHECK-NEXT: [[IS_NPOS:%.*]] = icmp eq i64 [[POS:%.*]], -1
+; CHECK-NEXT: [[CLAMPED:%.*]] = call i64 @llvm.umax.i64(i64 [[POS]], i64 [[LEN:%.*]])
+; CHECK-NEXT: [[OUT:%.*]] = select i1 [[IS_NPOS]], i64 [[LEN]], i64 [[CLAMPED]]
+; CHECK-NEXT: ret i64 [[OUT]]
+;
+ %is_npos = icmp eq i64 %pos, -1
+ %clamped = call i64 @llvm.umax.i64(i64 %pos, i64 %len)
+ %out = select i1 %is_npos, i64 %len, i64 %clamped
+ ret i64 %out
+}
+
+define i64 @select_npos_wrong_bound_negative(i64 %pos, i64 %len, i64 %other) {
+; CHECK-LABEL: @select_npos_wrong_bound_negative(
+; CHECK-NEXT: [[IS_NPOS:%.*]] = icmp eq i64 [[POS:%.*]], -1
+; CHECK-NEXT: [[CLAMPED:%.*]] = call i64 @llvm.umin.i64(i64 [[POS]], i64 [[LEN:%.*]])
+; CHECK-NEXT: [[OUT:%.*]] = select i1 [[IS_NPOS]], i64 [[OTHER:%.*]], i64 [[CLAMPED]]
+; CHECK-NEXT: ret i64 [[OUT]]
+;
+ %is_npos = icmp eq i64 %pos, -1
+ %clamped = call i64 @llvm.umin.i64(i64 %pos, i64 %len)
+ %out = select i1 %is_npos, i64 %other, i64 %clamped
+ ret i64 %out
+}
More information about the llvm-commits
mailing list