[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:15:45 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