#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;
double HUGE_VAL;
int /*<<< orphan*/ errno;
double frexp(double, int *);
double log(double arg) {
  double x, z, zsq, temp;
  int exp;
  if (arg <= 0.0) {
    errno = EDOM;
    return -HUGE_VAL;
  }
  x = frexp(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):
<log>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x10(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jb     1169 <log+0x59>
mov    0x2eae(%rip),%rax
mov    (%rax),%ecx
mov    0x2e95(%rip),%rax
mov    %ecx,(%rax)
mov    0x2ea4(%rip),%rax
movsd  (%rax),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12a7 <log+0x197>
movsd  -0x10(%rbp),%xmm0
lea    -0x34(%rbp),%rdi
call   1030 <frexp@plt>
movsd  %xmm0,-0x18(%rbp)
movsd  0xe7c(%rip),%xmm0
ucomisd -0x18(%rbp),%xmm0
jbe    11aa <log+0x9a>
movsd  0xe71(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x34(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x34(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  0xe99(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  0xe8d(%rip),%xmm1
addsd  -0x18(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
mulsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  0xe53(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe4f(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x28(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe2a(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x28(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe0d(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  -0x28(%rbp),%xmm1
movsd  0xdea(%rip),%xmm2
addsd  %xmm2,%xmm1
movsd  -0x28(%rbp),%xmm2
mulsd  %xmm2,%xmm1
movsd  0xdcd(%rip),%xmm2
addsd  %xmm2,%xmm1
movsd  -0x28(%rbp),%xmm2
mulsd  %xmm2,%xmm1
movsd  0xdb0(%rip),%xmm2
addsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm2
cvtsi2sdl -0x34(%rbp),%xmm1
movsd  0xd84(%rip),%xmm3
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<log>:
push   %rax
xorpd  %xmm1,%xmm1
ucomisd %xmm0,%xmm1
jae    11cb <log+0xbb>
lea    0x4(%rsp),%rdi
call   1030 <frexp@plt>
movsd  0xeff(%rip),%xmm1
xor    %ecx,%ecx
ucomisd %xmm0,%xmm1
seta   %cl
mov    0x4(%rsp),%eax
jbe    1144 <log+0x34>
addsd  %xmm0,%xmm0
movsd  0xeec(%rip),%xmm1
addsd  %xmm0,%xmm1
addsd  0xee8(%rip),%xmm0
divsd  %xmm0,%xmm1
movapd %xmm1,%xmm2
mulsd  %xmm1,%xmm2
movsd  0xedc(%rip),%xmm0
mulsd  %xmm2,%xmm0
addsd  0xed8(%rip),%xmm0
movsd  0xed8(%rip),%xmm3
addsd  %xmm2,%xmm3
unpcklpd %xmm3,%xmm0
unpcklpd %xmm2,%xmm2
mulpd  %xmm2,%xmm0
addpd  0xe78(%rip),%xmm0
sub    %ecx,%eax
mulpd  %xmm2,%xmm0
addpd  0xe7a(%rip),%xmm0
movapd %xmm0,%xmm2
unpckhpd %xmm0,%xmm2
divsd  %xmm2,%xmm0
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
mulsd  0xe9f(%rip),%xmm2
mulsd  %xmm1,%xmm0
addsd  %xmm2,%xmm0
pop    %rax
ret
mov    0x2e0e(%rip),%rax
mov    (%rax),%eax
mov    0x2df5(%rip),%rcx
mov    %eax,(%rcx)
mov    0x2e04(%rip),%rax
movsd  (%rax),%xmm0
xorps  0xe11(%rip),%xmm0
pop    %rax
ret

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

LLVM IR (-O2):
@EDOM = global i32 0
@errno = global i32 0
@HUGE_VAL = global double 0.000000e+00
define double @log(double %0) {
%2 = alloca i32
%3 = bitcast i32* %2 to i8*
%4 = fcmp ugt double %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 double, double* @HUGE_VAL
%8 = fneg double %7
br label %35
9: ; preds = %1
%10 = call double @frexp(double %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)
br label %35
35: ; preds = %9, %5
%36 = phi double [ %8, %5 ], [ %34, %9 ]
ret double %36
}