int dlog10(double v) {
  return (v >= 1000000000u)  ? 9
         : (v >= 100000000u) ? 8
         : (v >= 10000000u)  ? 7
         : (v >= 1000000u)   ? 6
         : (v >= 100000u)    ? 5
         : (v >= 10000u)     ? 4
         : (v >= 1000u)      ? 3
         : (v >= 100u)       ? 2
         : (v >= 10u)        ? 1u
                             : 0u;
}


x86 assembly (clang, -O0):
<dlog10>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  0xeea(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     112d <dlog10+0x2d>
mov    $0x9,%eax
mov    %eax,-0xc(%rbp)
jmp    1271 <dlog10+0x171>
movsd  -0x8(%rbp),%xmm0
movsd  0xece(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     1151 <dlog10+0x51>
mov    $0x8,%eax
mov    %eax,-0x10(%rbp)
jmp    126b <dlog10+0x16b>
movsd  -0x8(%rbp),%xmm0
movsd  0xeb2(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     1175 <dlog10+0x75>
mov    $0x7,%eax
mov    %eax,-0x14(%rbp)
jmp    1265 <dlog10+0x165>
movsd  -0x8(%rbp),%xmm0
movsd  0xe96(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     1199 <dlog10+0x99>
mov    $0x6,%eax
mov    %eax,-0x18(%rbp)
jmp    125f <dlog10+0x15f>
movsd  -0x8(%rbp),%xmm0
movsd  0xe7a(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     11bd <dlog10+0xbd>
mov    $0x5,%eax
mov    %eax,-0x1c(%rbp)
jmp    1259 <dlog10+0x159>
movsd  -0x8(%rbp),%xmm0
movsd  0xe5e(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     11e1 <dlog10+0xe1>
mov    $0x4,%eax
mov    %eax,-0x20(%rbp)
jmp    1253 <dlog10+0x153>
movsd  -0x8(%rbp),%xmm0
movsd  0xe42(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     1205 <dlog10+0x105>
mov    $0x3,%eax
mov    %eax,-0x24(%rbp)
jmp    124d <dlog10+0x14d>
movsd  -0x8(%rbp),%xmm0
movsd  0xe26(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     1229 <dlog10+0x129>
mov    $0x2,%eax
mov    %eax,-0x28(%rbp)
jmp    1247 <dlog10+0x147>
movsd  -0x8(%rbp),%xmm0
movsd  0xe0a(%rip),%xmm1
xor    %eax,%eax
mov    $0x1,%ecx
ucomisd %xmm1,%xmm0
cmovae %ecx,%eax
mov    %eax,-0x28(%rbp)
mov    -0x28(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    %eax,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0xc(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<dlog10>:
mov    $0x9,%eax
ucomisd 0xef3(%rip),%xmm0
jae    1185 <dlog10+0x85>
mov    $0x8,%eax
ucomisd 0xeec(%rip),%xmm0
jae    1185 <dlog10+0x85>
mov    $0x7,%eax
ucomisd 0xee5(%rip),%xmm0
jae    1185 <dlog10+0x85>
mov    $0x6,%eax
ucomisd 0xede(%rip),%xmm0
jae    1185 <dlog10+0x85>
mov    $0x5,%eax
ucomisd 0xed7(%rip),%xmm0
jae    1185 <dlog10+0x85>
mov    $0x4,%eax
ucomisd 0xed0(%rip),%xmm0
jae    1185 <dlog10+0x85>
mov    $0x3,%eax
ucomisd 0xec9(%rip),%xmm0
jae    1185 <dlog10+0x85>
mov    $0x2,%eax
ucomisd 0xec2(%rip),%xmm0
jae    1185 <dlog10+0x85>
xor    %eax,%eax
ucomisd 0xebe(%rip),%xmm0
setae  %al
ret

LLVM IR (-O0):
define i32 @dlog10(double %0) {
%2 = alloca double
store double %0, double* %2
%3 = load double, double* %2
%4 = fcmp oge double %3, 1.000000e+09
br i1 %4, label %5, label %6
5: ; preds = %1
br label %53
6: ; preds = %1
%7 = load double, double* %2
%8 = fcmp oge double %7, 1.000000e+08
br i1 %8, label %9, label %10
9: ; preds = %6
br label %51
10: ; preds = %6
%11 = load double, double* %2
%12 = fcmp oge double %11, 1.000000e+07
br i1 %12, label %13, label %14
13: ; preds = %10
br label %49
14: ; preds = %10
%15 = load double, double* %2
%16 = fcmp oge double %15, 1.000000e+06
br i1 %16, label %17, label %18
17: ; preds = %14
br label %47
18: ; preds = %14
%19 = load double, double* %2
%20 = fcmp oge double %19, 1.000000e+05
br i1 %20, label %21, label %22
21: ; preds = %18
br label %45
22: ; preds = %18
%23 = load double, double* %2
%24 = fcmp oge double %23, 1.000000e+04
br i1 %24, label %25, label %26
25: ; preds = %22
br label %43
26: ; preds = %22
%27 = load double, double* %2
%28 = fcmp oge double %27, 1.000000e+03
br i1 %28, label %29, label %30
29: ; preds = %26
br label %41
30: ; preds = %26
%31 = load double, double* %2
%32 = fcmp oge double %31, 1.000000e+02
br i1 %32, label %33, label %34
33: ; preds = %30
br label %39
34: ; preds = %30
%35 = load double, double* %2
%36 = fcmp oge double %35, 1.000000e+01
%37 = zext i1 %36 to i64
%38 = select i1 %36, i32 1, i32 0
br label %39
39: ; preds = %34, %33
%40 = phi i32 [ 2, %33 ], [ %38, %34 ]
br label %41
41: ; preds = %39, %29
%42 = phi i32 [ 3, %29 ], [ %40, %39 ]
br label %43
43: ; preds = %41, %25
%44 = phi i32 [ 4, %25 ], [ %42, %41 ]
br label %45
45: ; preds = %43, %21
%46 = phi i32 [ 5, %21 ], [ %44, %43 ]
br label %47
47: ; preds = %45, %17
%48 = phi i32 [ 6, %17 ], [ %46, %45 ]
br label %49
49: ; preds = %47, %13
%50 = phi i32 [ 7, %13 ], [ %48, %47 ]
br label %51
51: ; preds = %49, %9
%52 = phi i32 [ 8, %9 ], [ %50, %49 ]
br label %53
53: ; preds = %51, %5
%54 = phi i32 [ 9, %5 ], [ %52, %51 ]
ret i32 %54
}

LLVM IR (-O2):
define i32 @dlog10(double %0) {
%2 = fcmp ult double %0, 1.000000e+09
br i1 %2, label %3, label %20
3: ; preds = %1
%4 = fcmp ult double %0, 1.000000e+08
br i1 %4, label %5, label %20
5: ; preds = %3
%6 = fcmp ult double %0, 1.000000e+07
br i1 %6, label %7, label %20
7: ; preds = %5
%8 = fcmp ult double %0, 1.000000e+06
br i1 %8, label %9, label %20
9: ; preds = %7
%10 = fcmp ult double %0, 1.000000e+05
br i1 %10, label %11, label %20
11: ; preds = %9
%12 = fcmp ult double %0, 1.000000e+04
br i1 %12, label %13, label %20
13: ; preds = %11
%14 = fcmp ult double %0, 1.000000e+03
br i1 %14, label %15, label %20
15: ; preds = %13
%16 = fcmp ult double %0, 1.000000e+02
br i1 %16, label %17, label %20
17: ; preds = %15
%18 = fcmp oge double %0, 1.000000e+01
%19 = zext i1 %18 to i32
br label %20
20: ; preds = %3, %7, %11, %17, %15, %13, %9, %5, %1
%21 = phi i32 [ 9, %1 ], [ 8, %3 ], [ 7, %5 ], [ 6, %7 ], [ 5, %9 ], [ 4, %11 ], [ 3, %13 ], [ %19, %17 ], [ 2, %15 ]
ret i32 %21
}