diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 31 |
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: |