Skip to content

Commit 53989aa

Browse files
committed
[SimplifyLibCalls] Constant fold fdim
Signed-off-by: Kushal Pal <[email protected]>
1 parent 46f031f commit 53989aa

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class LibCallSimplifier {
211211
Value *optimizeTrigInversionPairs(CallInst *CI, IRBuilderBase &B);
212212
Value *optimizeSymmetric(CallInst *CI, LibFunc Func, IRBuilderBase &B);
213213
Value *optimizeRemquo(CallInst *CI, IRBuilderBase &B);
214+
Value *optimizeFdim(CallInst *CI, IRBuilderBase &B);
214215
// Wrapper for all floating point library call optimizations
215216
Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func,
216217
IRBuilderBase &B);

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3080,6 +3080,41 @@ Value *LibCallSimplifier::optimizeRemquo(CallInst *CI, IRBuilderBase &B) {
30803080
return ConstantFP::get(CI->getType(), Rem);
30813081
}
30823082

3083+
/// Constant folds fdim
3084+
Value *LibCallSimplifier::optimizeFdim(CallInst *CI, IRBuilderBase &B) {
3085+
const APFloat *X, *Y;
3086+
// Check if both values are constants
3087+
if (!match(CI->getArgOperand(0), m_APFloat(X)) ||
3088+
!match(CI->getArgOperand(1), m_APFloat(Y)))
3089+
return nullptr;
3090+
// If either argument is NaN, NaN is returned
3091+
if (X->isNaN() || Y->isNaN())
3092+
return ConstantFP::getQNaN(CI->getType());
3093+
3094+
// If the difference if negative, return +0.0
3095+
if (*X <= *Y)
3096+
return ConstantFP::get(CI->getType(), 0.0);
3097+
3098+
APFloat ReturnVal = *X;
3099+
APFloat::opStatus Status =
3100+
ReturnVal.subtract(*Y, RoundingMode::NearestTiesToEven);
3101+
switch (Status) {
3102+
case APFloat::opStatus::opOK:
3103+
break;
3104+
case APFloat::opStatus::opOverflow:
3105+
return ConstantFP::get(
3106+
CI->getType(),
3107+
APFloat::getLargest(X->getSemantics(), /*Negative=*/false));
3108+
case APFloat::opStatus::opUnderflow:
3109+
return ConstantFP::get(
3110+
CI->getType(),
3111+
APFloat::getLargest(X->getSemantics(), /*Negative=*/true));
3112+
default:
3113+
return nullptr;
3114+
}
3115+
return ConstantFP::get(CI->getType(), ReturnVal);
3116+
}
3117+
30833118
//===----------------------------------------------------------------------===//
30843119
// Integer Library Call Optimizations
30853120
//===----------------------------------------------------------------------===//
@@ -4009,6 +4044,10 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
40094044
if (hasFloatVersion(M, CI->getCalledFunction()->getName()))
40104045
return optimizeBinaryDoubleFP(CI, Builder, TLI);
40114046
return nullptr;
4047+
case LibFunc_fdim:
4048+
case LibFunc_fdimf:
4049+
case LibFunc_fdiml:
4050+
return optimizeFdim(CI, Builder);
40124051
case LibFunc_fminf:
40134052
case LibFunc_fmin:
40144053
case LibFunc_fminl:
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
4+
define double @fdim_double() {
5+
; CHECK-LABEL: define double @fdim_double() {
6+
; CHECK-NEXT: ret double 2.500000e+00
7+
;
8+
%dim = call double @fdim (double 10.5, double 8.0)
9+
ret double %dim
10+
}
11+
12+
define double @fdim_double1() {
13+
; CHECK-LABEL: define double @fdim_double1() {
14+
; CHECK-NEXT: ret double 0.000000e+00
15+
;
16+
%dim = call double @fdim (double 7.0, double 8.0)
17+
ret double %dim
18+
}
19+
20+
define float @fdim_float() {
21+
; CHECK-LABEL: define float @fdim_float() {
22+
; CHECK-NEXT: ret float 2.500000e+00
23+
;
24+
%dim = call float @fdimf (float 10.5, float 8.0)
25+
ret float %dim
26+
}
27+
28+
define float @fdim_float1() {
29+
; CHECK-LABEL: define float @fdim_float1() {
30+
; CHECK-NEXT: ret float 0.000000e+00
31+
;
32+
%dim = call float @fdimf (float 7.0, float 8.0)
33+
ret float %dim
34+
}
35+
36+
declare double @fdim(double, double)
37+
declare float @fdimf(float, float)

0 commit comments

Comments
 (0)