summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2015-11-04 23:36:56 +0000
committerDavide Italiano <davide@freebsd.org>2015-11-04 23:36:56 +0000
commit51507d2ad84683daa77d202141d0a63ff94ae9d6 (patch)
tree799c6d45abf918129bbe43185c05850c8f91e0fa /llvm/lib/Transforms
parente692621a9dc6eff696939a552fe7aa1fed4300ad (diff)
downloadbcm5719-llvm-51507d2ad84683daa77d202141d0a63ff94ae9d6.tar.gz
bcm5719-llvm-51507d2ad84683daa77d202141d0a63ff94ae9d6.zip
[SimplifyLibCalls] New transformation: tan(atan(x)) -> x
This is enabled only under -ffast-math. So, instead of emitting: 4007b0: 50 push %rax 4007b1: e8 8a fd ff ff callq 400540 <atanf@plt> 4007b6: 58 pop %rax 4007b7: e9 94 fd ff ff jmpq 400550 <tanf@plt> 4007bc: 0f 1f 40 00 nopl 0x0(%rax) for: float mytan(float x) { return tanf(atanf(x)); } we emit a single retq. Differential Revision: http://reviews.llvm.org/D14302 llvm-svn: 252098
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp39
1 files changed, 38 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 14a0a57ce30..6e9eacc4d2a 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -1359,6 +1359,40 @@ Value *LibCallSimplifier::optimizeSqrt(CallInst *CI, IRBuilder<> &B) {
return Ret;
}
+Value *LibCallSimplifier::optimizeTan(CallInst *CI, IRBuilder<> &B) {
+ Function *Callee = CI->getCalledFunction();
+ Value *Ret = nullptr;
+ if (UnsafeFPShrink && Callee->getName() == "tan" && TLI->has(LibFunc::tanf))
+ Ret = optimizeUnaryDoubleFP(CI, B, true);
+ FunctionType *FT = Callee->getFunctionType();
+
+ // Just make sure this has 1 argument of FP type, which matches the
+ // result type.
+ if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
+ !FT->getParamType(0)->isFloatingPointTy())
+ return Ret;
+
+ if (!canUseUnsafeFPMath(CI->getParent()->getParent()))
+ return Ret;
+ Value *Op1 = CI->getArgOperand(0);
+ auto *OpC = dyn_cast<CallInst>(Op1);
+ if (!OpC)
+ return Ret;
+
+ // tan(atan(x)) -> x
+ // tanf(atanf(x)) -> x
+ // tanl(atanl(x)) -> x
+ LibFunc::Func Func;
+ Function *F = OpC->getCalledFunction();
+ StringRef FuncName = F->getName();
+ if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func) &&
+ ((Func == LibFunc::atan && Callee->getName() == "tan") ||
+ (Func == LibFunc::atanf && Callee->getName() == "tanf") ||
+ (Func == LibFunc::atanl && Callee->getName() == "tanl")))
+ Ret = OpC->getArgOperand(0);
+ return Ret;
+}
+
static bool isTrigLibCall(CallInst *CI);
static void insertSinCosCall(IRBuilder<> &B, Function *OrigCallee, Value *Arg,
bool UseFloat, Value *&Sin, Value *&Cos,
@@ -2146,6 +2180,10 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
return optimizeFPuts(CI, Builder);
case LibFunc::puts:
return optimizePuts(CI, Builder);
+ case LibFunc::tan:
+ case LibFunc::tanf:
+ case LibFunc::tanl:
+ return optimizeTan(CI, Builder);
case LibFunc::perror:
return optimizeErrorReporting(CI, Builder);
case LibFunc::vfprintf:
@@ -2180,7 +2218,6 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
case LibFunc::logb:
case LibFunc::sin:
case LibFunc::sinh:
- case LibFunc::tan:
case LibFunc::tanh:
if (UnsafeFPShrink && hasFloatVersion(FuncName))
return optimizeUnaryDoubleFP(CI, Builder, true);
OpenPOWER on IntegriCloud