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 @@ -1563,9 +1563,14 @@ return emitUnaryFloatFnCall(Expo, TLI, LibFunc_exp10, LibFunc_exp10f, LibFunc_exp10l, B, Attrs); - // pow(n, x) -> exp2(log2(n) * x) - if (Pow->hasApproxFunc() && Pow->hasNoNaNs() && Pow->hasNoInfs() && - BaseF->isFiniteNonZero() && !BaseF->isNegative()) { + // pow(x, y) -> exp2(log2(x) * y) + if (Pow->hasApproxFunc() && Pow->hasNoNaNs() && BaseF->isFiniteNonZero() && + !BaseF->isNegative()) { + // pow(1, inf) is defined to be 1 but exp2(log2(1) * inf) evaluates to NaN. + // Luckily optimizePow has already handled the x == 1 case. + assert(!match(Base, m_FPOne()) && + "pow(1.0, y) should have been simplified earlier!"); + Value *Log = nullptr; if (Ty->isFloatTy()) Log = ConstantFP::get(Ty, std::log2(BaseF->convertToFloat())); diff --git a/llvm/test/Transforms/InstCombine/pow-exp.ll b/llvm/test/Transforms/InstCombine/pow-exp.ll --- a/llvm/test/Transforms/InstCombine/pow-exp.ll +++ b/llvm/test/Transforms/InstCombine/pow-exp.ll @@ -400,8 +400,9 @@ define double @pow_ok_base_no_ninf(double %e) { ; CHECK-LABEL: @pow_ok_base_no_ninf( -; CHECK-NEXT: [[CALL:%.*]] = tail call nnan afn double @pow(double 0x3FE6666666666666, double [[E:%.*]]) -; CHECK-NEXT: ret double [[CALL]] +; CHECK-NEXT: [[MUL:%.*]] = fmul nnan afn double [[E:%.*]], 0xBFE0776{{.*}} +; CHECK-NEXT: [[EXP2:%.*]] = call nnan afn double @exp2(double [[MUL]]) +; CHECK-NEXT: ret double [[EXP2]] ; %call = tail call afn nnan double @pow(double 0x3FE6666666666666, double %e) ret double %call