aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
diff options
context:
space:
mode:
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)