Skip to content

Commit 5184d76

Browse files
authored
[InstCombine] Convert @log to @llvm.log if the input is known positive. (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.
1 parent 54d3cf1 commit 5184d76

File tree

4 files changed

+56
-37
lines changed

4 files changed

+56
-37
lines changed

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2510,20 +2510,15 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) {
25102510
Intrinsic::ID LogID = LogFn->getIntrinsicID();
25112511
Module *Mod = Log->getModule();
25122512
Type *Ty = Log->getType();
2513-
Value *Ret = nullptr;
25142513

25152514
if (UnsafeFPShrink && hasFloatVersion(Mod, LogNm))
2516-
Ret = optimizeUnaryDoubleFP(Log, B, TLI, true);
2517-
2518-
// The earlier call must also be 'fast' in order to do these transforms.
2519-
CallInst *Arg = dyn_cast<CallInst>(Log->getArgOperand(0));
2520-
if (!Log->isFast() || !Arg || !Arg->isFast() || !Arg->hasOneUse())
2521-
return Ret;
2515+
if (Value *Ret = optimizeUnaryDoubleFP(Log, B, TLI, true))
2516+
return Ret;
25222517

25232518
LibFunc LogLb, ExpLb, Exp2Lb, Exp10Lb, PowLb;
25242519

25252520
// This is only applicable to log(), log2(), log10().
2526-
if (TLI->getLibFunc(LogNm, LogLb))
2521+
if (TLI->getLibFunc(LogNm, LogLb)) {
25272522
switch (LogLb) {
25282523
case LibFunc_logf:
25292524
LogID = Intrinsic::log;
@@ -2589,10 +2584,28 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) {
25892584
PowLb = LibFunc_powl;
25902585
break;
25912586
default:
2592-
return Ret;
2587+
return nullptr;
2588+
}
2589+
2590+
// Convert libcall to intrinsic if the value is known > 0.
2591+
bool IsKnownNoErrno = Log->hasNoNaNs() && Log->hasNoInfs();
2592+
if (!IsKnownNoErrno) {
2593+
SimplifyQuery SQ(DL, TLI, DT, AC, Log, true, true, DC);
2594+
KnownFPClass Known = computeKnownFPClass(
2595+
Log->getOperand(0),
2596+
KnownFPClass::OrderedLessThanZeroMask | fcSubnormal,
2597+
/*Depth=*/0, SQ);
2598+
Function *F = Log->getParent()->getParent();
2599+
IsKnownNoErrno = Known.cannotBeOrderedLessThanZero() &&
2600+
Known.isKnownNeverLogicalZero(*F, Ty);
2601+
}
2602+
if (IsKnownNoErrno) {
2603+
auto *NewLog = B.CreateUnaryIntrinsic(LogID, Log->getArgOperand(0), Log);
2604+
NewLog->copyMetadata(*Log);
2605+
return copyFlags(*Log, NewLog);
25932606
}
2594-
else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2595-
LogID == Intrinsic::log10) {
2607+
} else if (LogID == Intrinsic::log || LogID == Intrinsic::log2 ||
2608+
LogID == Intrinsic::log10) {
25962609
if (Ty->getScalarType()->isFloatTy()) {
25972610
ExpLb = LibFunc_expf;
25982611
Exp2Lb = LibFunc_exp2f;
@@ -2604,9 +2617,14 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) {
26042617
Exp10Lb = LibFunc_exp10;
26052618
PowLb = LibFunc_pow;
26062619
} else
2607-
return Ret;
2620+
return nullptr;
26082621
} else
2609-
return Ret;
2622+
return nullptr;
2623+
2624+
// The earlier call must also be 'fast' in order to do these transforms.
2625+
CallInst *Arg = dyn_cast<CallInst>(Log->getArgOperand(0));
2626+
if (!Log->isFast() || !Arg || !Arg->isFast() || !Arg->hasOneUse())
2627+
return nullptr;
26102628

26112629
IRBuilderBase::FastMathFlagGuard Guard(B);
26122630
B.setFastMathFlags(FastMathFlags::getFast());
@@ -2655,7 +2673,7 @@ Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) {
26552673
return MulY;
26562674
}
26572675

2658-
return Ret;
2676+
return nullptr;
26592677
}
26602678

26612679
// sqrt(exp(X)) -> exp(X * 0.5)

