[llvm] r254263 - [SimplifyLibCalls] Tranform log(pow(x, y)) -> y*log(x).
Davide Italiano via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 29 12:58:05 PST 2015
Author: davide
Date: Sun Nov 29 14:58:04 2015
New Revision: 254263
URL: http://llvm.org/viewvc/llvm-project?rev=254263&view=rev
Log:
[SimplifyLibCalls] Tranform log(pow(x, y)) -> y*log(x).
This one is enabled only under -ffast-math. There are cases where the
difference between the value computed and the correct value is huge
even for ffast-math, e.g. as Steven pointed out:
x = -1, y = -4
log(pow(-1), 4) = 0
4*log(-1) = NaN
I checked what GCC does and apparently they do the same optimization
(which result in the dramatic difference). Future work might try to
make this (slightly) less worse.
Differential Revision: http://reviews.llvm.org/D14400
Added:
llvm/trunk/test/Transforms/InstCombine/log-pow-nofastmath.ll
llvm/trunk/test/Transforms/InstCombine/log-pow.ll
Modified:
llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
Modified: llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h?rev=254263&r1=254262&r2=254263&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h Sun Nov 29 14:58:04 2015
@@ -132,6 +132,7 @@ private:
Value *optimizeExp2(CallInst *CI, IRBuilder<> &B);
Value *optimizeFabs(CallInst *CI, IRBuilder<> &B);
Value *optimizeFMinFMax(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeLog(CallInst *CI, IRBuilder<> &B);
Value *optimizeSqrt(CallInst *CI, IRBuilder<> &B);
Value *optimizeSinCosPi(CallInst *CI, IRBuilder<> &B);
Value *optimizeTan(CallInst *CI, IRBuilder<> &B);
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=254263&r1=254262&r2=254263&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Sun Nov 29 14:58:04 2015
@@ -1284,6 +1284,48 @@ Value *LibCallSimplifier::optimizeFMinFM
return B.CreateSelect(Cmp, Op0, Op1);
}
+Value *LibCallSimplifier::optimizeLog(CallInst *CI, IRBuilder<> &B) {
+ Function *Callee = CI->getCalledFunction();
+ Value *Ret = nullptr;
+ StringRef Name = Callee->getName();
+ if (UnsafeFPShrink && hasFloatVersion(Name))
+ 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;
+
+ // log(pow(x,y)) -> y*log(x)
+ // This is only applicable to log, log2, log10.
+ if (Name != "log" && Name != "log2" && Name != "log10")
+ return Ret;
+
+ 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) &&
+ Func == LibFunc::pow) || F->getIntrinsicID() == Intrinsic::pow)
+ return B.CreateFMul(OpC->getArgOperand(1),
+ EmitUnaryFloatFnCall(OpC->getOperand(0), Callee->getName(), B,
+ Callee->getAttributes()), "mul");
+ return Ret;
+}
+
Value *LibCallSimplifier::optimizeSqrt(CallInst *CI, IRBuilder<> &B) {
Function *Callee = CI->getCalledFunction();
@@ -2088,6 +2130,8 @@ Value *LibCallSimplifier::optimizeCall(C
return optimizeExp2(CI, Builder);
case Intrinsic::fabs:
return optimizeFabs(CI, Builder);
+ case Intrinsic::log:
+ return optimizeLog(CI, Builder);
case Intrinsic::sqrt:
return optimizeSqrt(CI, Builder);
default:
@@ -2170,6 +2214,12 @@ Value *LibCallSimplifier::optimizeCall(C
return optimizeFWrite(CI, Builder);
case LibFunc::fputs:
return optimizeFPuts(CI, Builder);
+ case LibFunc::log:
+ case LibFunc::log10:
+ case LibFunc::log1p:
+ case LibFunc::log2:
+ case LibFunc::logb:
+ return optimizeLog(CI, Builder);
case LibFunc::puts:
return optimizePuts(CI, Builder);
case LibFunc::tan:
@@ -2203,11 +2253,6 @@ Value *LibCallSimplifier::optimizeCall(C
case LibFunc::exp:
case LibFunc::exp10:
case LibFunc::expm1:
- case LibFunc::log:
- case LibFunc::log10:
- case LibFunc::log1p:
- case LibFunc::log2:
- case LibFunc::logb:
case LibFunc::sin:
case LibFunc::sinh:
case LibFunc::tanh:
Added: llvm/trunk/test/Transforms/InstCombine/log-pow-nofastmath.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/log-pow-nofastmath.ll?rev=254263&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/log-pow-nofastmath.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/log-pow-nofastmath.ll Sun Nov 29 14:58:04 2015
@@ -0,0 +1,17 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+define double @mylog(double %x, double %y) #0 {
+entry:
+ %pow = call double @llvm.pow.f64(double %x, double %y)
+ %call = call double @log(double %pow) #0
+ ret double %call
+}
+
+; CHECK-LABEL: define double @mylog(
+; CHECK: %pow = call double @llvm.pow.f64(double %x, double %y)
+; CHECK: %call = call double @log(double %pow)
+; CHECK: ret double %call
+; CHECK: }
+
+declare double @log(double) #0
+declare double @llvm.pow.f64(double, double)
Added: llvm/trunk/test/Transforms/InstCombine/log-pow.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/log-pow.ll?rev=254263&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/log-pow.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/log-pow.ll Sun Nov 29 14:58:04 2015
@@ -0,0 +1,19 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+define double @mylog(double %x, double %y) #0 {
+entry:
+ %pow = call double @llvm.pow.f64(double %x, double %y)
+ %call = call double @log(double %pow) #0
+ ret double %call
+}
+
+; CHECK-LABEL: define double @mylog(
+; CHECK: %log = call double @log(double %x) #0
+; CHECK: %mul = fmul fast double %log, %y
+; CHECK: ret double %mul
+; CHECK: }
+
+declare double @log(double) #0
+declare double @llvm.pow.f64(double, double)
+
+attributes #0 = { "unsafe-fp-math"="true" }
More information about the llvm-commits
mailing list