#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*/ tmp;
typedef int /*<<< orphan*/ time_t;
struct tm {
  int dummy;
};
struct timeval {
  int tv_usec;
  int /*<<< orphan*/ tv_sec;
};

/* Variables and functions */
int /*<<< orphan*/ gettimeofday(struct timeval *, int /*<<< orphan*/ *);
int /*<<< orphan*/ *localtime_r(int /*<<< orphan*/ *, struct tm *);
int /*<<< orphan*/ snprintf(char *, int, char *, char *, int);
int /*<<< orphan*/ strftime(char *, int, char *, struct tm *);
int strtime(char *buff, int buff_size, int fmt, unsigned long now) {
  struct timeval tv;
  struct tm tm;
  char tmp[32];
  if (buff == NULL)
    return -1;
  buff[0] = '\0';
  if (now == -1)
    return 0;
  if (now == 0) {
    gettimeofday(&tv, NULL);
    if (localtime_r(&tv.tv_sec, &tm) == NULL)
      return -1;
  } else {
    if (localtime_r((time_t *)&now, &tm) == NULL)
      ;
  }
  if (fmt == 1)
    strftime(buff, buff_size, "%F", &tm);
  else if (fmt == 2)
    strftime(buff, buff_size, "%F %T", &tm);
  else if (fmt == 3) {
    strftime(tmp, sizeof(tmp), "%F %T", &tm);
    snprintf(buff, buff_size, "%s-%03ld", tmp,
             now == 0 ? tv.tv_usec / 1000 : 0);
  } else
    return -1;
  return 0;
}


