#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 */
char *malloc(int);
int /*<<< orphan*/ snprintf(char *, int, char *, long long, char *);
int /*<<< orphan*/ sprintf(char *, char *);
char *milliseconds_to_long_string(long long ms) {
  long long div;
  char *name;
  char *str = malloc(256);
  if (!str)
    return NULL;
  if (ms < (long long)1000) {
    sprintf(str, "less than one second");
    return str;
  }
  if (ms < 60 * (long long)1000) {
    name = "second";
    div = (long long)1000;
  } else if (ms < 60 * 60 * (long long)1000) {
    name = "minute";
    div = 60 * (long long)1000;
  } else if (ms < 24 * 60 * 60 * (long long)1000) {
    name = "hour";
    div = 60 * 60 * (long long)1000;
  } else if (ms < 7 * 24 * 60 * 60 * (long long)1000) {
    name = "day";
    div = 24 * 60 * 60 * (long long)1000;
  } else if (ms < 52 * 7 * 24 * 60 * 60 * (long long)1000) {
    name = "week";
    div = 7 * 24 * 60 * 60 * (long long)1000;
  } else {
    name = "year";
    div = 52 * 7 * 24 * 60 * 60 * (long long)1000;
  }
  long long val = ms / div;
  char *fmt = 1 == val ? "%lld %s" : "%lld %ss";
  snprintf(str, 256, fmt, val, name);
  return str;
}


