[llvm] 80760b0 - [SimplifyLibCalls] Recognize and simplify f[min/max]imumnum (#170699)

via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 5 08:23:46 PST 2025


Author: valadaptive
Date: 2025-12-05T16:23:41Z
New Revision: 80760b0b1d05acd964fa9175b5cdd764a2ee798d

URL: https://github.com/llvm/llvm-project/commit/80760b0b1d05acd964fa9175b5cdd764a2ee798d
DIFF: https://github.com/llvm/llvm-project/commit/80760b0b1d05acd964fa9175b5cdd764a2ee798d.diff

LOG: [SimplifyLibCalls] Recognize and simplify f[min/max]imumnum (#170699)

Unlike fmin and fmax, these are deterministic with regards to signed
zero.

Added: 
    

Modified: 
    llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
    llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
    llvm/test/Transforms/InstCombine/float-shrink-compare.ll

Removed: 
    


################################################################################
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..c3537f544c432 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 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")
+                          ? 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:

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


        


More information about the llvm-commits mailing list