From 22829ab5faf0337144e620189e2000749ab825c9 Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Tue, 5 May 2020 13:32:59 +0100 Subject: [PATCH] [InstCombine] Allow denormal C in pow(C,y) -> exp2(log2(C)*y) We check that C is finite and strictly positive, but there's no need to check that it's normal too. exp2 should be just as accurate on denormals as pow is. Differential Revision: https://reviews.llvm.org/D79413 --- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 2 +- llvm/test/Transforms/InstCombine/pow-exp.ll | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 01bf124fcb064..a4ab13fb5e5ec 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1565,7 +1565,7 @@ Value *LibCallSimplifier::replacePowWithExp(CallInst *Pow, IRBuilderBase &B) { // pow(n, x) -> exp2(log2(n) * x) if (Pow->hasApproxFunc() && Pow->hasNoNaNs() && Pow->hasNoInfs() && - BaseF->isNormal() && !BaseF->isNegative()) { + 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 index dac926c9deba7..f5bf0f54fab40 100644 --- a/llvm/test/Transforms/InstCombine/pow-exp.ll +++ b/llvm/test/Transforms/InstCombine/pow-exp.ll @@ -263,8 +263,9 @@ define double @pow_ok_ten_base(double %e) { define double @pow_ok_denorm_base(double %e) { ; CHECK-LABEL: @pow_ok_denorm_base( -; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn double @pow(double 0xFFFFFFFF, double [[E:%.*]]) -; CHECK-NEXT: ret double [[CALL]] +; 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 @@ -312,8 +313,9 @@ define float @powf_ok_ten_base(float %e) { define float @powf_ok_denorm_base(float %e) { ; CHECK-LABEL: @powf_ok_denorm_base( -; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @powf(float 0x3780000000000000, float [[E:%.*]]) -; CHECK-NEXT: ret float [[CALL]] +; 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