x86 assembly (clang, -O0):
<strtime>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %edx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    116d <strtime+0x2d>
movl   $0xffffffff,-0x4(%rbp)
jmp    12da <strtime+0x19a>
mov    -0x10(%rbp),%rax
movb   $0x0,(%rax)
cmpq   $0xffffffffffffffff,-0x20(%rbp)
jne    118b <strtime+0x4b>
movl   $0x0,-0x4(%rbp)
jmp    12da <strtime+0x19a>
cmpq   $0x0,-0x20(%rbp)
jne    11cf <strtime+0x8f>
lea    -0x28(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1050 <gettimeofday@plt>
lea    -0x28(%rbp),%rdi
add    $0x4,%rdi
lea    -0x30(%rbp),%rsi
call   1030 <localtime_r@plt>
cmp    $0x0,%rax
jne    11ca <strtime+0x8a>
movl   $0xffffffff,-0x4(%rbp)
jmp    12da <strtime+0x19a>
jmp    11f0 <strtime+0xb0>
lea    -0x20(%rbp),%rdi
lea    -0x30(%rbp),%rsi
call   1030 <localtime_r@plt>
cmp    $0x0,%rax
jne    11eb <strtime+0xab>
jmp    11eb <strtime+0xab>
jmp    11f0 <strtime+0xb0>
cmpl   $0x1,-0x18(%rbp)
jne    1216 <strtime+0xd6>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
lea    0xdf8(%rip),%rdx
lea    -0x30(%rbp),%rcx
call   1060 <strftime@plt>
jmp    12d3 <strtime+0x193>
cmpl   $0x2,-0x18(%rbp)
jne    123c <strtime+0xfc>
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
lea    0xdd5(%rip),%rdx
lea    -0x30(%rbp),%rcx
call   1060 <strftime@plt>
jmp    12ce <strtime+0x18e>
cmpl   $0x3,-0x18(%rbp)
jne    12bd <strtime+0x17d>
lea    -0x50(%rbp),%rdi
mov    $0x20,%esi
lea    0xdad(%rip),%rdx
lea    -0x30(%rbp),%rcx
call   1060 <strftime@plt>
mov    -0x10(%rbp),%rax
mov    %rax,-0x68(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x5c(%rbp)
lea    -0x50(%rbp),%rax
mov    %rax,-0x58(%rbp)
cmpq   $0x0,-0x20(%rbp)
jne    1293 <strtime+0x153>
mov    -0x28(%rbp),%eax
mov    $0x3e8,%ecx
cltd
idiv   %ecx
mov    %eax,-0x6c(%rbp)
jmp    129d <strtime+0x15d>
xor    %eax,%eax
mov    %eax,-0x6c(%rbp)
jmp    129d <strtime+0x15d>
mov    -0x58(%rbp),%rcx
mov    -0x5c(%rbp),%esi
mov    -0x68(%rbp),%rdi
mov    -0x6c(%rbp),%r8d
lea    0xd56(%rip),%rdx
call   1040 <snprintf@plt>
jmp    12c9 <strtime+0x189>
movl   $0xffffffff,-0x4(%rbp)
jmp    12da <strtime+0x19a>
jmp    12ce <strtime+0x18e>
jmp    12d3 <strtime+0x193>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<strtime>:
push   %rbp
push   %r15
push   %r14
push   %rbx
sub    $0x48,%rsp
mov    %rcx,0x18(%rsp)
mov    $0xffffffff,%r15d
test   %rdi,%rdi
je     1249 <strtime+0x109>
mov    %rdi,%rbx
movb   $0x0,(%rdi)
cmp    $0xffffffffffffffff,%rcx
je     1246 <strtime+0x106>
mov    %edx,%ebp
mov    %esi,%r14d
test   %rcx,%rcx
jne    11bc <strtime+0x7c>
lea    0x10(%rsp),%rdi
xor    %esi,%esi
call   1050 <gettimeofday@plt>
lea    0x14(%rsp),%rdi
lea    0x8(%rsp),%rsi
call   1030 <localtime_r@plt>
test   %rax,%rax
je     1249 <strtime+0x109>
cmp    $0x3,%ebp
je     11d0 <strtime+0x90>
cmp    $0x2,%ebp
je     122f <strtime+0xef>
cmp    $0x1,%ebp
jne    1249 <strtime+0x109>
lea    0xe46(%rip),%rdx
jmp    1236 <strtime+0xf6>
lea    0x18(%rsp),%rdi
lea    0x8(%rsp),%rsi
call   1030 <localtime_r@plt>
cmp    $0x3,%ebp
jne    11a1 <strtime+0x61>
lea    0xe2c(%rip),%rdx
lea    0x20(%rsp),%rdi
lea    0x8(%rsp),%rcx
mov    $0x20,%esi
call   1060 <strftime@plt>
xor    %r15d,%r15d
cmpq   $0x0,0x18(%rsp)
mov    $0x0,%r8d
jne    1216 <strtime+0xd6>
movslq 0x10(%rsp),%rax
imul   $0x10624dd3,%rax,%r8
mov    %r8,%rax
shr    $0x3f,%rax
sar    $0x26,%r8
add    %eax,%r8d
lea    0xdec(%rip),%rdx
lea    0x20(%rsp),%rcx
mov    %rbx,%rdi
mov    %r14d,%esi
call   1040 <snprintf@plt>
jmp    1249 <strtime+0x109>
lea    0xdcd(%rip),%rdx
lea    0x8(%rsp),%rcx
mov    %rbx,%rdi
mov    %r14d,%esi
call   1060 <strftime@plt>
xor    %r15d,%r15d
mov    %r15d,%eax
add    $0x48,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.timeval = type { i32, i32 }
%struct.tm = type { i32 }
@.str = [3 x i8] c"%F\00"
@.str.1 = [6 x i8] c"%F %T\00"
@.str.2 = [9 x i8] c"%s-%03ld\00"
define i32 @strtime(i8* %0, i32 %1, i32 %2, i64 %3) {
%5 = alloca i32
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i64
%10 = alloca %struct.timeval
%11 = alloca %struct.tm
%12 = alloca [32 x i8]
store i8* %0, i8** %6
store i32 %1, i32* %7
store i32 %2, i32* %8
store i64 %3, i64* %9
%13 = load i8*, i8** %6
%14 = icmp eq i8* %13, null
br i1 %14, label %15, label %16
15: ; preds = %4
store i32 -1, i32* %5
br label %75
16: ; preds = %4
%17 = load i8*, i8** %6
%18 = getelementptr inbounds i8, i8* %17, i64 0
store i8 0, i8* %18
%19 = load i64, i64* %9
%20 = icmp eq i64 %19, -1
br i1 %20, label %21, label %22
21: ; preds = %16
store i32 0, i32* %5
br label %75
22: ; preds = %16
%23 = load i64, i64* %9
%24 = icmp eq i64 %23, 0
br i1 %24, label %25, label %32
25: ; preds = %22
%26 = call i32 @gettimeofday(%struct.timeval* %10, i32* null)
%27 = getelementptr inbounds %struct.timeval, %struct.timeval* %10, i32 0, i32 1
%28 = call i32* @localtime_r(i32* %27, %struct.tm* %11)
%29 = icmp eq i32* %28, null
br i1 %29, label %30, label %31
30: ; preds = %25
store i32 -1, i32* %5
br label %75
31: ; preds = %25
br label %38
32: ; preds = %22
%33 = bitcast i64* %9 to i32*
%34 = call i32* @localtime_r(i32* %33, %struct.tm* %11)
%35 = icmp eq i32* %34, null
br i1 %35, label %36, label %37
36: ; preds = %32
br label %37
37: ; preds = %36, %32
br label %38
38: ; preds = %37, %31
%39 = load i32, i32* %8
%40 = icmp eq i32 %39, 1
br i1 %40, label %41, label %45
41: ; preds = %38
%42 = load i8*, i8** %6
%43 = load i32, i32* %7
%44 = call i32 @strftime(i8* %42, i32 %43, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), %struct.tm* %11)
br label %74
45: ; preds = %38
%46 = load i32, i32* %8
%47 = icmp eq i32 %46, 2
br i1 %47, label %48, label %52
48: ; preds = %45
%49 = load i8*, i8** %6
%50 = load i32, i32* %7
%51 = call i32 @strftime(i8* %49, i32 %50, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0), %struct.tm* %11)
br label %73
52: ; preds = %45
%53 = load i32, i32* %8
%54 = icmp eq i32 %53, 3
br i1 %54, label %55, label %71
55: ; preds = %52
%56 = getelementptr inbounds [32 x i8], [32 x i8]* %12, i64 0, i64 0
%57 = call i32 @strftime(i8* %56, i32 32, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0), %struct.tm* %11)
%58 = load i8*, i8** %6
%59 = load i32, i32* %7
%60 = getelementptr inbounds [32 x i8], [32 x i8]* %12, i64 0, i64 0
%61 = load i64, i64* %9
%62 = icmp eq i64 %61, 0
br i1 %62, label %63, label %67
63: ; preds = %55
%64 = getelementptr inbounds %struct.timeval, %struct.timeval* %10, i32 0, i32 0
%65 = load i32, i32* %64
%66 = sdiv i32 %65, 1000
br label %68
67: ; preds = %55
br label %68
68: ; preds = %67, %63
%69 = phi i32 [ %66, %63 ], [ 0, %67 ]
%70 = call i32 @snprintf(i8* %58, i32 %59, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.2, i64 0, i64 0), i8* %60, i32 %69)
br label %72
71: ; preds = %52
store i32 -1, i32* %5
br label %75
72: ; preds = %68
br label %73
73: ; preds = %72, %48
br label %74
74: ; preds = %73, %41
store i32 0, i32* %5
br label %75
75: ; preds = %74, %71, %30, %21, %15
%76 = load i32, i32* %5
ret i32 %76
}

