Skip to content

Commit 80760b0

Browse files
authored
[SimplifyLibCalls] Recognize and simplify f[min/max]imumnum (#170699)
Unlike fmin and fmax, these are deterministic with regards to signed zero.
1 parent 38e5878 commit 80760b0

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ class LibCallSimplifier {
205205
Value *replacePowWithSqrt(CallInst *Pow, IRBuilderBase &B);
206206
Value *optimizeExp2(CallInst *CI, IRBuilderBase &B);
207207
Value *optimizeFMinFMax(CallInst *CI, IRBuilderBase &B);
208+
Value *optimizeFMinimumnumFMaximumnum(CallInst *CI, IRBuilderBase &B);
208209
Value *optimizeLog(CallInst *CI, IRBuilderBase &B);
209210
Value *optimizeSqrt(CallInst *CI, IRBuilderBase &B);
210211
Value *optimizeFMod(CallInst *CI, IRBuilderBase &B);

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2543,6 +2543,30 @@ Value *LibCallSimplifier::optimizeFMinFMax(CallInst *CI, IRBuilderBase &B) {
25432543
CI->getArgOperand(1), FMF));
25442544
}
25452545

2546+
Value *LibCallSimplifier::optimizeFMinimumnumFMaximumnum(CallInst *CI,
2547+
IRBuilderBase &B) {
2548+
Module *M = CI->getModule();
2549+
2550+
// If we can shrink the call to a float function rather than a double
2551+
// function, do that first.
2552+
Function *Callee = CI->getCalledFunction();
2553+
StringRef Name = Callee->getName();
2554+
if ((Name == "fminimum_num" || Name == "fmaximum_num") &&
2555+
hasFloatVersion(M, Name))
2556+
if (Value *Ret = optimizeBinaryDoubleFP(CI, B, TLI))
2557+
return Ret;
2558+
2559+
// The new fminimum_num/fmaximum_num functions, unlike fmin/fmax, *are*
2560+
// sensitive to the sign of zero, so we don't change the fast-math flags like
2561+
// we did for those.
2562+
2563+
Intrinsic::ID IID = Callee->getName().starts_with("fminimum_num")
2564+
? Intrinsic::minimumnum
2565+
: Intrinsic::maximumnum;
2566+
return copyFlags(*CI, B.CreateBinaryIntrinsic(IID, CI->getArgOperand(0),
2567+
CI->getArgOperand(1), CI));
2568+
}
2569+
25462570
Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) {
25472571
Function *LogFn = Log->getCalledFunction();
25482572
StringRef LogNm = LogFn->getName();
@@ -4123,6 +4147,13 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
41234147
case LibFunc_fmax:
41244148
case LibFunc_fmaxl:
41254149
return optimizeFMinFMax(CI, Builder);
4150+
case LibFunc_fminimum_numf:
4151+
case LibFunc_fminimum_num:
4152+
case LibFunc_fminimum_numl:
4153+
case LibFunc_fmaximum_numf:
4154+
case LibFunc_fmaximum_num:
4155+
case LibFunc_fmaximum_numl:
4156+
return optimizeFMinimumnumFMaximumnum(CI, Builder);
41264157
case LibFunc_cabs:
41274158
case LibFunc_cabsf:
41284159
case LibFunc_cabsl:

llvm/test/Transforms/InstCombine/float-shrink-compare.ll

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -465,11 +465,8 @@ define i1 @test18(float %x, float %y, float %z) {
465465

466466
define i1 @test_fminimum_num(float %x, float %y, float %z) {
467467
; CHECK-LABEL: @test_fminimum_num(
468-
; CHECK-NEXT: [[TMP1:%.*]] = fpext float [[X:%.*]] to double
469-
; CHECK-NEXT: [[TMP2:%.*]] = fpext float [[Y:%.*]] to double
470-
; CHECK-NEXT: [[TMP3:%.*]] = call double @fminimum_num(double [[TMP1]], double [[TMP2]]) #[[ATTR3:[0-9]+]]
471-
; CHECK-NEXT: [[TMP4:%.*]] = fpext float [[Z:%.*]] to double
472-
; CHECK-NEXT: [[TMP5:%.*]] = fcmp oeq double [[TMP3]], [[TMP4]]
468+
; CHECK-NEXT: [[FMINIMUM_NUMF:%.*]] = call float @llvm.minimumnum.f32(float [[X:%.*]], float [[Y:%.*]])
469+
; CHECK-NEXT: [[TMP5:%.*]] = fcmp oeq float [[FMINIMUM_NUMF]], [[Z:%.*]]
473470
; CHECK-NEXT: ret i1 [[TMP5]]
474471
;
475472
%1 = fpext float %x to double
@@ -482,11 +479,8 @@ define i1 @test_fminimum_num(float %x, float %y, float %z) {
482479

483480
define i1 @test_fmaximum_num(float %x, float %y, float %z) {
484481
; CHECK-LABEL: @test_fmaximum_num(
485-
; CHECK-NEXT: [[TMP1:%.*]] = fpext float [[X:%.*]] to double
486-
; CHECK-NEXT: [[TMP2:%.*]] = fpext float [[Y:%.*]] to double
487-
; CHECK-NEXT: [[TMP3:%.*]] = call double @fmaximum_num(double [[TMP1]], double [[TMP2]]) #[[ATTR3]]
488-
; CHECK-NEXT: [[TMP4:%.*]] = fpext float [[Z:%.*]] to double
489-
; CHECK-NEXT: [[TMP5:%.*]] = fcmp oeq double [[TMP3]], [[TMP4]]
482+
; CHECK-NEXT: [[FMAXIMUM_NUMF:%.*]] = call float @llvm.maximumnum.f32(float [[X:%.*]], float [[Y:%.*]])
483+
; CHECK-NEXT: [[TMP5:%.*]] = fcmp oeq float [[FMAXIMUM_NUMF]], [[Z:%.*]]
490484
; CHECK-NEXT: ret i1 [[TMP5]]
491485
;
492486
%1 = fpext float %x to double

0 commit comments

Comments
 (0)