[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