mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 06:00:28 +00:00
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252098 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d022e94463
commit
9496ef1fef
@ -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);
|
||||
|
@ -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);
|
||||
|
17
test/Transforms/InstCombine/tan-nofastmath.ll
Normal file
17
test/Transforms/InstCombine/tan-nofastmath.ll
Normal file
@ -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)
|
15
test/Transforms/InstCombine/tan.ll
Normal file
15
test/Transforms/InstCombine/tan.ll
Normal file
@ -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" }
|
Loading…
Reference in New Issue
Block a user