[llvm] [InstCombine] Convert @log to @llvm.log if the input is known positive. (PR #111428)

via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 7 12:57:09 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: David Green (davemgreen)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/111428.diff


4 Files Affected:

- (modified) llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp (+32-17) 
- (modified) llvm/test/Transforms/InstCombine/double-float-shrink-1.ll (+11-10) 
- (modified) llvm/test/Transforms/InstCombine/log-pow.ll (+3-3) 
- (added) llvm/test/Transforms/InstCombine/log-to-intrinsic.ll (+279) 


``````````diff
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)

``````````

</details>


https://github.com/llvm/llvm-project/pull/111428


More information about the llvm-commits mailing list