Skip to content

Commit

Permalink
[SimplifyLibCalls] New trick: pow(x, 0.5) -> sqrt(x) under -ffast-math.
Browse files Browse the repository at this point in the history
Differential Revision:	http://reviews.llvm.org/D14466


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253521 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
dcci committed Nov 18, 2015
1 parent 3fe74b8 commit b8dd4a3
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
11 changes: 9 additions & 2 deletions lib/Transforms/Utils/SimplifyLibCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1096,14 +1096,16 @@ 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
// differences the transformation changes overflow and
// 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<CallInst>(Op1)) {
IRBuilder<>::FastMathFlagGuard Guard(B);
FastMathFlags FMF;
Expand Down Expand Up @@ -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);
Expand Down
15 changes: 15 additions & 0 deletions test/Transforms/InstCombine/pow-sqrt.ll
Original file line number Diff line number Diff line change
@@ -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" }

0 comments on commit b8dd4a3

Please sign in to comment.