x86 assembly (clang, -O0):
<milliseconds_to_long_string>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    $0x100,%edi
call   1040 <malloc@plt>
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
jne    1162 <milliseconds_to_long_string+0x32>
movq   $0x0,-0x8(%rbp)
jmp    12d0 <milliseconds_to_long_string+0x1a0>
cmpq   $0x3e8,-0x10(%rbp)
jge    118d <milliseconds_to_long_string+0x5d>
mov    -0x28(%rbp),%rdi
lea    0xe85(%rip),%rsi
call   1050 <sprintf@plt>
mov    -0x28(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    12d0 <milliseconds_to_long_string+0x1a0>
cmpq   $0xea60,-0x10(%rbp)
jge    11b3 <milliseconds_to_long_string+0x83>
lea    0xe6c(%rip),%rax
mov    %rax,-0x20(%rbp)
movq   $0x3e8,-0x18(%rbp)
jmp    127e <milliseconds_to_long_string+0x14e>
cmpq   $0x36ee80,-0x10(%rbp)
jge    11d9 <milliseconds_to_long_string+0xa9>
lea    0xe4d(%rip),%rax
mov    %rax,-0x20(%rbp)
movq   $0xea60,-0x18(%rbp)
jmp    1279 <milliseconds_to_long_string+0x149>
cmpq   $0x5265c00,-0x10(%rbp)
05
jge    11ff <milliseconds_to_long_string+0xcf>
lea    0xe2e(%rip),%rax
mov    %rax,-0x20(%rbp)
movq   $0x36ee80,-0x18(%rbp)
jmp    1274 <milliseconds_to_long_string+0x144>
cmpq   $0x240c8400,-0x10(%rbp)
24
jge    1225 <milliseconds_to_long_string+0xf5>
lea    0xe0d(%rip),%rax
mov    %rax,-0x20(%rbp)
movq   $0x5265c00,-0x18(%rbp)
05
jmp    126f <milliseconds_to_long_string+0x13f>
movabs $0x7528ad000,%rax
cmp    %rax,-0x10(%rbp)
jge    1251 <milliseconds_to_long_string+0x121>
lea    0xde5(%rip),%rax
mov    %rax,-0x20(%rbp)
movq   $0x240c8400,-0x18(%rbp)
24
jmp    126a <milliseconds_to_long_string+0x13a>
lea    0xdd2(%rip),%rax
mov    %rax,-0x20(%rbp)
movabs $0x7528ad000,%rax
mov    %rax,-0x18(%rbp)
jmp    126f <milliseconds_to_long_string+0x13f>
jmp    1274 <milliseconds_to_long_string+0x144>
jmp    1279 <milliseconds_to_long_string+0x149>
jmp    127e <milliseconds_to_long_string+0x14e>
mov    -0x10(%rbp),%rax
cqto
idivq  -0x18(%rbp)
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rsi
mov    $0x1,%edx
lea    0xd9b(%rip),%rax
lea    0xd8c(%rip),%rcx
cmp    %rsi,%rdx
cmove  %rcx,%rax
mov    %rax,-0x38(%rbp)
mov    -0x28(%rbp),%rdi
mov    -0x38(%rbp),%rdx
mov    -0x30(%rbp),%rcx
mov    -0x20(%rbp),%r8
mov    $0x100,%esi
call   1030 <snprintf@plt>
mov    -0x28(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<milliseconds_to_long_string>:
push   %r14
push   %rbx
push   %rax
mov    %rdi,%r14
mov    $0x100,%edi
call   1040 <malloc@plt>
mov    %rax,%rbx
test   %rax,%rax
je     1234 <milliseconds_to_long_string+0x114>
cmp    $0x3e7,%r14
jg     1163 <milliseconds_to_long_string+0x43>
movups 0xeb3(%rip),%xmm0
movups %xmm0,(%rbx)
movabs $0x646e6f63657320,%rax
mov    %rax,0xd(%rbx)
jmp    1234 <milliseconds_to_long_string+0x114>
cmp    $0xea60,%r14
jae    117a <milliseconds_to_long_string+0x5a>
mov    $0x3e8,%ecx
lea    0xe96(%rip),%r8
jmp    11f1 <milliseconds_to_long_string+0xd1>
cmp    $0x36ee80,%r14
jae    1191 <milliseconds_to_long_string+0x71>
mov    $0xea60,%ecx
lea    0xe86(%rip),%r8
jmp    11f1 <milliseconds_to_long_string+0xd1>
cmp    $0x5265c00,%r14
jae    11a8 <milliseconds_to_long_string+0x88>
mov    $0x36ee80,%ecx
lea    0xe76(%rip),%r8
jmp    11f1 <milliseconds_to_long_string+0xd1>
cmp    $0x240c8400,%r14
jae    11bf <milliseconds_to_long_string+0x9f>
mov    $0x5265c00,%ecx
lea    0xe64(%rip),%r8
jmp    11f1 <milliseconds_to_long_string+0xd1>
mov    %r14,%rax
shr    $0xc,%rax
cmp    $0x7528ad,%rax
lea    0xe52(%rip),%rax
lea    0xe50(%rip),%r8
cmovb  %rax,%r8
mov    $0x240c8400,%eax
movabs $0x7528ad000,%rcx
cmovb  %rax,%rcx
mov    %r14,%rax
or     %rcx,%rax
shr    $0x20,%rax
je     1207 <milliseconds_to_long_string+0xe7>
mov    %r14,%rax
xor    %edx,%edx
div    %rcx
jmp    120e <milliseconds_to_long_string+0xee>
mov    %r14d,%eax
xor    %edx,%edx
div    %ecx
cmp    $0x1,%rax
lea    0xe16(%rip),%rcx
lea    0xe17(%rip),%rdx
cmove  %rcx,%rdx
mov    %rbx,%rdi
mov    $0x100,%esi
mov    %rax,%rcx
call   1030 <snprintf@plt>
mov    %rbx,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
@.str = [21 x i8] c"less than one second\00"
@.str.1 = [7 x i8] c"second\00"
@.str.2 = [7 x i8] c"minute\00"
@.str.3 = [5 x i8] c"hour\00"
@.str.4 = [4 x i8] c"day\00"
@.str.5 = [5 x i8] c"week\00"
@.str.6 = [5 x i8] c"year\00"
@.str.7 = [8 x i8] c"%lld %s\00"
@.str.8 = [9 x i8] c"%lld %ss\00"
define i8* @milliseconds_to_long_string(i64 %0) {
%2 = alloca i8*
%3 = alloca i64
%4 = alloca i64
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i64
%8 = alloca i8*
store i64 %0, i64* %3
%9 = call i8* @malloc(i32 256)
store i8* %9, i8** %6
%10 = load i8*, i8** %6
%11 = icmp ne i8* %10, null
br i1 %11, label %13, label %12
12: ; preds = %1
store i8* null, i8** %2
br label %59
13: ; preds = %1
%14 = load i64, i64* %3
%15 = icmp slt i64 %14, 1000
br i1 %15, label %16, label %20
16: ; preds = %13
%17 = load i8*, i8** %6
%18 = call i32 @sprintf(i8* %17, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str, i64 0, i64 0))
%19 = load i8*, i8** %6
store i8* %19, i8** %2
br label %59
20: ; preds = %13
%21 = load i64, i64* %3
%22 = icmp slt i64 %21, 60000
br i1 %22, label %23, label %24
23: ; preds = %20
store i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i64 0, i64 0), i8** %5
store i64 1000, i64* %4
br label %45
24: ; preds = %20
%25 = load i64, i64* %3
%26 = icmp slt i64 %25, 3600000
br i1 %26, label %27, label %28
27: ; preds = %24
store i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.2, i64 0, i64 0), i8** %5
store i64 60000, i64* %4
br label %44
28: ; preds = %24
%29 = load i64, i64* %3
%30 = icmp slt i64 %29, 86400000
br i1 %30, label %31, label %32
31: ; preds = %28
store i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.3, i64 0, i64 0), i8** %5
store i64 3600000, i64* %4
br label %43
32: ; preds = %28
%33 = load i64, i64* %3
%34 = icmp slt i64 %33, 604800000
br i1 %34, label %35, label %36
35: ; preds = %32
store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i64 0, i64 0), i8** %5
store i64 86400000, i64* %4
br label %42
36: ; preds = %32
%37 = load i64, i64* %3
%38 = icmp slt i64 %37, 31449600000
br i1 %38, label %39, label %40
39: ; preds = %36
store i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.5, i64 0, i64 0), i8** %5
store i64 604800000, i64* %4
br label %41
40: ; preds = %36
store i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.6, i64 0, i64 0), i8** %5
store i64 31449600000, i64* %4
br label %41
41: ; preds = %40, %39
br label %42
42: ; preds = %41, %35
br label %43
43: ; preds = %42, %31
br label %44
44: ; preds = %43, %27
br label %45
45: ; preds = %44, %23
%46 = load i64, i64* %3
%47 = load i64, i64* %4
%48 = sdiv i64 %46, %47
store i64 %48, i64* %7
%49 = load i64, i64* %7
%50 = icmp eq i64 1, %49
%51 = zext i1 %50 to i64
%52 = select i1 %50, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.7, i64 0, i64 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.8, i64 0, i64 0)
store i8* %52, i8** %8
%53 = load i8*, i8** %6
%54 = load i8*, i8** %8
%55 = load i64, i64* %7
%56 = load i8*, i8** %5
%57 = call i32 @snprintf(i8* %53, i32 256, i8* %54, i64 %55, i8* %56)
%58 = load i8*, i8** %6
store i8* %58, i8** %2
br label %59
59: ; preds = %45, %16, %12
%60 = load i8*, i8** %2
ret i8* %60
}

