aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp31
1 files changed, 31 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 5f902ee..e06ebb6 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -3126,6 +3126,33 @@ Value *LibCallSimplifier::optimizeRemquo(CallInst *CI, IRBuilderBase &B) {
return ConstantFP::get(CI->getType(), Rem);
}
+/// Constant folds fdim
+Value *LibCallSimplifier::optimizeFdim(CallInst *CI, IRBuilderBase &B) {
+ // Cannot perform the fold unless the call has attribute memory(none)
+ if (!CI->doesNotAccessMemory())
+ return nullptr;
+
+ // TODO : Handle undef values
+ // Propagate poison if any
+ if (isa<PoisonValue>(CI->getArgOperand(0)))
+ return CI->getArgOperand(0);
+ if (isa<PoisonValue>(CI->getArgOperand(1)))
+ return CI->getArgOperand(1);
+
+ const APFloat *X, *Y;
+ // Check if both values are constants
+ if (!match(CI->getArgOperand(0), m_APFloat(X)) ||
+ !match(CI->getArgOperand(1), m_APFloat(Y)))
+ return nullptr;
+
+ APFloat Difference = *X;
+ Difference.subtract(*Y, RoundingMode::NearestTiesToEven);
+
+ APFloat MaxVal =
+ maximum(Difference, APFloat::getZero(CI->getType()->getFltSemantics()));
+ return ConstantFP::get(CI->getType(), MaxVal);
+}
+
//===----------------------------------------------------------------------===//
// Integer Library Call Optimizations
//===----------------------------------------------------------------------===//
@@ -4059,6 +4086,10 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
if (hasFloatVersion(M, CI->getCalledFunction()->getName()))
return optimizeBinaryDoubleFP(CI, Builder, TLI);
return nullptr;
+ case LibFunc_fdim:
+ case LibFunc_fdimf:
+ case LibFunc_fdiml:
+ return optimizeFdim(CI, Builder);
case LibFunc_fminf:
case LibFunc_fmin:
case LibFunc_fminl: