Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1052,15 +1052,19 @@ Callee->getAttributes()); } - // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))). + // In finite-only mode, pow(x, 0.5) -> fabs(sqrt(x)) + Value *Sqrt = emitUnaryFloatFnCall(Op1, "sqrt", B, Callee->getAttributes()); + Value *FAbs = + emitUnaryFloatFnCall(Sqrt, "fabs", B, Callee->getAttributes()); + if (CI->hasNoNaNs() && CI->hasNoInfs()) + return FAbs; + + // Otherwise, 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 finite-only mode, this could be just fabs(sqrt(x)). Value *Inf = ConstantFP::getInfinity(CI->getType()); Value *NegInf = ConstantFP::getInfinity(CI->getType(), true); - Value *Sqrt = emitUnaryFloatFnCall(Op1, "sqrt", B, Callee->getAttributes()); - Value *FAbs = - emitUnaryFloatFnCall(Sqrt, "fabs", B, Callee->getAttributes()); Value *FCmp = B.CreateFCmpOEQ(Op1, NegInf); Value *Sel = B.CreateSelect(FCmp, Inf, FAbs); return Sel; Index: test/Transforms/InstCombine/pow-sqrt.ll =================================================================== --- test/Transforms/InstCombine/pow-sqrt.ll +++ test/Transforms/InstCombine/pow-sqrt.ll @@ -11,3 +11,14 @@ declare double @llvm.pow.f64(double, double) +; In finite-only mode, we can transform pow(x, 0.5) -> fabs(sqrt(x)) + +define double @pow_finite(double %x) { + %pow = call nnan ninf double @llvm.pow.f64(double %x, double 5.000000e-01) + ret double %pow +} + +; CHECK-LABEL: define double @pow_finite( +; CHECK-NEXT: %sqrt = call double @sqrt(double %x) +; CHECK-NEXT: %fabs = call double @fabs(double %sqrt) +; CHECK-NEXT: ret double %fabs