double log10(double x) {
  double xi, y, q, q2;
  int ex;
  if (x <= 0.0)
    return (0.);
  ex = 0.0;
  xi = x;
  while (xi < 1.0) {
    xi *= 10.0;
    ex--;
  }
  while (xi > 10.0) {
    xi *= 0.1;
    ex++;
  }
  q = (xi - 3.16227766) / (xi + 3.16227766);
  q2 = q * q;
  y = ((((.191337714 * q2 + .094376476) * q2 + .177522071) * q2 + .289335524) *
           q2 +
       .868591718) *
          q +
      .5;
  y += (double)ex;
  return (y);
}


x86 assembly (clang, -O0):
<log10>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jb     1124 <log10+0x24>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1269 <log10+0x169>
movl   $0x0,-0x34(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xec3(%rip),%xmm0
ucomisd -0x18(%rbp),%xmm0
jbe    1168 <log10+0x68>
movsd  0xeb8(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x34(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x34(%rbp)
jmp    1135 <log10+0x35>
jmp    116d <log10+0x6d>
movsd  -0x18(%rbp),%xmm0
movsd  0xe8e(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11a4 <log10+0xa4>
movsd  0xebc(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    116d <log10+0x6d>
movsd  -0x18(%rbp),%xmm0
movsd  0xe8f(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  0xe83(%rip),%xmm1
addsd  -0x18(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  0xe49(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe45(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x30(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe20(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x30(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe03(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x30(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xde6(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  -0x28(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xdc9(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
cvtsi2sdl -0x34(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<log10>:
xorpd  %xmm1,%xmm1
ucomisd %xmm0,%xmm1
jae    11dc <log10+0xdc>
xor    %eax,%eax
movsd  0xee8(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    113d <log10+0x3d>
xor    %eax,%eax
movsd  0xee0(%rip),%xmm2
nopl   0x0(%rax,%rax,1)
mulsd  %xmm2,%xmm0
add    $0xffffffff,%eax
ucomisd %xmm0,%xmm1
ja     1130 <log10+0x30>
ucomisd 0xec3(%rip),%xmm0
jbe    116d <log10+0x6d>
movsd  0xec1(%rip),%xmm1
movsd  0xeb1(%rip),%xmm2
nopw   0x0(%rax,%rax,1)
mulsd  %xmm1,%xmm0
add    $0x1,%eax
ucomisd %xmm2,%xmm0
ja     1160 <log10+0x60>
movsd  0xea3(%rip),%xmm1
addsd  %xmm0,%xmm1
addsd  0xe9f(%rip),%xmm0
divsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
mulsd  %xmm1,%xmm0
movsd  0xe93(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xe8f(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xe8b(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xe87(%rip),%xmm2
mulsd  %xmm0,%xmm2
addsd  0xe83(%rip),%xmm2
mulsd  %xmm1,%xmm2
addsd  0xe7f(%rip),%xmm2
xorps  %xmm1,%xmm1
cvtsi2sd %eax,%xmm1
addsd  %xmm2,%xmm1
movapd %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @log10(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 %12
11: ; preds = %1
store double 0.000000e+00, double* %2
br label %55
12: ; preds = %1
store i32 0, i32* %8
%13 = load double, double* %3
store double %13, double* %4
br label %14
14: ; preds = %17, %12
%15 = load double, double* %4
%16 = fcmp olt double %15, 1.000000e+00
br i1 %16, label %17, label %22
17: ; preds = %14
%18 = load double, double* %4
%19 = fmul double %18, 1.000000e+01
store double %19, double* %4
%20 = load i32, i32* %8
%21 = add nsw i32 %20, -1
store i32 %21, i32* %8
br label %14
22: ; preds = %14
br label %23
23: ; preds = %26, %22
%24 = load double, double* %4
%25 = fcmp ogt double %24, 1.000000e+01
br i1 %25, label %26, label %31
26: ; preds = %23
%27 = load double, double* %4
%28 = fmul double %27, 1.000000e-01
store double %28, double* %4
%29 = load i32, i32* %8
%30 = add nsw i32 %29, 1
store i32 %30, i32* %8
br label %23
31: ; preds = %23
%32 = load double, double* %4
%33 = fsub double %32, 0x40094C583AD4923E
%34 = load double, double* %4
%35 = fadd double %34, 0x40094C583AD4923E
%36 = fdiv double %33, %35
store double %36, double* %6
%37 = load double, double* %6
%38 = load double, double* %6
%39 = fmul double %37, %38
store double %39, double* %7
%40 = load double, double* %7
%41 = call double @llvm.fmuladd.f64(double 0x3FC87DC1140F8A14, double %40, double 0x3FB8290E85EE85C9)
%42 = load double, double* %7
%43 = call double @llvm.fmuladd.f64(double %41, double %42, double 0x3FC6B90B10A1B036)
%44 = load double, double* %7
%45 = call double @llvm.fmuladd.f64(double %43, double %44, double 0x3FD284792549AA5D)
%46 = load double, double* %7
%47 = call double @llvm.fmuladd.f64(double %45, double %46, double 0x3FEBCB80DBCC5DD6)
%48 = load double, double* %6
%49 = call double @llvm.fmuladd.f64(double %47, double %48, double 5.000000e-01)
store double %49, double* %5
%50 = load i32, i32* %8
%51 = sitofp i32 %50 to double
%52 = load double, double* %5
%53 = fadd double %52, %51
store double %53, double* %5
%54 = load double, double* %5
store double %54, double* %2
br label %55
55: ; preds = %31, %11
%56 = load double, double* %2
ret double %56
}

LLVM IR (-O2):
define double @log10(double %0) {
%2 = fcmp ugt double %0, 0.000000e+00
br i1 %2, label %3, label %35
3: ; preds = %1
%4 = fcmp olt double %0, 1.000000e+00
br i1 %4, label %9, label %5
5: ; preds = %9, %3
%6 = phi double [ %0, %3 ], [ %12, %9 ]
%7 = phi i32 [ 0, %3 ], [ %13, %9 ]
%8 = fcmp ogt double %6, 1.000000e+01
br i1 %8, label %15, label %21
9: ; preds = %3, %9
%10 = phi i32 [ %13, %9 ], [ 0, %3 ]
%11 = phi double [ %12, %9 ], [ %0, %3 ]
%12 = fmul double %11, 1.000000e+01
%13 = add nsw i32 %10, -1
%14 = fcmp olt double %12, 1.000000e+00
br i1 %14, label %9, label %5
15: ; preds = %5, %15
%16 = phi i32 [ %19, %15 ], [ %7, %5 ]
%17 = phi double [ %18, %15 ], [ %6, %5 ]
%18 = fmul double %17, 1.000000e-01
%19 = add nsw i32 %16, 1
%20 = fcmp ogt double %18, 1.000000e+01
br i1 %20, label %15, label %21
21: ; preds = %15, %5
%22 = phi double [ %6, %5 ], [ %18, %15 ]
%23 = phi i32 [ %7, %5 ], [ %19, %15 ]
%24 = fadd double %22, 0xC0094C583AD4923E
%25 = fadd double %22, 0x40094C583AD4923E
%26 = fdiv double %24, %25
%27 = fmul double %26, %26
%28 = tail call double @llvm.fmuladd.f64(double %27, double 0x3FC87DC1140F8A14, double 0x3FB8290E85EE85C9)
%29 = tail call double @llvm.fmuladd.f64(double %28, double %27, double 0x3FC6B90B10A1B036)
%30 = tail call double @llvm.fmuladd.f64(double %29, double %27, double 0x3FD284792549AA5D)
%31 = tail call double @llvm.fmuladd.f64(double %30, double %27, double 0x3FEBCB80DBCC5DD6)
%32 = tail call double @llvm.fmuladd.f64(double %31, double %26, double 5.000000e-01)
%33 = sitofp i32 %23 to double
%34 = fadd double %32, %33
br label %35
35: ; preds = %1, %21
%36 = phi double [ %34, %21 ], [ 0.000000e+00, %1 ]
ret double %36
}