#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ EDOM;
float HUGE_VALF;
int /*<<< orphan*/ errno;
double frexpf(float, int *);
float logf(float arg) {
  double x, z, zsq, temp;
  int exp;
  if (arg <= 0.0) {
    errno = EDOM;
    return -HUGE_VALF;
  }
  x = frexpf(arg, &exp);
  if (x < 0.707106781186548e0) {
    x *= 2;
    exp--;
  }
  z = (x - 1) / (x + 1);
  zsq = z * z;
  temp = ((0.421087371217980e0 * zsq + -0.963769093368687e1) * zsq +
          0.309572928215377e2) *
             zsq +
         -0.240139179559211e2;
  temp =
      temp /
      (((1.0 * zsq + -0.891110902798312e1) * zsq + 0.194809660700890e2) * zsq +
       -0.120069589779605e2);
  temp = temp * z + exp * 0.693147180559945e0;
  return temp;
}


x86 assembly (clang, -O0):
<logf>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movss  %xmm0,-0x8(%rbp)
movss  -0x8(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
xorps  %xmm0,%xmm0
ucomisd %xmm1,%xmm0
jb     1167 <logf+0x57>
mov    0x2ea6(%rip),%rax
mov    (%rax),%ecx
mov    0x2e8d(%rip),%rax
mov    %ecx,(%rax)
mov    0x2ea4(%rip),%rax
movss  (%rax),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    12a9 <logf+0x199>
movss  -0x8(%rbp),%xmm0
lea    -0x2c(%rbp),%rdi
call   1030 <frexpf@plt>
movsd  %xmm0,-0x10(%rbp)
movsd  0xe7e(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    11a8 <logf+0x98>
movsd  0xe73(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    -0x2c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x2c(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  0xe9b(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  0xe8f(%rip),%xmm1
addsd  -0x10(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xe55(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe51(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x20(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe2c(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x20(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe0f(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm1
movsd  0xdec(%rip),%xmm2
addsd  %xmm2,%xmm1
movsd  -0x20(%rbp),%xmm2
mulsd  %xmm2,%xmm1
movsd  0xdcf(%rip),%xmm2
addsd  %xmm2,%xmm1
movsd  -0x20(%rbp),%xmm2
mulsd  %xmm2,%xmm1
movsd  0xdb2(%rip),%xmm2
addsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm2
cvtsi2sdl -0x2c(%rbp),%xmm1
movsd  0xd86(%rip),%xmm3
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<logf>:
push   %rax
xorps  %xmm1,%xmm1
ucomiss %xmm0,%xmm1
jae    11d0 <logf+0xc0>
lea    0x4(%rsp),%rdi
call   1030 <frexpf@plt>
movsd  0xf01(%rip),%xmm1
xor    %ecx,%ecx
ucomisd %xmm0,%xmm1
seta   %cl
mov    0x4(%rsp),%eax
jbe    1142 <logf+0x32>
addsd  %xmm0,%xmm0
sub    %ecx,%eax
movsd  0xeec(%rip),%xmm1
addsd  %xmm0,%xmm1
addsd  0xee8(%rip),%xmm0
divsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
mulsd  %xmm1,%xmm0
movsd  0xedc(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xed8(%rip),%xmm2
movsd  0xed8(%rip),%xmm3
addsd  %xmm0,%xmm3
unpcklpd %xmm3,%xmm2
unpcklpd %xmm0,%xmm0
mulpd  %xmm0,%xmm2
addpd  0xe78(%rip),%xmm2
mulpd  %xmm0,%xmm2
addpd  0xe7c(%rip),%xmm2
movapd %xmm2,%xmm0
unpckhpd %xmm2,%xmm0
divsd  %xmm0,%xmm2
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
mulsd  0xea1(%rip),%xmm0
mulsd  %xmm1,%xmm2
addsd  %xmm0,%xmm2
xorps  %xmm0,%xmm0
cvtsd2ss %xmm2,%xmm0
pop    %rax
ret
mov    0x2e09(%rip),%rax
mov    (%rax),%eax
mov    0x2df0(%rip),%rcx
mov    %eax,(%rcx)
mov    0x2e07(%rip),%rax
movss  (%rax),%xmm0
xorps  0xe0c(%rip),%xmm0
pop    %rax
ret

LLVM IR (-O0):
@EDOM = global i32 0
@errno = global i32 0
@HUGE_VALF = global float 0.000000e+00
define float @logf(float %0) {
%2 = alloca float
%3 = alloca float
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca i32
store float %0, float* %3
%9 = load float, float* %3
%10 = fpext float %9 to double
%11 = fcmp ole double %10, 0.000000e+00
br i1 %11, label %12, label %16
12: ; preds = %1
%13 = load i32, i32* @EDOM
store i32 %13, i32* @errno
%14 = load float, float* @HUGE_VALF
%15 = fneg float %14
store float %15, float* %2
br label %57
16: ; preds = %1
%17 = load float, float* %3
%18 = call double @frexpf(float %17, i32* %8)
store double %18, double* %4
%19 = load double, double* %4
%20 = fcmp olt double %19, 0x3FE6A09E667F3BD1
br i1 %20, label %21, label %26
21: ; preds = %16
%22 = load double, double* %4
%23 = fmul double %22, 2.000000e+00
store double %23, double* %4
%24 = load i32, i32* %8
%25 = add nsw i32 %24, -1
store i32 %25, i32* %8
br label %26
26: ; preds = %21, %16
%27 = load double, double* %4
%28 = fsub double %27, 1.000000e+00
%29 = load double, double* %4
%30 = fadd double %29, 1.000000e+00
%31 = fdiv double %28, %30
store double %31, double* %5
%32 = load double, double* %5
%33 = load double, double* %5
%34 = fmul double %32, %33
store double %34, double* %6
%35 = load double, double* %6
%36 = call double @llvm.fmuladd.f64(double 0x3FDAF3187208F312, double %35, double 0xC023467F6D124818)
%37 = load double, double* %6
%38 = call double @llvm.fmuladd.f64(double %36, double %37, double 0x403EF51124713332)
%39 = load double, double* %6
%40 = call double @llvm.fmuladd.f64(double %38, double %39, double 0xC0380390208D8220)
store double %40, double* %7
%41 = load double, double* %7
%42 = load double, double* %6
%43 = call double @llvm.fmuladd.f64(double 1.000000e+00, double %42, double 0xC021D27CE1EC8E42)
%44 = load double, double* %6
%45 = call double @llvm.fmuladd.f64(double %43, double %44, double 0x40337B2097A58495)
%46 = load double, double* %6
%47 = call double @llvm.fmuladd.f64(double %45, double %46, double 0xC0280390208D8203)
%48 = fdiv double %41, %47
store double %48, double* %7
%49 = load double, double* %7
%50 = load double, double* %5
%51 = load i32, i32* %8
%52 = sitofp i32 %51 to double
%53 = fmul double %52, 0x3FE62E42FEFA39EC
%54 = call double @llvm.fmuladd.f64(double %49, double %50, double %53)
store double %54, double* %7
%55 = load double, double* %7
%56 = fptrunc double %55 to float
store float %56, float* %2
br label %57
57: ; preds = %26, %12
%58 = load float, float* %2
ret float %58
}

LLVM IR (-O2):
@EDOM = global i32 0
@errno = global i32 0
@HUGE_VALF = global float 0.000000e+00
define float @logf(float %0) {
%2 = alloca i32
%3 = bitcast i32* %2 to i8*
%4 = fcmp ugt float %0, 0.000000e+00
br i1 %4, label %9, label %5
5: ; preds = %1
%6 = load i32, i32* @EDOM
store i32 %6, i32* @errno
%7 = load float, float* @HUGE_VALF
%8 = fneg float %7
br label %36
9: ; preds = %1
%10 = call double @frexpf(float %0, i32* %2)
%11 = fcmp olt double %10, 0x3FE6A09E667F3BD1
%12 = fmul double %10, 2.000000e+00
%13 = load i32, i32* %2
%14 = sext i1 %11 to i32
%15 = add nsw i32 %13, %14
%16 = select i1 %11, double %12, double %10
%17 = fadd double %16, -1.000000e+00
%18 = fadd double %16, 1.000000e+00
%19 = fdiv double %17, %18
%20 = fmul double %19, %19
%21 = tail call double @llvm.fmuladd.f64(double %20, double 0x3FDAF3187208F312, double 0xC023467F6D124818)
%22 = fadd double %20, 0xC021D27CE1EC8E42
%23 = insertelement <2 x double> poison, double %21, i64 0
%24 = insertelement <2 x double> %23, double %22, i64 1
%25 = insertelement <2 x double> poison, double %20, i64 0
%26 = shufflevector <2 x double> %25, <2 x double> poison, <2 x i32> zeroinitializer
%27 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %24, <2 x double> %26, <2 x double> <double 0x403EF51124713332, double 0x40337B2097A58495>)
%28 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %27, <2 x double> %26, <2 x double> <double 0xC0380390208D8220, double 0xC0280390208D8203>)
%29 = extractelement <2 x double> %28, i64 0
%30 = extractelement <2 x double> %28, i64 1
%31 = fdiv double %29, %30
%32 = sitofp i32 %15 to double
%33 = fmul double %32, 0x3FE62E42FEFA39EC
%34 = tail call double @llvm.fmuladd.f64(double %31, double %19, double %33)
%35 = fptrunc double %34 to float
br label %36
36: ; preds = %9, %5
%37 = phi float [ %8, %5 ], [ %35, %9 ]
ret float %37
}