From: Davide Italiano Date: Wed, 4 Nov 2015 23:36:56 +0000 (+0000) Subject: [SimplifyLibCalls] New transformation: tan(atan(x)) -> x X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=9496ef1fefb7a9caa9e5acf9356a59ca5c37c07d [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 4007b6: 58 pop %rax 4007b7: e9 94 fd ff ff jmpq 400550 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252098 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h index 89686fd5cbc..55b0a13ad3c 100644 --- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -134,6 +134,7 @@ private: Value *optimizeFMinFMax(CallInst *CI, IRBuilder<> &B); Value *optimizeSqrt(CallInst *CI, IRBuilder<> &B); Value *optimizeSinCosPi(CallInst *CI, IRBuilder<> &B); + Value *optimizeTan(CallInst *CI, IRBuilder<> &B); // Integer Library Call Optimizations Value *optimizeFFS(CallInst *CI, IRBuilder<> &B); diff --git a/lib/Transforms/Utils/SimplifyLibCalls.cpp b/lib/Transforms/Utils/SimplifyLibCalls.cpp index 14a0a57ce30..6e9eacc4d2a 100644 --- a/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/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(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); diff --git a/test/Transforms/InstCombine/tan-nofastmath.ll b/test/Transforms/InstCombine/tan-nofastmath.ll new file mode 100644 index 00000000000..0fe7b2c1d52 --- /dev/null +++ b/test/Transforms/InstCombine/tan-nofastmath.ll @@ -0,0 +1,17 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +define float @mytan(float %x) { +entry: + %call = call float @atanf(float %x) + %call1 = call float @tanf(float %call) + ret float %call1 +} + +; CHECK-LABEL: define float @mytan( +; CHECK: %call = call float @atanf(float %x) +; CHECK-NEXT: %call1 = call float @tanf(float %call) +; CHECK-NEXT: ret float %call1 +; CHECK-NEXT: } + +declare float @tanf(float) +declare float @atanf(float) diff --git a/test/Transforms/InstCombine/tan.ll b/test/Transforms/InstCombine/tan.ll new file mode 100644 index 00000000000..58e3bb355bd --- /dev/null +++ b/test/Transforms/InstCombine/tan.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +define float @mytan(float %x) #0 { +entry: + %call = call float @atanf(float %x) + %call1 = call float @tanf(float %call) + ret float %call1 +} + +; CHECK-LABEL: define float @mytan( +; CHECK: ret float %x + +declare float @tanf(float) #0 +declare float @atanf(float) #0 +attributes #0 = { "unsafe-fp-math"="true" }