diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1722,7 +1722,8 @@ // pow(x, n) -> x * x * x * ... const APFloat *ExpoF; - if (AllowApprox && match(Expo, m_APFloat(ExpoF))) { + if (AllowApprox && match(Expo, m_APFloat(ExpoF)) && + !ExpoF->isExactlyValue(0.5) && !ExpoF->isExactlyValue(-0.5)) { // We limit to a max of 7 multiplications, thus the maximum exponent is 32. // If the exponent is an integer+0.5 we generate a call to sqrt and an // additional fmul. diff --git a/llvm/test/Transforms/InstCombine/pow-4.ll b/llvm/test/Transforms/InstCombine/pow-4.ll --- a/llvm/test/Transforms/InstCombine/pow-4.ll +++ b/llvm/test/Transforms/InstCombine/pow-4.ll @@ -234,6 +234,24 @@ ret <4 x float> %1 } +; (float)pow((double)(float)x, 0.5) +; FIXME: One call to `sqrtf` would suffice (PR47613). +define float @shrink_pow_libcall_half(float %x) { +; SQRT-LABEL: @shrink_pow_libcall_half( +; SQRT-NEXT: [[SQRTF:%.*]] = call fast float @sqrtf(float [[X:%.*]]) +; SQRT-NEXT: [[SQRTF1:%.*]] = call fast float @sqrtf(float [[X]]) +; SQRT-NEXT: ret float [[SQRTF1]] +; +; NOSQRT-LABEL: @shrink_pow_libcall_half( +; NOSQRT-NEXT: [[SQRTF:%.*]] = call fast float @sqrtf(float [[X:%.*]]) +; NOSQRT-NEXT: ret float [[SQRTF]] +; + %dx = fpext float %x to double + %call = call fast double @pow(double %dx, double 0.5) + %fr = fptrunc double %call to float + ret float %fr +} + ; Make sure that -0.0 exponent is always simplified. define double @PR43233(double %x) {