Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1074,6 +1074,22 @@ if (Op2C->getValueAPF().isZero()) // pow(x, 0.0) -> 1.0 return ConstantFP::get(CI->getType(), 1.0); + if (Op2C->isExactlyValue(-0.5) && + hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf, + LibFunc::sqrtl)) { + // If -ffast-math: + // pow(x, -0.5) -> 1.0 / sqrt(x) + if (CI->hasUnsafeAlgebra()) { + + // Here we cannot lower to an intrinsic because C99 sqrt() and llvm.sqrt + // are not guaranteed to have the same semantics. + Value *Sqrt = emitUnaryFloatFnCall(Op1, TLI->getName(LibFunc::sqrt), B, + Callee->getAttributes()); + + return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), Sqrt, "sqrtrecip"); + } + } + if (Op2C->isExactlyValue(0.5) && hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf, LibFunc::sqrtl) && Index: test/Transforms/InstCombine/pow-sqrt.ll =================================================================== --- test/Transforms/InstCombine/pow-sqrt.ll +++ test/Transforms/InstCombine/pow-sqrt.ll @@ -9,5 +9,14 @@ ; CHECK-NEXT: %sqrt = call fast double @sqrt(double %x) ; CHECK-NEXT: ret double %sqrt -declare double @llvm.pow.f64(double, double) +define double @pow_neghalf(double %x) { + %pow = call fast double @llvm.pow.f64(double %x, double -5.000000e-01) + ret double %pow +} +; CHECK-LABEL: define double @pow_neghalf( +; CHECK-NEXT: %sqrt = call double @sqrt(double %x) #0 +; CHECK-NEXT: %sqrtrecip = fdiv double 1.000000e+00, %sqrt +; CHECK-NEXT: ret double %sqrtrecip + +declare double @llvm.pow.f64(double, double)