Index: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1096,6 +1096,8 @@ 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 @@ // 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 @@ 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); Index: llvm/trunk/test/Transforms/InstCombine/pow-sqrt.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/pow-sqrt.ll +++ llvm/trunk/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" }