[llvm] [SimplifyLibCalls] Recognize and simplify f[min/max]imumnum (PR #170699)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 5 07:50:45 PST 2025
https://github.com/valadaptive updated https://github.com/llvm/llvm-project/pull/170699
>From ac5e79e15f9a3f82d9b0fb2c86641ec3b0e2e49d Mon Sep 17 00:00:00 2001
From: valadaptive <valadaptive at protonmail.com>
Date: Thu, 4 Dec 2025 10:44:47 -0500
Subject: [PATCH 1/3] [SimplifyLibCalls] Recognize and simplify
f[min/max]imumnum
Unlike fmin and fmax, these are deterministic with regards to signed
zero.
---
.../llvm/Transforms/Utils/SimplifyLibCalls.h | 1 +
.../lib/Transforms/Utils/SimplifyLibCalls.cpp | 31 +++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 4e7c97194cc59..64d2512308935 100644
--- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -205,6 +205,7 @@ class LibCallSimplifier {
Value *replacePowWithSqrt(CallInst *Pow, IRBuilderBase &B);
Value *optimizeExp2(CallInst *CI, IRBuilderBase &B);
Value *optimizeFMinFMax(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeFMinimumnumFMaximumnum(CallInst *CI, IRBuilderBase &B);
Value *optimizeLog(CallInst *CI, IRBuilderBase &B);
Value *optimizeSqrt(CallInst *CI, IRBuilderBase &B);
Value *optimizeFMod(CallInst *CI, IRBuilderBase &B);
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 6a5edd1fa7306..98a4b1b4036ae 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -2543,6 +2543,30 @@ Value *LibCallSimplifier::optimizeFMinFMax(CallInst *CI, IRBuilderBase &B) {
CI->getArgOperand(1), FMF));
}
+Value *LibCallSimplifier::optimizeFMinimumnumFMaximumnum(CallInst *CI,
+ IRBuilderBase &B) {
+ Module *M = CI->getModule();
+
+ // If we can shrink the call to a float function rather than a double
+ // function, do that first.
+ Function *Callee = CI->getCalledFunction();
+ StringRef Name = Callee->getName();
+ if ((Name == "fminimum_num" || Name == "fmaximum_num") &&
+ hasFloatVersion(M, Name))
+ if (Value *Ret = optimizeBinaryDoubleFP(CI, B, TLI))
+ return Ret;
+
+ // The new fminimum_num/fmaximum_num functions, unlike fmin/fmax, *are*
+ // sensitive to the sigh of zero, so we don't change the fast-math flags like
+ // we did for those.
+
+ Intrinsic::ID IID = Callee->getName().starts_with("fminimum_num")
+ ? Intrinsic::minimumnum
+ : Intrinsic::maximumnum;
+ return copyFlags(*CI, B.CreateBinaryIntrinsic(IID, CI->getArgOperand(0),
+ CI->getArgOperand(1), CI));
+}
+
Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) {
Function *LogFn = Log->getCalledFunction();
StringRef LogNm = LogFn->getName();
@@ -4123,6 +4147,13 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
case LibFunc_fmax:
case LibFunc_fmaxl:
return optimizeFMinFMax(CI, Builder);
+ case LibFunc_fminimum_numf:
+ case LibFunc_fminimum_num:
+ case LibFunc_fminimum_numl:
+ case LibFunc_fmaximum_numf:
+ case LibFunc_fmaximum_num:
+ case LibFunc_fmaximum_numl:
+ return optimizeFMinimumnumFMaximumnum(CI, Builder);
case LibFunc_cabs:
case LibFunc_cabsf:
case LibFunc_cabsl:
>From 2057460a40fc5e4209c8447a98cfedb96b328eb8 Mon Sep 17 00:00:00 2001
From: valadaptive <valadaptive at protonmail.com>
Date: Fri, 5 Dec 2025 10:38:07 -0500
Subject: [PATCH 2/3] Update regression tests
---
.../Transforms/InstCombine/float-shrink-compare.ll | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/float-shrink-compare.ll b/llvm/test/Transforms/InstCombine/float-shrink-compare.ll
index 46341cf3d346f..6383feff3a6ee 100644
--- a/llvm/test/Transforms/InstCombine/float-shrink-compare.ll
+++ b/llvm/test/Transforms/InstCombine/float-shrink-compare.ll
@@ -465,11 +465,8 @@ define i1 @test18(float %x, float %y, float %z) {
define i1 @test_fminimum_num(float %x, float %y, float %z) {
; CHECK-LABEL: @test_fminimum_num(
-; CHECK-NEXT: [[TMP1:%.*]] = fpext float [[X:%.*]] to double
-; CHECK-NEXT: [[TMP2:%.*]] = fpext float [[Y:%.*]] to double
-; CHECK-NEXT: [[TMP3:%.*]] = call double @fminimum_num(double [[TMP1]], double [[TMP2]]) #[[ATTR3:[0-9]+]]
-; CHECK-NEXT: [[TMP4:%.*]] = fpext float [[Z:%.*]] to double
-; CHECK-NEXT: [[TMP5:%.*]] = fcmp oeq double [[TMP3]], [[TMP4]]
+; CHECK-NEXT: [[FMINIMUM_NUMF:%.*]] = call float @llvm.minimumnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: [[TMP5:%.*]] = fcmp oeq float [[FMINIMUM_NUMF]], [[Z:%.*]]
; CHECK-NEXT: ret i1 [[TMP5]]
;
%1 = fpext float %x to double
@@ -482,11 +479,8 @@ define i1 @test_fminimum_num(float %x, float %y, float %z) {
define i1 @test_fmaximum_num(float %x, float %y, float %z) {
; CHECK-LABEL: @test_fmaximum_num(
-; CHECK-NEXT: [[TMP1:%.*]] = fpext float [[X:%.*]] to double
-; CHECK-NEXT: [[TMP2:%.*]] = fpext float [[Y:%.*]] to double
-; CHECK-NEXT: [[TMP3:%.*]] = call double @fmaximum_num(double [[TMP1]], double [[TMP2]]) #[[ATTR3]]
-; CHECK-NEXT: [[TMP4:%.*]] = fpext float [[Z:%.*]] to double
-; CHECK-NEXT: [[TMP5:%.*]] = fcmp oeq double [[TMP3]], [[TMP4]]
+; CHECK-NEXT: [[FMAXIMUM_NUMF:%.*]] = call float @llvm.maximumnum.f32(float [[X:%.*]], float [[Y:%.*]])
+; CHECK-NEXT: [[TMP5:%.*]] = fcmp oeq float [[FMAXIMUM_NUMF]], [[Z:%.*]]
; CHECK-NEXT: ret i1 [[TMP5]]
;
%1 = fpext float %x to double
>From fa8b4ff2bb57f44a2128cac52022035bbfabdfdc Mon Sep 17 00:00:00 2001
From: valadaptive <79560998+valadaptive at users.noreply.github.com>
Date: Fri, 5 Dec 2025 10:50:37 -0500
Subject: [PATCH 3/3] Fix typo
Co-authored-by: Yingwei Zheng <dtcxzyw at qq.com>
---
llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 98a4b1b4036ae..c3537f544c432 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -2557,7 +2557,7 @@ Value *LibCallSimplifier::optimizeFMinimumnumFMaximumnum(CallInst *CI,
return Ret;
// The new fminimum_num/fmaximum_num functions, unlike fmin/fmax, *are*
- // sensitive to the sigh of zero, so we don't change the fast-math flags like
+ // sensitive to the sign of zero, so we don't change the fast-math flags like
// we did for those.
Intrinsic::ID IID = Callee->getName().starts_with("fminimum_num")
More information about the llvm-commits
mailing list