LLVM IR (-O2):
@.str = [21 x i8] c"less than one second\00"
@.str.1 = [7 x i8] c"second\00"
@.str.2 = [7 x i8] c"minute\00"
@.str.3 = [5 x i8] c"hour\00"
@.str.4 = [4 x i8] c"day\00"
@.str.5 = [5 x i8] c"week\00"
@.str.6 = [5 x i8] c"year\00"
@.str.7 = [8 x i8] c"%lld %s\00"
@.str.8 = [9 x i8] c"%lld %ss\00"
define i8* @milliseconds_to_long_string(i64 %0) {
%2 = tail call dereferenceable_or_null(256) i8* @malloc(i32 256)
%3 = icmp eq i8* %2, null
br i1 %3, label %26, label %4
4: ; preds = %1
%5 = icmp slt i64 %0, 1000
br i1 %5, label %6, label %7
6: ; preds = %4
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 dereferenceable(21) %2, i8* align 1 dereferenceable(21) getelementptr inbounds ([21 x i8], [21 x i8]* @.str, i64 0, i64 0), i64 21, i1 false)
br label %26
7: ; preds = %4
%8 = icmp ult i64 %0, 60000
br i1 %8, label %19, label %9
9: ; preds = %7
%10 = icmp ult i64 %0, 3600000
br i1 %10, label %19, label %11
11: ; preds = %9
%12 = icmp ult i64 %0, 86400000
br i1 %12, label %19, label %13
13: ; preds = %11
%14 = icmp ult i64 %0, 604800000
br i1 %14, label %19, label %15
15: ; preds = %13
%16 = icmp ult i64 %0, 31449600000
%17 = select i1 %16, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.5, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.6, i64 0, i64 0)
%18 = select i1 %16, i64 604800000, i64 31449600000
br label %19
19: ; preds = %15, %13, %11, %9, %7
%20 = phi i8* [ getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i64 0, i64 0), %7 ], [ getelementptr inbounds ([7 x i8], [7 x i8]* @.str.2, i64 0, i64 0), %9 ], [ getelementptr inbounds ([5 x i8], [5 x i8]* @.str.3, i64 0, i64 0), %11 ], [ getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i64 0, i64 0), %13 ], [ %17, %15 ]
%21 = phi i64 [ 1000, %7 ], [ 60000, %9 ], [ 3600000, %11 ], [ 86400000, %13 ], [ %18, %15 ]
%22 = udiv i64 %0, %21
%23 = icmp eq i64 %22, 1
%24 = select i1 %23, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.7, i64 0, i64 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.8, i64 0, i64 0)
%25 = tail call i32 @snprintf(i8* %2, i32 256, i8* %24, i64 %22, i8* %20)
br label %26
26: ; preds = %1, %19, %6
ret i8* %2
}