-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[InstCombine] Convert @log to @llvm.log if the input is known positive. #111428
Conversation
|
||
// fmod(x,y) can set errno if y == 0 or x == +/-inf, and returns Nan in those | ||
// case. If we know those do not happen, then we can convert the fmod into | ||
// frem. | ||
bool IsNoNan = CI->hasNoNaNs(); | ||
if (!IsNoNan) { | ||
SimplifyQuery SQ(DL, TLI, DT, AC, CI, true, true, DC); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unrelated, I'll push it separately.
@llvm/pr-subscribers-llvm-transforms Author: David Green (davemgreen) ChangesSimilar to 112aac4, 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. Full diff: https://github.com/llvm/llvm-project/pull/111428.diff 4 Files Affected:
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 6799d333fb2844..0c1ddc19d7f245 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,26 @@ 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,
+ /*Depth=*/0, SQ);
+ IsKnownNoErrno =
+ Known.isKnownNeverZero() && Known.cannotBeOrderedLessThanZero();
+ }
+ if (IsKnownNoErrno) {
+ IRBuilderBase::FastMathFlagGuard Guard(B);
+ B.setFastMathFlags(Log->getFastMathFlags());
+ return B.CreateIntrinsic(LogID, {Ty}, {Log->getArgOperand(0)});
}
- 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 +2615,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 +2671,7 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) {
return MulY;
}
- return Ret;
+ return nullptr;
}
// sqrt(exp(X)) -> exp(X * 0.5)
@@ -2797,13 +2813,13 @@ Value *LibCallSimplifier::optimizeSqrt(CallInst *CI, IRBuilderBase &B) {
}
Value *LibCallSimplifier::optimizeFMod(CallInst *CI, IRBuilderBase &B) {
- SimplifyQuery SQ(DL, TLI, DT, AC, CI, true, true, DC);
// fmod(x,y) can set errno if y == 0 or x == +/-inf, and returns Nan in those
// case. If we know those do not happen, then we can convert the fmod into
// frem.
bool IsNoNan = CI->hasNoNaNs();
if (!IsNoNan) {
+ SimplifyQuery SQ(DL, TLI, DT, AC, CI, true, true, DC);
KnownFPClass Known0 = computeKnownFPClass(CI->getOperand(0), fcInf,
/*Depth=*/0, SQ);
if (Known0.isKnownNeverInfinity()) {
@@ -2811,8 +2827,7 @@ Value *LibCallSimplifier::optimizeFMod(CallInst *CI, IRBuilderBase &B) {
computeKnownFPClass(CI->getOperand(1), fcZero | fcSubnormal,
/*Depth=*/0, SQ);
Function *F = CI->getParent()->getParent();
- if (Known1.isKnownNeverLogicalZero(*F, CI->getType()))
- IsNoNan = true;
+ IsNoNan = Known1.isKnownNeverLogicalZero(*F, CI->getType());
}
}
diff --git a/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll b/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll
index 85c9a01e5fabab..c13a01bb9d4890 100644
--- a/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll
+++ b/llvm/test/Transforms/InstCombine/double-float-shrink-1.ll
@@ -249,10 +249,10 @@ define double @exp10_test2(float %f) {
define float @log_test1(float %f) {
; CHECK-LABEL: @log_test1(
-; LINUX-NEXT: [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]])
+; LINUX-NEXT: [[LOGF:%.*]] = call fast float @llvm.log.f32(float [[F:%.*]])
; LINUX-NEXT: ret float [[LOGF]]
-; MS32: [[LOGF:%.*]] = call fast double @log(double [[F:%.*]])
-; MS64-NEXT: [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]])
+; MS32: [[LOGF:%.*]] = call fast double @llvm.log.f64(double [[F:%.*]])
+; MS64-NEXT: [[LOGF:%.*]] = call fast float @llvm.log.f32(float [[F:%.*]])
;
%conv = fpext float %f to double
%call = call fast double @log(double %conv)
@@ -263,7 +263,7 @@ define float @log_test1(float %f) {
define double @log_test2(float %f) {
; CHECK-LABEL: @log_test2(
; CHECK-NEXT: [[CONV:%.*]] = fpext float [[F:%.*]] to double
-; CHECK-NEXT: [[CALL:%.*]] = call fast double @log(double [[CONV]])
+; CHECK-NEXT: [[CALL:%.*]] = call fast double @llvm.log.f64(double [[CONV]])
; CHECK-NEXT: ret double [[CALL]]
;
%conv = fpext float %f to double
@@ -273,10 +273,10 @@ define double @log_test2(float %f) {
define float @log10_test1(float %f) {
; CHECK-LABEL: @log10_test1(
-; LINUX-NEXT: [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]])
+; LINUX-NEXT: [[LOG10F:%.*]] = call fast float @llvm.log10.f32(float [[F:%.*]])
; LINUX-NEXT: ret float [[LOG10F]]
-; MS32: [[LOG10F:%.*]] = call fast double @log10(double [[F:%.*]])
-; MS64-NEXT: [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]])
+; MS32: [[LOG10F:%.*]] = call fast double @llvm.log10.f64(double [[F:%.*]])
+; MS64-NEXT: [[LOG10F:%.*]] = call fast float @llvm.log10.f32(float [[F:%.*]])
;
%conv = fpext float %f to double
%call = call fast double @log10(double %conv)
@@ -287,7 +287,7 @@ define float @log10_test1(float %f) {
define double @log10_test2(float %f) {
; CHECK-LABEL: @log10_test2(
; CHECK-NEXT: [[CONV:%.*]] = fpext float [[F:%.*]] to double
-; CHECK-NEXT: [[CALL:%.*]] = call fast double @log10(double [[CONV]])
+; CHECK-NEXT: [[CALL:%.*]] = call fast double @llvm.log10.f64(double [[CONV]])
; CHECK-NEXT: ret double [[CALL]]
;
%conv = fpext float %f to double
@@ -320,7 +320,7 @@ define double @log1p_test2(float %f) {
define float @log2_test1(float %f) {
; CHECK-LABEL: @log2_test1(
-; ISC99-NEXT: [[LOG2F:%.*]] = call fast float @log2f(float [[F:%.*]])
+; ISC99-NEXT: [[LOG2F:%.*]] = call fast float @llvm.log2.f32(float [[F:%.*]])
; ISC99-NEXT: ret float [[LOG2F]]
; ISC89: [[LOG2F:%.*]] = call fast double @log2(double [[F:%.*]])
;
@@ -333,7 +333,8 @@ define float @log2_test1(float %f) {
define double @log2_test2(float %f) {
; CHECK-LABEL: @log2_test2(
; CHECK-NEXT: [[CONV:%.*]] = fpext float [[F:%.*]] to double
-; CHECK-NEXT: [[CALL:%.*]] = call fast double @log2(double [[CONV]])
+; ISC99-NEXT: [[CALL:%.*]] = call fast double @llvm.log2.f64(double [[CONV]])
+; ISC89-NEXT: [[LOG2F:%.*]] = call fast double @log2(double [[F:%.*]])
; CHECK-NEXT: ret double [[CALL]]
;
%conv = fpext float %f to double
diff --git a/llvm/test/Transforms/InstCombine/log-pow.ll b/llvm/test/Transforms/InstCombine/log-pow.ll
index b628e7cc57f15f..bfa636e470bb45 100644
--- a/llvm/test/Transforms/InstCombine/log-pow.ll
+++ b/llvm/test/Transforms/InstCombine/log-pow.ll
@@ -73,7 +73,7 @@ define float @logf_powfi_nonconst(float %x, i32 %y) {
define double @log_powi_not_fast(double %x, i32 %y) {
; CHECK-LABEL: @log_powi_not_fast(
; CHECK-NEXT: [[POW:%.*]] = call double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]])
-; CHECK-NEXT: [[LOG:%.*]] = call fast double @log(double [[POW]])
+; CHECK-NEXT: [[LOG:%.*]] = call fast double @llvm.log.f64(double [[POW]])
; CHECK-NEXT: ret double [[LOG]]
;
%pow = call double @llvm.powi.f64.i32(double %x, i32 %y)
@@ -106,7 +106,7 @@ define <2 x double> @log2v_powv(<2 x double> %x, <2 x double> %y) {
define double @log_pow_not_fast(double %x, double %y) {
; CHECK-LABEL: @log_pow_not_fast(
; CHECK-NEXT: [[POW:%.*]] = call double @pow(double [[X:%.*]], double [[Y:%.*]])
-; CHECK-NEXT: [[LOG:%.*]] = call fast double @log(double [[POW]])
+; CHECK-NEXT: [[LOG:%.*]] = call fast double @llvm.log.f64(double [[POW]])
; CHECK-NEXT: ret double [[LOG]]
;
%pow = call double @pow(double %x, double %y)
@@ -158,7 +158,7 @@ define float @log2f_exp10f(float %x) {
define double @log_exp2_not_fast(double %x) {
; CHECK-LABEL: @log_exp2_not_fast(
; CHECK-NEXT: [[EXP:%.*]] = call double @exp2(double [[X:%.*]])
-; CHECK-NEXT: [[LOG:%.*]] = call fast double @log(double [[EXP]])
+; CHECK-NEXT: [[LOG:%.*]] = call fast double @llvm.log.f64(double [[EXP]])
; CHECK-NEXT: ret double [[LOG]]
;
%exp = call double @exp2(double %x)
diff --git a/llvm/test/Transforms/InstCombine/log-to-intrinsic.ll b/llvm/test/Transforms/InstCombine/log-to-intrinsic.ll
new file mode 100644
index 00000000000000..3ee91f4edf50f5
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/log-to-intrinsic.ll
@@ -0,0 +1,279 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+define float @test_logf_pos(float %f) {
+; CHECK-LABEL: define float @test_logf_pos(
+; CHECK-SAME: float [[F:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt float [[F]], 0.000000e+00
+; CHECK-NEXT: br i1 [[ISINF]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.log.f32(float [[F]])
+; CHECK-NEXT: ret float [[CALL]]
+; CHECK: return:
+; CHECK-NEXT: ret float 0.000000e+00
+;
+entry:
+ %isinf = fcmp ole float %f, 0x0000000000000000
+ br i1 %isinf, label %return, label %if.end
+
+if.end:
+ %call = tail call float @logf(float %f)
+ ret float %call
+
+return:
+ ret float 0.0
+}
+
+define double @test_log_pos(double %f) {
+; CHECK-LABEL: define double @test_log_pos(
+; CHECK-SAME: double [[F:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt double [[F]], 0.000000e+00
+; CHECK-NEXT: br i1 [[ISINF]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.log.f64(double [[F]])
+; CHECK-NEXT: ret double [[CALL]]
+; CHECK: return:
+; CHECK-NEXT: ret double 0.000000e+00
+;
+entry:
+ %isinf = fcmp ole double %f, 0x0000000000000000
+ br i1 %isinf, label %return, label %if.end
+
+if.end:
+ %call = tail call double @log(double %f)
+ ret double %call
+
+return:
+ ret double 0.0
+}
+
+define fp128 @test_logl_pos(fp128 %f) {
+; CHECK-LABEL: define fp128 @test_logl_pos(
+; CHECK-SAME: fp128 [[F:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt fp128 [[F]], 0xL00000000000000000000000000000000
+; CHECK-NEXT: br i1 [[ISINF]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[CALL:%.*]] = call fp128 @llvm.log.f128(fp128 [[F]])
+; CHECK-NEXT: ret fp128 [[CALL]]
+; CHECK: return:
+; CHECK-NEXT: ret fp128 0xL00000000000000000000000000000000
+;
+entry:
+ %isinf = fcmp ole fp128 %f, 0xL00000000000000000000000000000000
+ br i1 %isinf, label %return, label %if.end
+
+if.end:
+ %call = tail call fp128 @logl(fp128 %f)
+ ret fp128 %call
+
+return:
+ ret fp128 0xL00000000000000000000000000000000
+}
+
+define float @test_log10f_pos(float %f) {
+; CHECK-LABEL: define float @test_log10f_pos(
+; CHECK-SAME: float [[F:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt float [[F]], 0.000000e+00
+; CHECK-NEXT: br i1 [[ISINF]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.log10.f32(float [[F]])
+; CHECK-NEXT: ret float [[CALL]]
+; CHECK: return:
+; CHECK-NEXT: ret float 0.000000e+00
+;
+entry:
+ %isinf = fcmp ole float %f, 0x0000000000000000
+ br i1 %isinf, label %return, label %if.end
+
+if.end:
+ %call = tail call float @log10f(float %f)
+ ret float %call
+
+return:
+ ret float 0.0
+}
+
+define double @test_log10_pos(double %f) {
+; CHECK-LABEL: define double @test_log10_pos(
+; CHECK-SAME: double [[F:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt double [[F]], 0.000000e+00
+; CHECK-NEXT: br i1 [[ISINF]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.log10.f64(double [[F]])
+; CHECK-NEXT: ret double [[CALL]]
+; CHECK: return:
+; CHECK-NEXT: ret double 0.000000e+00
+;
+entry:
+ %isinf = fcmp ole double %f, 0x0000000000000000
+ br i1 %isinf, label %return, label %if.end
+
+if.end:
+ %call = tail call double @log10(double %f)
+ ret double %call
+
+return:
+ ret double 0.0
+}
+
+define fp128 @test_log10l_pos(fp128 %f) {
+; CHECK-LABEL: define fp128 @test_log10l_pos(
+; CHECK-SAME: fp128 [[F:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt fp128 [[F]], 0xL00000000000000000000000000000000
+; CHECK-NEXT: br i1 [[ISINF]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[CALL:%.*]] = call fp128 @llvm.log10.f128(fp128 [[F]])
+; CHECK-NEXT: ret fp128 [[CALL]]
+; CHECK: return:
+; CHECK-NEXT: ret fp128 0xL00000000000000000000000000000000
+;
+entry:
+ %isinf = fcmp ole fp128 %f, 0xL00000000000000000000000000000000
+ br i1 %isinf, label %return, label %if.end
+
+if.end:
+ %call = tail call fp128 @log10l(fp128 %f)
+ ret fp128 %call
+
+return:
+ ret fp128 0xL00000000000000000000000000000000
+}
+
+define float @test_log2f_pos(float %f) {
+; CHECK-LABEL: define float @test_log2f_pos(
+; CHECK-SAME: float [[F:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt float [[F]], 0.000000e+00
+; CHECK-NEXT: br i1 [[ISINF]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.log2.f32(float [[F]])
+; CHECK-NEXT: ret float [[CALL]]
+; CHECK: return:
+; CHECK-NEXT: ret float 0.000000e+00
+;
+entry:
+ %isinf = fcmp ole float %f, 0x0000000000000000
+ br i1 %isinf, label %return, label %if.end
+
+if.end:
+ %call = tail call float @log2f(float %f)
+ ret float %call
+
+return:
+ ret float 0.0
+}
+
+define double @test_log2_pos(double %f) {
+; CHECK-LABEL: define double @test_log2_pos(
+; CHECK-SAME: double [[F:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt double [[F]], 0.000000e+00
+; CHECK-NEXT: br i1 [[ISINF]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.log2.f64(double [[F]])
+; CHECK-NEXT: ret double [[CALL]]
+; CHECK: return:
+; CHECK-NEXT: ret double 0.000000e+00
+;
+entry:
+ %isinf = fcmp ole double %f, 0x0000000000000000
+ br i1 %isinf, label %return, label %if.end
+
+if.end:
+ %call = tail call double @log2(double %f)
+ ret double %call
+
+return:
+ ret double 0.0
+}
+
+define fp128 @test_log2l_pos(fp128 %f) {
+; CHECK-LABEL: define fp128 @test_log2l_pos(
+; CHECK-SAME: fp128 [[F:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt fp128 [[F]], 0xL00000000000000000000000000000000
+; CHECK-NEXT: br i1 [[ISINF]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[CALL:%.*]] = call fp128 @llvm.log2.f128(fp128 [[F]])
+; CHECK-NEXT: ret fp128 [[CALL]]
+; CHECK: return:
+; CHECK-NEXT: ret fp128 0xL00000000000000000000000000000000
+;
+entry:
+ %isinf = fcmp ole fp128 %f, 0xL00000000000000000000000000000000
+ br i1 %isinf, label %return, label %if.end
+
+if.end:
+ %call = tail call fp128 @log2l(fp128 %f)
+ ret fp128 %call
+
+return:
+ ret fp128 0xL00000000000000000000000000000000
+}
+
+
+define double @test_logb_pos(double %f) {
+; CHECK-LABEL: define double @test_logb_pos(
+; CHECK-SAME: double [[F:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt double [[F]], 0.000000e+00
+; CHECK-NEXT: br i1 [[ISINF]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[CALL:%.*]] = tail call double @logb(double [[F]])
+; CHECK-NEXT: ret double [[CALL]]
+; CHECK: return:
+; CHECK-NEXT: ret double 0.000000e+00
+;
+entry:
+ %isinf = fcmp ole double %f, 0x0000000000000000
+ br i1 %isinf, label %return, label %if.end
+
+if.end:
+ %call = tail call double @logb(double %f)
+ ret double %call
+
+return:
+ ret double 0.0
+}
+
+define double @test_log1p_pos(double %f) {
+; CHECK-LABEL: define double @test_log1p_pos(
+; CHECK-SAME: double [[F:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt double [[F]], 0.000000e+00
+; CHECK-NEXT: br i1 [[ISINF]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[CALL:%.*]] = tail call double @log1p(double [[F]])
+; CHECK-NEXT: ret double [[CALL]]
+; CHECK: return:
+; CHECK-NEXT: ret double 0.000000e+00
+;
+entry:
+ %isinf = fcmp ole double %f, 0x0000000000000000
+ br i1 %isinf, label %return, label %if.end
+
+if.end:
+ %call = tail call double @log1p(double %f)
+ ret double %call
+
+return:
+ ret double 0.0
+}
+
+declare double @log(double)
+declare float @logf(float)
+declare fp128 @logl(fp128)
+declare double @log10(double)
+declare float @log10f(float)
+declare fp128 @log10l(fp128)
+declare double @log2(double)
+declare float @log2f(float)
+declare fp128 @log2l(fp128)
+declare double @logb(double)
+declare double @log1p(double)
|
493cea5
to
41ded02
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm with nits
Function *F = Log->getParent()->getParent(); | ||
IsKnownNoErrno = Known.isKnownNeverLogicalZero(*F, Ty) && | ||
Known.cannotBeOrderedLessThanZero(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function *F = Log->getParent()->getParent(); | |
IsKnownNoErrno = Known.isKnownNeverLogicalZero(*F, Ty) && | |
Known.cannotBeOrderedLessThanZero(); | |
Function *F = Log->getParent()->getParent(); | |
IsKnownNoErrno = Known.cannotBeOrderedLessThanZero() && | |
Known.isKnownNeverLogicalZero(*F, Ty); |
Similar to 112aac4, 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.
41ded02
to
1268da3
Compare
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/139/builds/4826 Here is the relevant piece of the build log for the reference
|
…e. (llvm#111428) Similar to 112aac4, 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.
Similar to 112aac4, 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.