Index: include/llvm/Transforms/Utils/SimplifyLibCalls.h =================================================================== --- include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -134,6 +134,7 @@ 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); Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1359,6 +1359,44 @@ 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); + + // tanf(atanf(x)) -> x + if (auto *OpC = dyn_cast(Op1)) { + IRBuilder<>::FastMathFlagGuard Guard(B); + FastMathFlags FMF; + FMF.setUnsafeAlgebra(); + B.SetFastMathFlags(FMF); + + LibFunc::Func Func; + Function *F = OpC->getCalledFunction(); + StringRef FuncName = F->getName(); + + if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func) && + ((Callee->getName() == "tan" && (Func == LibFunc::atan)) || + (Callee->getName() == "tanf" && (Func == LibFunc::atanf)) || + (Callee->getName() == "tanl" && (Func == LibFunc::atanl)))) + return 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 +2184,10 @@ 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 +2222,6 @@ case LibFunc::logb: case LibFunc::sin: case LibFunc::sinh: - case LibFunc::tan: case LibFunc::tanh: if (UnsafeFPShrink && hasFloatVersion(FuncName)) return optimizeUnaryDoubleFP(CI, Builder, true); Index: test/Transforms/InstCombine/tan.ll =================================================================== --- test/Transforms/InstCombine/tan.ll +++ test/Transforms/InstCombine/tan.ll @@ -0,0 +1,20 @@ +; 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: define float @mytan(float %x) #0 { +; CHECK-NEXT: entry: +; CHECK-NEXT: %call = call float @atanf(float %x) +; CHECK-NEXT: ret float %x +; CHECK-NEXT: } + +declare float @tanf(float) #1 +declare float @atanf(float) #1 + +attributes #0 = { "unsafe-fp-math"="true" } +attributes #1 = { "unsafe-fp-math"="true" }