llvm/test/Transforms/InstCombine/double-float-shrink-1.ll

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,10 @@ define double @exp10_test2(float %f) {
249249

250250
define float @log_test1(float %f) {
251251
; CHECK-LABEL: @log_test1(
252-
; LINUX-NEXT: [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]])
252+
; LINUX-NEXT: [[LOGF:%.*]] = call fast float @llvm.log.f32(float [[F:%.*]])
253253
; LINUX-NEXT: ret float [[LOGF]]
254-
; MS32: [[LOGF:%.*]] = call fast double @log(double [[F:%.*]])
255-
; MS64-NEXT: [[LOGF:%.*]] = call fast float @logf(float [[F:%.*]])
254+
; MS32: [[LOGF:%.*]] = call fast double @llvm.log.f64(double [[F:%.*]])
255+
; MS64-NEXT: [[LOGF:%.*]] = call fast float @llvm.log.f32(float [[F:%.*]])
256256
;
257257
%conv = fpext float %f to double
258258
%call = call fast double @log(double %conv)
@@ -263,7 +263,7 @@ define float @log_test1(float %f) {
263263
define double @log_test2(float %f) {
264264
; CHECK-LABEL: @log_test2(
265265
; CHECK-NEXT: [[CONV:%.*]] = fpext float [[F:%.*]] to double
266-
; CHECK-NEXT: [[CALL:%.*]] = call fast double @log(double [[CONV]])
266+
; CHECK-NEXT: [[CALL:%.*]] = call fast double @llvm.log.f64(double [[CONV]])
267267
; CHECK-NEXT: ret double [[CALL]]
268268
;
269269
%conv = fpext float %f to double
@@ -273,10 +273,10 @@ define double @log_test2(float %f) {
273273

274274
define float @log10_test1(float %f) {
275275
; CHECK-LABEL: @log10_test1(
276-
; LINUX-NEXT: [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]])
276+
; LINUX-NEXT: [[LOG10F:%.*]] = call fast float @llvm.log10.f32(float [[F:%.*]])
277277
; LINUX-NEXT: ret float [[LOG10F]]
278-
; MS32: [[LOG10F:%.*]] = call fast double @log10(double [[F:%.*]])
279-
; MS64-NEXT: [[LOG10F:%.*]] = call fast float @log10f(float [[F:%.*]])
278+
; MS32: [[LOG10F:%.*]] = call fast double @llvm.log10.f64(double [[F:%.*]])
279+
; MS64-NEXT: [[LOG10F:%.*]] = call fast float @llvm.log10.f32(float [[F:%.*]])
280280
;
281281
%conv = fpext float %f to double
282282
%call = call fast double @log10(double %conv)
@@ -287,7 +287,7 @@ define float @log10_test1(float %f) {
287287
define double @log10_test2(float %f) {
288288
; CHECK-LABEL: @log10_test2(
289289
; CHECK-NEXT: [[CONV:%.*]] = fpext float [[F:%.*]] to double
290-
; CHECK-NEXT: [[CALL:%.*]] = call fast double @log10(double [[CONV]])
290+
; CHECK-NEXT: [[CALL:%.*]] = call fast double @llvm.log10.f64(double [[CONV]])
291291
; CHECK-NEXT: ret double [[CALL]]
292292
;
293293
%conv = fpext float %f to double
@@ -320,7 +320,7 @@ define double @log1p_test2(float %f) {
320320

321321
define float @log2_test1(float %f) {
322322
; CHECK-LABEL: @log2_test1(
323-
; ISC99-NEXT: [[LOG2F:%.*]] = call fast float @log2f(float [[F:%.*]])
323+
; ISC99-NEXT: [[LOG2F:%.*]] = call fast float @llvm.log2.f32(float [[F:%.*]])
324324
; ISC99-NEXT: ret float [[LOG2F]]
325325
; ISC89: [[LOG2F:%.*]] = call fast double @log2(double [[F:%.*]])
326326
;
@@ -333,7 +333,8 @@ define float @log2_test1(float %f) {
333333
define double @log2_test2(float %f) {
334334
; CHECK-LABEL: @log2_test2(
335335
; CHECK-NEXT: [[CONV:%.*]] = fpext float [[F:%.*]] to double
336-
; CHECK-NEXT: [[CALL:%.*]] = call fast double @log2(double [[CONV]])
336+
; ISC99-NEXT: [[CALL:%.*]] = call fast double @llvm.log2.f64(double [[CONV]])
337+
; ISC89-NEXT: [[LOG2F:%.*]] = call fast double @log2(double [[F:%.*]])
337338
; CHECK-NEXT: ret double [[CALL]]
338339
;
339340
%conv = fpext float %f to double

llvm/test/Transforms/InstCombine/log-pow.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ define float @logf_powfi_nonconst(float %x, i32 %y) {
7373
define double @log_powi_not_fast(double %x, i32 %y) {
7474
; CHECK-LABEL: @log_powi_not_fast(
7575
; CHECK-NEXT: [[POW:%.*]] = call double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]])
76-
; CHECK-NEXT: [[LOG:%.*]] = call fast double @log(double [[POW]])
76+
; CHECK-NEXT: [[LOG:%.*]] = call fast double @llvm.log.f64(double [[POW]])
7777
; CHECK-NEXT: ret double [[LOG]]
7878
;
7979
%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) {
106106
define double @log_pow_not_fast(double %x, double %y) {
107107
; CHECK-LABEL: @log_pow_not_fast(
108108
; CHECK-NEXT: [[POW:%.*]] = call double @pow(double [[X:%.*]], double [[Y:%.*]])
109-
; CHECK-NEXT: [[LOG:%.*]] = call fast double @log(double [[POW]])
109+
; CHECK-NEXT: [[LOG:%.*]] = call fast double @llvm.log.f64(double [[POW]])
110110
; CHECK-NEXT: ret double [[LOG]]
111111
;
112112
%pow = call double @pow(double %x, double %y)
@@ -158,7 +158,7 @@ define float @log2f_exp10f(float %x) {
158158
define double @log_exp2_not_fast(double %x) {
159159
; CHECK-LABEL: @log_exp2_not_fast(
160160
; CHECK-NEXT: [[EXP:%.*]] = call double @exp2(double [[X:%.*]])
161-
; CHECK-NEXT: [[LOG:%.*]] = call fast double @log(double [[EXP]])
161+
; CHECK-NEXT: [[LOG:%.*]] = call fast double @llvm.log.f64(double [[EXP]])
162162
; CHECK-NEXT: ret double [[LOG]]
163163
;
164164
%exp = call double @exp2(double %x)

llvm/test/Transforms/InstCombine/log-to-intrinsic.ll

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ define float @test_logf_pos(float %f) {
88
; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt float [[F]], 0.000000e+00
99
; CHECK-NEXT: br i1 [[ISINF]], label %[[IF_END:.*]], label %[[RETURN:.*]]
1010
; CHECK: [[IF_END]]:
11-
; CHECK-NEXT: [[CALL:%.*]] = tail call float @logf(float [[F]])
11+
; CHECK-NEXT: [[CALL:%.*]] = tail call float @llvm.log.f32(float [[F]])
1212
; CHECK-NEXT: ret float [[CALL]]
1313
; CHECK: [[RETURN]]:
1414
; CHECK-NEXT: ret float 0.000000e+00
@@ -32,7 +32,7 @@ define double @test_log_pos(double %f) {
3232
; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt double [[F]], 0.000000e+00
3333
; CHECK-NEXT: br i1 [[ISINF]], label %[[IF_END:.*]], label %[[RETURN:.*]]
3434
; CHECK: [[IF_END]]:
35-
; CHECK-NEXT: [[CALL:%.*]] = tail call double @log(double [[F]])
35+
; CHECK-NEXT: [[CALL:%.*]] = tail call double @llvm.log.f64(double [[F]])
3636
; CHECK-NEXT: ret double [[CALL]]
3737
; CHECK: [[RETURN]]:
3838
; CHECK-NEXT: ret double 0.000000e+00
@@ -56,7 +56,7 @@ define fp128 @test_logl_pos(fp128 %f) {
5656
; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt fp128 [[F]], 0xL00000000000000000000000000000000
5757
; CHECK-NEXT: br i1 [[ISINF]], label %[[IF_END:.*]], label %[[RETURN:.*]]
5858
; CHECK: [[IF_END]]:
59-
; CHECK-NEXT: [[CALL:%.*]] = tail call fp128 @logl(fp128 [[F]])
59+
; CHECK-NEXT: [[CALL:%.*]] = tail call fp128 @llvm.log.f128(fp128 [[F]])
6060
; CHECK-NEXT: ret fp128 [[CALL]]
6161
; CHECK: [[RETURN]]:
6262
; CHECK-NEXT: ret fp128 0xL00000000000000000000000000000000
@@ -80,7 +80,7 @@ define float @test_log10f_pos(float %f) {
8080
; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt float [[F]], 0.000000e+00
8181
; CHECK-NEXT: br i1 [[ISINF]], label %[[IF_END:.*]], label %[[RETURN:.*]]
8282
; CHECK: [[IF_END]]:
83-
; CHECK-NEXT: [[CALL:%.*]] = tail call float @log10f(float [[F]])
83+
; CHECK-NEXT: [[CALL:%.*]] = tail call float @llvm.log10.f32(float [[F]])
8484
; CHECK-NEXT: ret float [[CALL]]
8585
; CHECK: [[RETURN]]:
8686
; CHECK-NEXT: ret float 0.000000e+00
@@ -104,7 +104,7 @@ define double @test_log10_pos(double %f) {
104104
; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt double [[F]], 0.000000e+00
105105
; CHECK-NEXT: br i1 [[ISINF]], label %[[IF_END:.*]], label %[[RETURN:.*]]
106106
; CHECK: [[IF_END]]:
107-
; CHECK-NEXT: [[CALL:%.*]] = tail call double @log10(double [[F]])
107+
; CHECK-NEXT: [[CALL:%.*]] = tail call double @llvm.log10.f64(double [[F]])
108108
; CHECK-NEXT: ret double [[CALL]]
109109
; CHECK: [[RETURN]]:
110110
; CHECK-NEXT: ret double 0.000000e+00
@@ -128,7 +128,7 @@ define fp128 @test_log10l_pos(fp128 %f) {
128128
; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt fp128 [[F]], 0xL00000000000000000000000000000000
129129
; CHECK-NEXT: br i1 [[ISINF]], label %[[IF_END:.*]], label %[[RETURN:.*]]
130130
; CHECK: [[IF_END]]:
131-
; CHECK-NEXT: [[CALL:%.*]] = tail call fp128 @log10l(fp128 [[F]])
131+
; CHECK-NEXT: [[CALL:%.*]] = tail call fp128 @llvm.log10.f128(fp128 [[F]])
132132
; CHECK-NEXT: ret fp128 [[CALL]]
133133
; CHECK: [[RETURN]]:
134134
; CHECK-NEXT: ret fp128 0xL00000000000000000000000000000000
@@ -152,7 +152,7 @@ define float @test_log2f_pos(float %f) {
152152
; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt float [[F]], 0.000000e+00
153153
; CHECK-NEXT: br i1 [[ISINF]], label %[[IF_END:.*]], label %[[RETURN:.*]]
154154
; CHECK: [[IF_END]]:
155-
; CHECK-NEXT: [[CALL:%.*]] = tail call float @log2f(float [[F]])
155+
; CHECK-NEXT: [[CALL:%.*]] = tail call float @llvm.log2.f32(float [[F]])
156156
; CHECK-NEXT: ret float [[CALL]]
157157
; CHECK: [[RETURN]]:
158158
; CHECK-NEXT: ret float 0.000000e+00
@@ -176,7 +176,7 @@ define double @test_log2_pos(double %f) {
176176
; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt double [[F]], 0.000000e+00
177177
; CHECK-NEXT: br i1 [[ISINF]], label %[[IF_END:.*]], label %[[RETURN:.*]]
178178
; CHECK: [[IF_END]]:
179-
; CHECK-NEXT: [[CALL:%.*]] = tail call double @log2(double [[F]])
179+
; CHECK-NEXT: [[CALL:%.*]] = tail call double @llvm.log2.f64(double [[F]])
180180
; CHECK-NEXT: ret double [[CALL]]
181181
; CHECK: [[RETURN]]:
182182
; CHECK-NEXT: ret double 0.000000e+00
@@ -200,7 +200,7 @@ define fp128 @test_log2l_pos(fp128 %f) {
200200
; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt fp128 [[F]], 0xL00000000000000000000000000000000
201201
; CHECK-NEXT: br i1 [[ISINF]], label %[[IF_END:.*]], label %[[RETURN:.*]]
202202
; CHECK: [[IF_END]]:
203-
; CHECK-NEXT: [[CALL:%.*]] = tail call fp128 @log2l(fp128 [[F]])
203+
; CHECK-NEXT: [[CALL:%.*]] = tail call fp128 @llvm.log2.f128(fp128 [[F]])
204204
; CHECK-NEXT: ret fp128 [[CALL]]
205205
; CHECK: [[RETURN]]:
206206
; CHECK-NEXT: ret fp128 0xL00000000000000000000000000000000
@@ -273,7 +273,7 @@ define float @metadata(float %f) {
273273
; CHECK-NEXT: [[ISINF:%.*]] = fcmp ugt float [[F]], 0.000000e+00
274274
; CHECK-NEXT: br i1 [[ISINF]], label %[[IF_END:.*]], label %[[RETURN:.*]]
275275
; CHECK: [[IF_END]]:
276-
; CHECK-NEXT: [[CALL:%.*]] = tail call float @logf(float [[F]]), !fpmath [[META0:![0-9]+]]
276+
; CHECK-NEXT: [[CALL:%.*]] = tail call float @llvm.log.f32(float [[F]]), !fpmath [[META0:![0-9]+]]
277277
; CHECK-NEXT: ret float [[CALL]]
278278
; CHECK: [[RETURN]]:
279279
; CHECK-NEXT: ret float 0.000000e+00

0 commit comments

Comments
 (0)