From 0ca42bb5a8f0e1a3290cd0bd33fdc443941b08ff Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 14 Oct 2014 20:43:11 +0000 Subject: Optimize away fabs() calls when input is squared (known positive). Eliminate library calls and intrinsic calls to fabs when the input is a squared value. Note that no unsafe-math / fast-math assumptions are needed for this optimization. Differential Revision: http://reviews.llvm.org/D5777 llvm-svn: 219717 --- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 31 +++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp') diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index cb4b09cbaf0..9fac7ef540e 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1230,6 +1230,30 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilder<> &B) { return Ret; } +Value *LibCallSimplifier::optimizeFabs(CallInst *CI, IRBuilder<> &B) { + Function *Callee = CI->getCalledFunction(); + + Value *Ret = nullptr; + if (Callee->getName() == "fabs" && TLI->has(LibFunc::fabsf)) { + Ret = optimizeUnaryDoubleFP(CI, B, false); + } + + FunctionType *FT = Callee->getFunctionType(); + // 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; + + Value *Op = CI->getArgOperand(0); + if (Instruction *I = dyn_cast(Op)) { + // Fold fabs(x * x) -> x * x; any squared FP value must already be positive. + if (I->getOpcode() == Instruction::FMul) + if (I->getOperand(0) == I->getOperand(1)) + return Op; + } + return Ret; +} + static bool isTrigLibCall(CallInst *CI); static void insertSinCosCall(IRBuilder<> &B, Function *OrigCallee, Value *Arg, bool UseFloat, Value *&Sin, Value *&Cos, @@ -1893,6 +1917,8 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { return optimizePow(CI, Builder); case Intrinsic::exp2: return optimizeExp2(CI, Builder); + case Intrinsic::fabs: + return optimizeFabs(CI, Builder); default: return nullptr; } @@ -1965,6 +1991,10 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { case LibFunc::exp2: case LibFunc::exp2f: return optimizeExp2(CI, Builder); + case LibFunc::fabsf: + case LibFunc::fabs: + case LibFunc::fabsl: + return optimizeFabs(CI, Builder); case LibFunc::ffs: case LibFunc::ffsl: case LibFunc::ffsll: @@ -1999,7 +2029,6 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { case LibFunc::fputc: return optimizeErrorReporting(CI, Builder, 1); case LibFunc::ceil: - case LibFunc::fabs: case LibFunc::floor: case LibFunc::rint: case LibFunc::round: -- cgit v1.2.3