From b8dd4a3d670ffb4285a9e2329cdc9880be83800e Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Wed, 18 Nov 2015 23:21:32 +0000 Subject: [PATCH] [SimplifyLibCalls] New trick: pow(x, 0.5) -> sqrt(x) under -ffast-math. Differential Revision: http://reviews.llvm.org/D14466 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253521 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/SimplifyLibCalls.cpp | 11 +++++++++-- test/Transforms/InstCombine/pow-sqrt.ll | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 test/Transforms/InstCombine/pow-sqrt.ll diff --git a/lib/Transforms/Utils/SimplifyLibCalls.cpp b/lib/Transforms/Utils/SimplifyLibCalls.cpp index 8e2eeb9211c..72abd0b3329 100644 --- a/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1096,6 +1096,8 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { Callee->getAttributes()); } + bool unsafeFPMath = canUseUnsafeFPMath(CI->getParent()->getParent()); + // pow(exp(x), y) -> exp(x*y) // pow(exp2(x), y) -> exp2(x * y) // We enable these only under fast-math. Besides rounding @@ -1103,7 +1105,7 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { // underflow behavior quite dramatically. // Example: x = 1000, y = 0.001. // pow(exp(x), y) = pow(inf, 0.001) = inf, whereas exp(x*y) = exp(1). - if (canUseUnsafeFPMath(CI->getParent()->getParent())) { + if (unsafeFPMath) { if (auto *OpC = dyn_cast(Op1)) { IRBuilder<>::FastMathFlagGuard Guard(B); FastMathFlags FMF; @@ -1134,10 +1136,15 @@ Value *LibCallSimplifier::optimizePow(CallInst *CI, IRBuilder<> &B) { LibFunc::sqrtl) && hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::fabs, LibFunc::fabsf, LibFunc::fabsl)) { + + // In -ffast-math, pow(x, 0.5) -> sqrt(x). + if (unsafeFPMath) + return EmitUnaryFloatFnCall(Op1, TLI->getName(LibFunc::sqrt), B, + Callee->getAttributes()); + // 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 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()); Value *NegInf = ConstantFP::getInfinity(CI->getType(), true); diff --git a/test/Transforms/InstCombine/pow-sqrt.ll b/test/Transforms/InstCombine/pow-sqrt.ll new file mode 100644 index 00000000000..8fc74e4a002 --- /dev/null +++ b/test/Transforms/InstCombine/pow-sqrt.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +define double @mypow(double %x) #0 { +entry: + %pow = call double @llvm.pow.f64(double %x, double 5.000000e-01) + ret double %pow +} + +; CHECK-LABEL: define double @mypow( +; CHECK: %sqrt = call double @sqrt(double %x) #1 +; CHECK: ret double %sqrt +; CHECK: } + +declare double @llvm.pow.f64(double, double) +attributes #0 = { "unsafe-fp-math"="true" } -- 2.34.1