aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
diff options
context:
space:
mode:
authorDavid Green <david.green@arm.com>2024-10-10 09:54:25 +0100
committerGitHub <noreply@github.com>2024-10-10 09:54:25 +0100
commit5184d763c70bf0c64b309262a40d9528a7dc4a2f (patch)
tree26e30d09482c406277a9a6d3d0ab1fe986a4e1b0 /llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
parent54d3cf14213f18e44ef9ed2ffe3b3131e472e2f5 (diff)
downloadllvm-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.cpp46
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)