[llvm] [InstCombine] Fold smin(-a, x - a) + a to smin(x, 0) (PR #167109)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 8 00:16:08 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Aneesh Kadiyala (ARandomDev99)
<details>
<summary>Changes</summary>
This PR adds support for folding `smin(-a, x - a) + a` and its commuted variants to `smin(x, 0)`.
Fixes #<!-- -->167003
---
Full diff: https://github.com/llvm/llvm-project/pull/167109.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp (+14)
- (modified) llvm/test/Transforms/InstCombine/add-min-max.ll (+15)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/167109
More information about the llvm-commits
mailing list