diff options
author | David Green <david.green@arm.com> | 2024-10-10 09:54:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-10 09:54:25 +0100 |
commit | 5184d763c70bf0c64b309262a40d9528a7dc4a2f (patch) | |
tree | 26e30d09482c406277a9a6d3d0ab1fe986a4e1b0 /llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | |
parent | 54d3cf14213f18e44ef9ed2ffe3b3131e472e2f5 (diff) | |
download | llvm-5184d763c70bf0c64b309262a40d9528a7dc4a2f.zip llvm-5184d763c70bf0c64b309262a40d9528a7dc4a2f.tar.gz llvm-5184d763c70bf0c64b309262a40d9528a7dc4a2f.tar.bz2 |
[InstCombine] Convert @log to @llvm.log if the input is known positive. (#111428)
Similar to 112aac4e8961b9626bb84f36deeaa5a674f03f5a, this converts log
libcalls to llvm.log.f64 intrinsics if we know they do not set errno, as
the input is not zero and not negative. As log will produce errno if the
input is 0 (returning -inf) or if the input is negative (returning nan),
we also perform the conversion when we have noinf and nonan.
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 347e4d6..5f902ee 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -2510,20 +2510,15 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) { Intrinsic::ID LogID = LogFn->getIntrinsicID(); Module *Mod = Log->getModule(); Type *Ty = Log->getType(); - Value *Ret = nullptr; if (UnsafeFPShrink && hasFloatVersion(Mod, LogNm)) - Ret = optimizeUnaryDoubleFP(Log, B, TLI, true); - - // The earlier call must also be 'fast' in order to do these transforms. - CallInst *Arg = dyn_cast<CallInst>(Log->getArgOperand(0)); - if (!Log->isFast() || !Arg || !Arg->isFast() || !Arg->hasOneUse()) - return Ret; + if (Value *Ret = optimizeUnaryDoubleFP(Log, B, TLI, true)) + return Ret; LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb; // This is only applicable to log(), log2(), log10(). - if (TLI->getLibFunc(LogNm, LogLb)) + if (TLI->getLibFunc(LogNm, LogLb)) { switch (LogLb) { case LibFunc_logf: LogID = Intrinsic::log; @@ -2589,10 +2584,28 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) { PowLb = LibFunc_powl; break; default: - return Ret; + return nullptr; + } + + // Convert libcall to intrinsic if the value is known > 0. + bool IsKnownNoErrno = Log->hasNoNaNs() && Log->hasNoInfs(); + if (!IsKnownNoErrno) { + SimplifyQuery SQ(DL, TLI, DT, AC, Log, true, true, DC); + KnownFPClass Known = computeKnownFPClass( + Log->getOperand(0), + KnownFPClass::OrderedLessThanZeroMask | fcSubnormal, + /*Depth=*/0, SQ); + Function *F = Log->getParent()->getParent(); + IsKnownNoErrno = Known.cannotBeOrderedLessThanZero() && + Known.isKnownNeverLogicalZero(*F, Ty); + } + if (IsKnownNoErrno) { + auto *NewLog = B.CreateUnaryIntrinsic(LogID, Log->getArgOperand(0), Log); + NewLog->copyMetadata(*Log); + return copyFlags(*Log, NewLog); } - else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 || - LogID == Intrinsic::log10) { + } else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 || + LogID == Intrinsic::log10) { if (Ty->getScalarType()->isFloatTy()) { ExpLb = LibFunc_expf; Exp2Lb = LibFunc_exp2f; @@ -2604,9 +2617,14 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) { Exp10Lb = LibFunc_exp10; PowLb = LibFunc_pow; } else - return Ret; + return nullptr; } else - return Ret; + return nullptr; + + // The earlier call must also be 'fast' in order to do these transforms. + CallInst *Arg = dyn_cast<CallInst>(Log->getArgOperand(0)); + if (!Log->isFast() || !Arg || !Arg->isFast() || !Arg->hasOneUse()) + return nullptr; IRBuilderBase::FastMathFlagGuard Guard(B); B.setFastMathFlags(FastMathFlags::getFast()); @@ -2655,7 +2673,7 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) { return MulY; } - return Ret; + return nullptr; } // sqrt(exp(X)) -> exp(X * 0.5) |