[llvm] [InstCombine] Fold smin(-a, x - a) + a to smin(x, 0) (PR #167109)
Aneesh Kadiyala via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 8 00:16:34 PST 2025
https://github.com/ARandomDev99 updated https://github.com/llvm/llvm-project/pull/167109
>From 696bfe2f289ddb4ab850a33b8839209302cb3f35 Mon Sep 17 00:00:00 2001
From: Aneesh K <notspaceboy at pm.me>
Date: Sat, 8 Nov 2025 12:27:52 +0530
Subject: [PATCH] [InstCombine] Fold smin(-a, x - a) + a to smin(x, 0) This
adds support for folding `smin(-a, x - a) + a` and its commuted variants to
`smin(x, 0)`. This does give different in cases where `-a` or `x - a`
overflow.
Co-authored-by: Jami Rithvik <rithvikjami at gmail.com>
---
.../Transforms/InstCombine/InstCombineAddSub.cpp | 14 ++++++++++++++
llvm/test/Transforms/InstCombine/add-min-max.ll | 15 +++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 9bee523c7b7e5..a6e9639c5f5a0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2037,6 +2037,20 @@ Instruction *InstCombinerImpl::visitFAdd(BinaryOperator &I) {
return BinaryOperator::CreateFSubFMF(Z, XY, &I);
}
+ // smin(-a, x - a) + a --> smin(x, 0) [2 commuted variants]
+ // smin(x - a, -a) + a --> smin(x, 0) [2 commuted variants]
+ if (match(&I,
+ m_c_FAdd(m_SMin(m_FNeg(m_Value(A)), m_FSub(m_Value(X), m_Value(A))),
+ m_Value(A))) ||
+ match(&I,
+ m_c_FAdd(m_SMin(m_FSub(m_Value(X), m_Value(A)), m_FNeg(m_Value(A))),
+ m_Value(A)))) {
+ Constant *Zero = Constant::getNullValue(I.getType());
+ return replaceInstUsesWith(
+ I,
+ Builder.CreateIntrinsic(Intrinsic::smin, {I.getType()}, {X, Zero}, &I));
+ }
+
// Check for (fadd double (sitofp x), y), see if we can merge this into an
// integer add followed by a promotion.
if (Instruction *R = foldFBinOpOfIntCasts(I))
diff --git a/llvm/test/Transforms/InstCombine/add-min-max.ll b/llvm/test/Transforms/InstCombine/add-min-max.ll
index 2117a55e2a490..cbf960d32cb90 100644
--- a/llvm/test/Transforms/InstCombine/add-min-max.ll
+++ b/llvm/test/Transforms/InstCombine/add-min-max.ll
@@ -83,3 +83,18 @@ entry:
%res = add nuw nsw i32 %min, %max
ret i32 %res
}
+
+
+define i32 @sadd_min_neg(i32 %x, i32 %a) {
+; CHECK-LABEL: @sadd_min_neg(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i64 5)
+; CHECK-NEXT: ret i32 [[RES]]
+;
+entry:
+ %neg_a = sub nsw i32 0, %a
+ %x_minus_a = sub nsw i32 %x, %a
+ %smin = call i32 @llvm.smin.i32(i32 %neg_a, i32 %x_minus_a)
+ %res = add nsw i32 %smin, %a
+ ret i32 %res
+}
\ No newline at end of file
More information about the llvm-commits
mailing list