diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2017-01-23 23:55:08 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2017-01-23 23:55:08 +0000 |
commit | 954a624fb987f97e74bdf7b01685d4ec2a4dc861 (patch) | |
tree | e03549055cc52b4f71844c21083df43e13609977 /llvm/lib/Transforms | |
parent | 461aa57ad34d6155be8d401283619723bf623603 (diff) | |
download | bcm5719-llvm-954a624fb987f97e74bdf7b01685d4ec2a4dc861.tar.gz bcm5719-llvm-954a624fb987f97e74bdf7b01685d4ec2a4dc861.zip |
SimplifyLibCalls: Replace more unary libcalls with intrinsics
llvm-svn: 292855
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 49 |
3 files changed, 37 insertions, 30 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index e6e126bf784..07ee3c032c2 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1680,11 +1680,18 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { return SelectInst::Create(Cond, Call0, Call1); } + LLVM_FALLTHROUGH; + } + case Intrinsic::ceil: + case Intrinsic::floor: + case Intrinsic::round: + case Intrinsic::nearbyint: + case Intrinsic::trunc: { Value *ExtSrc; if (match(II->getArgOperand(0), m_FPExt(m_Value(ExtSrc))) && II->getArgOperand(0)->hasOneUse()) { // fabs (fpext x) -> fpext (fabs x) - Value *F = Intrinsic::getDeclaration(II->getModule(), Intrinsic::fabs, + Value *F = Intrinsic::getDeclaration(II->getModule(), II->getIntrinsicID(), { ExtSrc->getType() }); CallInst *NewFabs = Builder->CreateCall(F, ExtSrc); NewFabs->copyFastMathFlags(II); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 5ba6fd6fe32..178920678d8 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1393,7 +1393,14 @@ Instruction *InstCombiner::visitFPTrunc(FPTruncInst &CI) { if (II) { switch (II->getIntrinsicID()) { default: break; - case Intrinsic::fabs: { + case Intrinsic::fabs: + case Intrinsic::ceil: + case Intrinsic::floor: + case Intrinsic::rint: + case Intrinsic::round: + case Intrinsic::nearbyint: + case Intrinsic::trunc: { + // Do unary FP operation on smaller type. // (fptrunc (fabs x)) -> (fabs (fptrunc x)) Value *InnerTrunc = Builder->CreateFPTrunc(II->getArgOperand(0), CI.getType()); diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 3ab933d9320..4ea051e973b 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -948,6 +948,20 @@ static Value *optimizeUnaryDoubleFP(CallInst *CI, IRBuilder<> &B, return B.CreateFPExt(V, B.getDoubleTy()); } +// Replace a libcall \p CI with a call to intrinsic \p IID +static Value *replaceUnaryCall(CallInst *CI, IRBuilder<> &B, Intrinsic::ID IID) { + // Propagate fast-math flags from the existing call to the new call. + IRBuilder<>::FastMathFlagGuard Guard(B); + B.setFastMathFlags(CI->getFastMathFlags()); + + Module *M = CI->getModule(); + Value *V = CI->getArgOperand(0); + Function *F = Intrinsic::getDeclaration(M, IID, CI->getType()); + CallInst *NewCall = B.CreateCall(F, V); + NewCall->takeName(CI); + return NewCall; +} + /// Shrink double -> float for binary functions like 'fmin/fmax'. static Value *optimizeBinaryDoubleFP(CallInst *CI, IRBuilder<> &B) { Function *Callee = CI->getCalledFunction(); @@ -1210,19 +1224,6 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilder<> &B) { return Ret; } -Value *LibCallSimplifier::optimizeFabs(CallInst *CI, IRBuilder<> &B) { - Function *Callee = CI->getCalledFunction(); - IRBuilder<>::FastMathFlagGuard Guard(B); - B.setFastMathFlags(CI->getFastMathFlags()); - - // fabs/fabsf -> llvm.fabs.* - Value *F = Intrinsic::getDeclaration(Callee->getParent(), Intrinsic::fabs, - CI->getType()); - Value *NewCall = B.CreateCall(F, { CI->getArgOperand(0) }); - NewCall->takeName(CI); - return NewCall; -} - Value *LibCallSimplifier::optimizeFMinFMax(CallInst *CI, IRBuilder<> &B) { Function *Callee = CI->getCalledFunction(); // If we can shrink the call to a float function rather than a double @@ -2091,7 +2092,7 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { case LibFunc_fabsf: case LibFunc_fabs: case LibFunc_fabsl: - return optimizeFabs(CI, Builder); + return replaceUnaryCall(CI, Builder, Intrinsic::fabs); case LibFunc_sqrtf: case LibFunc_sqrt: case LibFunc_sqrtl: @@ -2144,14 +2145,16 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { case LibFunc_fputc: return optimizeErrorReporting(CI, Builder, 1); case LibFunc_ceil: + return replaceUnaryCall(CI, Builder, Intrinsic::ceil); case LibFunc_floor: - case LibFunc_rint: + return replaceUnaryCall(CI, Builder, Intrinsic::floor); case LibFunc_round: + return replaceUnaryCall(CI, Builder, Intrinsic::round); case LibFunc_nearbyint: + case LibFunc_rint: + return replaceUnaryCall(CI, Builder, Intrinsic::nearbyint); case LibFunc_trunc: - if (hasFloatVersion(FuncName)) - return optimizeUnaryDoubleFP(CI, Builder, false); - return nullptr; + return replaceUnaryCall(CI, Builder, Intrinsic::trunc); case LibFunc_acos: case LibFunc_acosh: case LibFunc_asin: @@ -2215,16 +2218,10 @@ void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) { // * log(exp10(y)) -> y*log(10) // * log(sqrt(x)) -> 0.5*log(x) // -// lround, lroundf, lroundl: -// * lround(cnst) -> cnst' -// // pow, powf, powl: // * pow(sqrt(x),y) -> pow(x,y*0.5) // * pow(pow(x,y),z)-> pow(x,y*z) // -// round, roundf, roundl: -// * round(cnst) -> cnst' -// // signbit: // * signbit(cnst) -> cnst' // * signbit(nncst) -> 0 (if pstv is a non-negative constant) @@ -2234,10 +2231,6 @@ void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) { // * sqrt(Nroot(x)) -> pow(x,1/(2*N)) // * sqrt(pow(x,y)) -> pow(|x|,y*0.5) // -// trunc, truncf, truncl: -// * trunc(cnst) -> cnst' -// -// //===----------------------------------------------------------------------===// // Fortified Library Call Optimizations |