[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