#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 scalar_t__ time_t;
struct tm {
  int tm_sec;
  int tm_min;
  int tm_hour;
  int tm_mday;
  int tm_mon;
  int tm_year;
  scalar_t__ tm_isdst;
};

/* Variables and functions */
scalar_t__ mktime(struct tm *);
int /*<<< orphan*/ tzset();
void date2epoch(int year, int mm, int dd, int hour, int min, int sec, int msec,
                double *epoch) {
  struct tm date;
  time_t tmp;
  extern long timezone;
  date.tm_sec = sec;
  date.tm_min = min;
  date.tm_hour = hour;
  date.tm_mday = dd;
  date.tm_mon = mm - 1;
  date.tm_year = year - 1900;
  date.tm_isdst = 0;
  tzset();
  tmp = mktime(&date);
  *epoch = (double)tmp + (double)(msec) / 1000. - timezone;
}


x86 assembly (clang, -O0):
<date2epoch>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%eax
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    %ecx,-0x10(%rbp)
mov    %r8d,-0x14(%rbp)
mov    %r9d,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    %eax,-0x38(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x34(%rbp)
mov    -0x10(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x8(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x28(%rbp)
mov    -0x4(%rbp),%eax
sub    $0x76c,%eax
mov    %eax,-0x24(%rbp)
movq   $0x0,-0x20(%rbp)
mov    $0x0,%al
call   1030 <tzset@plt>
lea    -0x38(%rbp),%rdi
call   1040 <mktime@plt>
mov    %rax,-0x40(%rbp)
cvtsi2sdq -0x40(%rbp),%xmm0
cvtsi2sdl 0x10(%rbp),%xmm1
movsd  0xe62(%rip),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
mov    0x2e33(%rip),%rax
cvtsi2sdq (%rax),%xmm1
subsd  %xmm1,%xmm0
mov    0x18(%rbp),%rax
movsd  %xmm0,(%rax)
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<date2epoch>:
push   %rbx
sub    $0x20,%rsp
mov    0x38(%rsp),%rbx
mov    %r9d,(%rsp)
mov    %r8d,0x4(%rsp)
mov    %ecx,0x8(%rsp)
mov    %edx,0xc(%rsp)
add    $0xffffffff,%esi
mov    %esi,0x10(%rsp)
add    $0xfffff894,%edi
mov    %edi,0x14(%rsp)
movq   $0x0,0x18(%rsp)
xor    %eax,%eax
call   1030 <tzset@plt>
mov    %rsp,%rdi
call   1040 <mktime@plt>
cvtsi2sd %rax,%xmm0
cvtsi2sdl 0x30(%rsp),%xmm1
divsd  0xe89(%rip),%xmm1
addsd  %xmm0,%xmm1
mov    0x2e5e(%rip),%rax
xorps  %xmm0,%xmm0
cvtsi2sdq (%rax),%xmm0
subsd  %xmm0,%xmm1
movsd  %xmm1,(%rbx)
add    $0x20,%rsp
pop    %rbx
ret

LLVM IR (-O0):
%struct.tm = type { i32, i32, i32, i32, i32, i32, i64 }
@timezone = external global i64
define void @date2epoch(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, double* %7) {
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca double*
%17 = alloca %struct.tm
%18 = alloca i64
store i32 %0, i32* %9
store i32 %1, i32* %10
store i32 %2, i32* %11
store i32 %3, i32* %12
store i32 %4, i32* %13
store i32 %5, i32* %14
store i32 %6, i32* %15
store double* %7, double** %16
%19 = load i32, i32* %14
%20 = getelementptr inbounds %struct.tm, %struct.tm* %17, i32 0, i32 0
store i32 %19, i32* %20
%21 = load i32, i32* %13
%22 = getelementptr inbounds %struct.tm, %struct.tm* %17, i32 0, i32 1
store i32 %21, i32* %22
%23 = load i32, i32* %12
%24 = getelementptr inbounds %struct.tm, %struct.tm* %17, i32 0, i32 2
store i32 %23, i32* %24
%25 = load i32, i32* %11
%26 = getelementptr inbounds %struct.tm, %struct.tm* %17, i32 0, i32 3
store i32 %25, i32* %26
%27 = load i32, i32* %10
%28 = sub nsw i32 %27, 1
%29 = getelementptr inbounds %struct.tm, %struct.tm* %17, i32 0, i32 4
store i32 %28, i32* %29
%30 = load i32, i32* %9
%31 = sub nsw i32 %30, 1900
%32 = getelementptr inbounds %struct.tm, %struct.tm* %17, i32 0, i32 5
store i32 %31, i32* %32
%33 = getelementptr inbounds %struct.tm, %struct.tm* %17, i32 0, i32 6
store i64 0, i64* %33
%34 = call i32 (...) @tzset()
%35 = call i64 @mktime(%struct.tm* %17)
store i64 %35, i64* %18
%36 = load i64, i64* %18
%37 = sitofp i64 %36 to double
%38 = load i32, i32* %15
%39 = sitofp i32 %38 to double
%40 = fdiv double %39, 1.000000e+03
%41 = fadd double %37, %40
%42 = load i64, i64* @timezone
%43 = sitofp i64 %42 to double
%44 = fsub double %41, %43
%45 = load double*, double** %16
store double %44, double* %45
ret void
}

LLVM IR (-O2):
%struct.tm = type { i32, i32, i32, i32, i32, i32, i64 }
@timezone = external global i64
define void @date2epoch(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, double* nocapture writeonly %7) {
%9 = alloca %struct.tm
%10 = bitcast %struct.tm* %9 to i8*
%11 = getelementptr inbounds %struct.tm, %struct.tm* %9, i64 0, i32 0
store i32 %5, i32* %11
%12 = getelementptr inbounds %struct.tm, %struct.tm* %9, i64 0, i32 1
store i32 %4, i32* %12
%13 = getelementptr inbounds %struct.tm, %struct.tm* %9, i64 0, i32 2
store i32 %3, i32* %13
%14 = getelementptr inbounds %struct.tm, %struct.tm* %9, i64 0, i32 3
store i32 %2, i32* %14
%15 = add nsw i32 %1, -1
%16 = getelementptr inbounds %struct.tm, %struct.tm* %9, i64 0, i32 4
store i32 %15, i32* %16
%17 = add nsw i32 %0, -1900
%18 = getelementptr inbounds %struct.tm, %struct.tm* %9, i64 0, i32 5
store i32 %17, i32* %18
%19 = getelementptr inbounds %struct.tm, %struct.tm* %9, i64 0, i32 6
store i64 0, i64* %19
%20 = tail call i32 (...) @tzset()
%21 = call i64 @mktime(%struct.tm* %9)
%22 = sitofp i64 %21 to double
%23 = sitofp i32 %6 to double
%24 = fdiv double %23, 1.000000e+03
%25 = fadd double %24, %22
%26 = load i64, i64* @timezone
%27 = sitofp i64 %26 to double
%28 = fsub double %25, %27
store double %28, double* %7
ret void
}