From a6b21ea4ba4ef7250346c9423807415be049ebfd Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Tue, 27 Dec 2011 18:25:50 +0000 Subject: [PATCH] Turn cos(-x) into cos(x). Patch by Alexander Malyshev! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147291 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SimplifyLibCalls.cpp | 32 ++++++++++++++++++---- test/Transforms/SimplifyLibCalls/cos.ll | 14 ++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 test/Transforms/SimplifyLibCalls/cos.ll diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index f3184ecc860..dcfcf1a8764 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -840,6 +840,28 @@ struct MemSetOpt : public LibCallOptimization { // Math Library Optimizations //===----------------------------------------------------------------------===// +//===---------------------------------------===// +// 'cos*' Optimizations + +struct CosOpt : public LibCallOptimization { + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { + 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 0; + + // cos(-x) -> cos(x) + Value *Op1 = CI->getArgOperand(0); + if (BinaryOperator::isFNeg(Op1)) { + BinaryOperator *BinExpr = cast(Op1); + return B.CreateCall(Callee, BinExpr->getOperand(1), "cos"); + } + return 0; + } +}; + //===---------------------------------------===// // 'pow*' Optimizations @@ -870,7 +892,7 @@ struct PowOpt : public LibCallOptimization { if (Op2C->isExactlyValue(0.5)) { // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))). // This is faster than calling pow, and still handles negative zero - // and negative infinite correctly. + // and negative infinity correctly. // TODO: In fast-math mode, this could be just sqrt(x). // TODO: In finite-only mode, this could be just fabs(sqrt(x)). Value *Inf = ConstantFP::getInfinity(CI->getType()); @@ -1455,7 +1477,7 @@ namespace { StrToOpt StrTo; StrSpnOpt StrSpn; StrCSpnOpt StrCSpn; StrStrOpt StrStr; MemCmpOpt MemCmp; MemCpyOpt MemCpy; MemMoveOpt MemMove; MemSetOpt MemSet; // Math Library Optimizations - PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP; + CosOpt Cos; PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP; // Integer Optimizations FFSOpt FFS; AbsOpt Abs; IsDigitOpt IsDigit; IsAsciiOpt IsAscii; ToAsciiOpt ToAscii; @@ -1539,6 +1561,9 @@ void SimplifyLibCalls::InitOptimizations() { Optimizations["__strcpy_chk"] = &StrCpyChk; // Math Library Optimizations + Optimizations["cosf"] = &Cos; + Optimizations["cos"] = &Cos; + Optimizations["cosl"] = &Cos; Optimizations["powf"] = &Pow; Optimizations["pow"] = &Pow; Optimizations["powl"] = &Pow; @@ -2352,9 +2377,6 @@ bool SimplifyLibCalls::doInitialization(Module &M) { // * cbrt(sqrt(x)) -> pow(x,1/6) // * cbrt(sqrt(x)) -> pow(x,1/9) // -// cos, cosf, cosl: -// * cos(-x) -> cos(x) -// // exp, expf, expl: // * exp(log(x)) -> x // diff --git a/test/Transforms/SimplifyLibCalls/cos.ll b/test/Transforms/SimplifyLibCalls/cos.ll new file mode 100644 index 00000000000..6a8ce8c3881 --- /dev/null +++ b/test/Transforms/SimplifyLibCalls/cos.ll @@ -0,0 +1,14 @@ +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define double @foo(double %d) nounwind readnone { +; CHECK: @foo + %1 = fsub double -0.000000e+00, %d + %2 = call double @cos(double %1) nounwind readnone +; CHECK: call double @cos(double %d) + ret double %2 +} + +declare double @cos(double) nounwind readnone