LLVM IR (-O2):
%struct.timeval = type { i32, i32 }
%struct.tm = type { i32 }
@.str = [3 x i8] c"%F\00"
@.str.1 = [6 x i8] c"%F %T\00"
@.str.2 = [9 x i8] c"%s-%03ld\00"
define i32 @strtime(i8* %0, i32 %1, i32 %2, i64 %3) {
%5 = alloca i64
%6 = alloca %struct.timeval
%7 = alloca %struct.tm
%8 = alloca [32 x i8]
store i64 %3, i64* %5
%9 = bitcast %struct.timeval* %6 to i8*
%10 = bitcast %struct.tm* %7 to i8*
%11 = getelementptr inbounds [32 x i8], [32 x i8]* %8, i64 0, i64 0
%12 = icmp eq i8* %0, null
br i1 %12, label %38, label %13
13: ; preds = %4
store i8 0, i8* %0
switch i64 %3, label %19 [
i64 -1, label %38
i64 0, label %14
]
14: ; preds = %13
%15 = call i32 @gettimeofday(%struct.timeval* %6, i32* null)
%16 = getelementptr inbounds %struct.timeval, %struct.timeval* %6, i64 0, i32 1
%17 = call i32* @localtime_r(i32* %16, %struct.tm* %7)
%18 = icmp eq i32* %17, null
br i1 %18, label %38, label %22
19: ; preds = %13
%20 = bitcast i64* %5 to i32*
%21 = call i32* @localtime_r(i32* %20, %struct.tm* %7)
br label %22
22: ; preds = %14, %19
switch i32 %2, label %38 [
i32 1, label %23
i32 2, label %25
i32 3, label %27
]
23: ; preds = %22
%24 = call i32 @strftime(i8* %0, i32 %1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), %struct.tm* %7)
br label %38
25: ; preds = %22
%26 = call i32 @strftime(i8* %0, i32 %1, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0), %struct.tm* %7)
br label %38
27: ; preds = %22
%28 = call i32 @strftime(i8* %11, i32 32, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0), %struct.tm* %7)
%29 = load i64, i64* %5
%30 = icmp eq i64 %29, 0
br i1 %30, label %31, label %35
31: ; preds = %27
%32 = getelementptr inbounds %struct.timeval, %struct.timeval* %6, i64 0, i32 0
%33 = load i32, i32* %32
%34 = sdiv i32 %33, 1000
br label %35
35: ; preds = %27, %31
%36 = phi i32 [ %34, %31 ], [ 0, %27 ]
%37 = call i32 @snprintf(i8* %0, i32 %1, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.2, i64 0, i64 0), i8* %11, i32 %36)
br label %38
38: ; preds = %23, %35, %25, %22, %14, %13, %4
%39 = phi i32 [ -1, %4 ], [ 0, %13 ], [ -1, %14 ], [ -1, %22 ], [ 0, %25 ], [ 0, %35 ], [ 0, %23 ]
ret i32 %39
}