#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 */
typedef int /*<<< orphan*/ places_max;

/* Variables and functions */
intptr_t abs_value(intptr_t);
intptr_t count_places(intptr_t num) {
  static intptr_t const places_max[] = {
      9,
      99,
      999,
      9999,
      99999,
      999999,
      9999999,
      99999999,
      999999999,
      9999999999,
      99999999999,
      999999999999,
      9999999999999,
      99999999999999,
      999999999999999,
      9999999999999999,
      99999999999999999,
      999999999999999999,
  };
  intptr_t rslt = 0;
  intptr_t start = 0;
  intptr_t middle = 0;
  intptr_t end = (sizeof(places_max) / sizeof(places_max[0]));
  intptr_t positive = 0;
  if (((intptr_t) ~(~(uintptr_t)0 >> 1)) == num) {
    positive = abs_value(num + 1);
  } else {
    positive = abs_value(num);
  }
  while (start < end) {
    middle = start + (end - start) / 2;
    if (positive <= places_max[middle]) {
      rslt = middle + 1;
      end = middle;
    } else {
      rslt = middle + 2;
      start = middle + 1;
    }
  }
  if (num < 0) {
    ++rslt;
  }
  return rslt;
}


x86 assembly (clang, -O0):
<count_places>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
movq   $0x0,-0x10(%rbp)
movq   $0x0,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
movq   $0x12,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
movabs $0x8000000000000000,%rax
cmp    -0x8(%rbp),%rax
jne    116e <count_places+0x5e>
mov    -0x8(%rbp),%rdi
add    $0x1,%rdi
call   1030 <abs_value@plt>
mov    %rax,-0x30(%rbp)
jmp    117b <count_places+0x6b>
mov    -0x8(%rbp),%rdi
call   1030 <abs_value@plt>
mov    %rax,-0x30(%rbp)
jmp    1180 <count_places+0x70>
mov    -0x18(%rbp),%rax
cmp    -0x28(%rbp),%rax
jge    1205 <count_places+0xf5>
mov    -0x18(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x28(%rbp),%rax
sub    -0x18(%rbp),%rax
mov    $0x2,%ecx
cqto
idiv   %rcx
mov    %rax,%rcx
mov    -0x38(%rbp),%rax
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x30(%rbp),%rax
mov    -0x20(%rbp),%rdx
lea    0xe3b(%rip),%rcx
cmp    (%rcx,%rdx,8),%rax
jg     11e8 <count_places+0xd8>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x28(%rbp)
jmp    1200 <count_places+0xf0>
mov    -0x20(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x10(%rbp)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    1180 <count_places+0x70>
cmpq   $0x0,-0x8(%rbp)
jge    121c <count_places+0x10c>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<count_places>:
push   %r14
push   %rbx
push   %rax
mov    %rdi,%r14
movabs $0x8000000000000000,%rax
lea    0x1(%rax),%rdi
cmp    %rax,%r14
cmovne %r14,%rdi
call   1030 <abs_value@plt>
mov    $0x12,%ebx
xor    %esi,%esi
lea    0xec1(%rip),%r8
jmp    1158 <count_places+0x48>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    %rdi,%rsi
cmp    %rdi,%rbx
jle    118b <count_places+0x7b>
mov    %rbx,%rcx
sub    %rsi,%rcx
mov    %rcx,%rdi
shr    $0x3f,%rdi
add    %rcx,%rdi
sar    %rdi
lea    (%rdi,%rsi,1),%rcx
mov    (%r8,%rcx,8),%rdx
lea    (%rdi,%rsi,1),%r9
add    $0x1,%r9
mov    %r9,%rdi
cmp    %rdx,%rax
jg     1150 <count_places+0x40>
mov    %rsi,%rdi
mov    %rcx,%rbx
jmp    1150 <count_places+0x40>
add    $0x2,%rcx
cmp    %rdx,%rax
cmovg  %rcx,%r9
shr    $0x3f,%r14
add    %r9,%r14
mov    %r14,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
@count_places.places_max = internal constant [18 x i64] [i64 9, i64 99, i64 999, i64 9999, i64 99999, i64 999999, i64 9999999, i64 99999999, i64 999999999, i64 9999999999, i64 99999999999, i64 999999999999, i64 9999999999999, i64 99999999999999, i64 999999999999999, i64 9999999999999999, i64 99999999999999999, i64 999999999999999999]
define i64 @count_places(i64 %0) {
%2 = alloca i64
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
%6 = alloca i64
%7 = alloca i64
store i64 %0, i64* %2
store i64 0, i64* %3
store i64 0, i64* %4
store i64 0, i64* %5
store i64 18, i64* %6
store i64 0, i64* %7
%8 = load i64, i64* %2
%9 = icmp eq i64 -9223372036854775808, %8
br i1 %9, label %10, label %14
10: ; preds = %1
%11 = load i64, i64* %2
%12 = add nsw i64 %11, 1
%13 = call i64 @abs_value(i64 %12)
store i64 %13, i64* %7
br label %17
14: ; preds = %1
%15 = load i64, i64* %2
%16 = call i64 @abs_value(i64 %15)
store i64 %16, i64* %7
br label %17
17: ; preds = %14, %10
br label %18
18: ; preds = %43, %17
%19 = load i64, i64* %4
%20 = load i64, i64* %6
%21 = icmp slt i64 %19, %20
br i1 %21, label %22, label %44
22: ; preds = %18
%23 = load i64, i64* %4
%24 = load i64, i64* %6
%25 = load i64, i64* %4
%26 = sub nsw i64 %24, %25
%27 = sdiv i64 %26, 2
%28 = add nsw i64 %23, %27
store i64 %28, i64* %5
%29 = load i64, i64* %7
%30 = load i64, i64* %5
%31 = getelementptr inbounds [18 x i64], [18 x i64]* @count_places.places_max, i64 0, i64 %30
%32 = load i64, i64* %31
%33 = icmp sle i64 %29, %32
br i1 %33, label %34, label %38
34: ; preds = %22
%35 = load i64, i64* %5
%36 = add nsw i64 %35, 1
store i64 %36, i64* %3
%37 = load i64, i64* %5
store i64 %37, i64* %6
br label %43
38: ; preds = %22
%39 = load i64, i64* %5
%40 = add nsw i64 %39, 2
store i64 %40, i64* %3
%41 = load i64, i64* %5
%42 = add nsw i64 %41, 1
store i64 %42, i64* %4
br label %43
43: ; preds = %38, %34
br label %18
44: ; preds = %18
%45 = load i64, i64* %2
%46 = icmp slt i64 %45, 0
br i1 %46, label %47, label %50
47: ; preds = %44
%48 = load i64, i64* %3
%49 = add nsw i64 %48, 1
store i64 %49, i64* %3
br label %50
50: ; preds = %47, %44
%51 = load i64, i64* %3
ret i64 %51
}

LLVM IR (-O2):
@count_places.places_max = internal unnamed_addr constant [18 x i64] [i64 9, i64 99, i64 999, i64 9999, i64 99999, i64 999999, i64 9999999, i64 99999999, i64 999999999, i64 9999999999, i64 99999999999, i64 999999999999, i64 9999999999999, i64 99999999999999, i64 999999999999999, i64 9999999999999999, i64 99999999999999999, i64 999999999999999999]
define i64 @count_places(i64 %0) {
%2 = icmp eq i64 %0, -9223372036854775808
%3 = select i1 %2, i64 -9223372036854775807, i64 %0
%4 = tail call i64 @abs_value(i64 %3)
br label %5
5: ; preds = %1, %5
%6 = phi i64 [ 18, %1 ], [ %16, %5 ]
%7 = phi i64 [ 0, %1 ], [ %15, %5 ]
%8 = sub nsw i64 %6, %7
%9 = sdiv i64 %8, 2
%10 = add nsw i64 %9, %7
%11 = getelementptr inbounds [18 x i64], [18 x i64]* @count_places.places_max, i64 0, i64 %10
%12 = load i64, i64* %11
%13 = icmp sgt i64 %4, %12
%14 = add nsw i64 %10, 1
%15 = select i1 %13, i64 %14, i64 %7
%16 = select i1 %13, i64 %6, i64 %10
%17 = icmp sgt i64 %16, %15
br i1 %17, label %5, label %18
18: ; preds = %5
%19 = add nsw i64 %10, 2
%20 = select i1 %13, i64 %19, i64 %14
%21 = lshr i64 %0, 63
%22 = add nsw i64 %20, %21
ret i64 %22
}