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 @@ -1565,7 +1565,7 @@ // pow(n, x) -> exp2(log2(n) * x) if (Pow->hasOneUse() && Pow->hasApproxFunc() && Pow->hasNoNaNs() && - Pow->hasNoInfs() && BaseF->isNormal() && !BaseF->isNegative()) { + Pow->hasNoInfs() && BaseF->isFiniteNonZero() && !BaseF->isNegative()) { 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 @@ -261,6 +261,16 @@ ret double %call } +define double @pow_ok_denorm_base(double %e) { +; CHECK-LABEL: @pow_ok_denorm_base( +; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn double [[E:%.*]], 0xC0904800000005C5 +; CHECK-NEXT: [[EXP2:%.*]] = call nnan ninf afn double @exp2(double [[MUL]]) +; CHECK-NEXT: ret double [[EXP2]] +; + %call = tail call afn nnan ninf double @pow(double 0x00000000FFFFFFFF, double %e) + ret double %call +} + define float @powf_ok_base(float %e) { ; CHECK-LABEL: @powf_ok_base( ; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn float [[E:%.*]], 0xBFE07762{{.*}} @@ -301,6 +311,16 @@ ret float %call } +define float @powf_ok_denorm_base(float %e) { +; CHECK-LABEL: @powf_ok_denorm_base( +; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn float [[E:%.*]], -1.350000e+02 +; CHECK-NEXT: [[EXP2F:%.*]] = call nnan ninf afn float @exp2f(float [[MUL]]) +; CHECK-NEXT: ret float [[EXP2F]] +; + %call = tail call afn nnan ninf float @powf(float 0x3780000000000000, float %e) + ret float %call +} + ; Negative tests define double @pow_zero_base(double %e) {