#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 */
struct timeval {
  long tv_usec;
  int tv_sec;
};

/* Variables and functions */
double deltaT(struct timeval *tin, struct timeval *tout) {
  long usec;
  double sec;
  usec = tout->tv_usec - tin->tv_usec;
  if (usec < 0) {
    sec = tout->tv_sec - tin->tv_sec - 1 + ((double)(usec + 1000000)) * 1e-6;
  } else {
    sec = tout->tv_sec - tin->tv_sec + ((double)usec) * 1e-6;
  }
  return sec;
}


x86 assembly (clang, -O0):
<deltaT>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    -0x8(%rbp),%rcx
sub    (%rcx),%rax
mov    %rax,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
jge    1167 <deltaT+0x67>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%eax
mov    -0x8(%rbp),%rcx
sub    0x8(%rcx),%eax
sub    $0x1,%eax
cvtsi2sd %eax,%xmm1
mov    -0x18(%rbp),%rax
add    $0xf4240,%rax
cvtsi2sd %rax,%xmm0
movsd  0xeab(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    1194 <deltaT+0x94>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%eax
mov    -0x8(%rbp),%rcx
sub    0x8(%rcx),%eax
cvtsi2sd %eax,%xmm1
cvtsi2sdq -0x18(%rbp),%xmm0
movsd  0xe79(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<deltaT>:
mov    (%rsi),%rax
sub    (%rdi),%rax
mov    0x8(%rdi),%ecx
lea    0xf4240(%rax),%rdx
mov    %ecx,%edi
neg    %edi
test   %rax,%rax
not    %ecx
cmovns %rax,%rdx
cmovns %edi,%ecx
add    0x8(%rsi),%ecx
cvtsi2sd %ecx,%xmm1
cvtsi2sd %rdx,%xmm0
mulsd  0xecc(%rip),%xmm0
addsd  %xmm1,%xmm0
ret

LLVM IR (-O0):
%struct.timeval = type { i64, i32 }
define double @deltaT(%struct.timeval* %0, %struct.timeval* %1) {
%3 = alloca %struct.timeval*
%4 = alloca %struct.timeval*
%5 = alloca i64
%6 = alloca double
store %struct.timeval* %0, %struct.timeval** %3
store %struct.timeval* %1, %struct.timeval** %4
%7 = load %struct.timeval*, %struct.timeval** %4
%8 = getelementptr inbounds %struct.timeval, %struct.timeval* %7, i32 0, i32 0
%9 = load i64, i64* %8
%10 = load %struct.timeval*, %struct.timeval** %3
%11 = getelementptr inbounds %struct.timeval, %struct.timeval* %10, i32 0, i32 0
%12 = load i64, i64* %11
%13 = sub nsw i64 %9, %12
store i64 %13, i64* %5
%14 = load i64, i64* %5
%15 = icmp slt i64 %14, 0
br i1 %15, label %16, label %30
16: ; preds = %2
%17 = load %struct.timeval*, %struct.timeval** %4
%18 = getelementptr inbounds %struct.timeval, %struct.timeval* %17, i32 0, i32 1
%19 = load i32, i32* %18
%20 = load %struct.timeval*, %struct.timeval** %3
%21 = getelementptr inbounds %struct.timeval, %struct.timeval* %20, i32 0, i32 1
%22 = load i32, i32* %21
%23 = sub nsw i32 %19, %22
%24 = sub nsw i32 %23, 1
%25 = sitofp i32 %24 to double
%26 = load i64, i64* %5
%27 = add nsw i64 %26, 1000000
%28 = sitofp i64 %27 to double
%29 = call double @llvm.fmuladd.f64(double %28, double 0x3EB0C6F7A0B5ED8D, double %25)
store double %29, double* %6
br label %42
30: ; preds = %2
%31 = load %struct.timeval*, %struct.timeval** %4
%32 = getelementptr inbounds %struct.timeval, %struct.timeval* %31, i32 0, i32 1
%33 = load i32, i32* %32
%34 = load %struct.timeval*, %struct.timeval** %3
%35 = getelementptr inbounds %struct.timeval, %struct.timeval* %34, i32 0, i32 1
%36 = load i32, i32* %35
%37 = sub nsw i32 %33, %36
%38 = sitofp i32 %37 to double
%39 = load i64, i64* %5
%40 = sitofp i64 %39 to double
%41 = call double @llvm.fmuladd.f64(double %40, double 0x3EB0C6F7A0B5ED8D, double %38)
store double %41, double* %6
br label %42
42: ; preds = %30, %16
%43 = load double, double* %6
ret double %43
}

LLVM IR (-O2):
%struct.timeval = type { i64, i32 }
define double @deltaT(%struct.timeval* nocapture %0, %struct.timeval* nocapture %1) {
%3 = getelementptr inbounds %struct.timeval, %struct.timeval* %1, i64 0, i32 0
%4 = load i64, i64* %3
%5 = getelementptr inbounds %struct.timeval, %struct.timeval* %0, i64 0, i32 0
%6 = load i64, i64* %5
%7 = sub nsw i64 %4, %6
%8 = icmp slt i64 %7, 0
%9 = getelementptr inbounds %struct.timeval, %struct.timeval* %1, i64 0, i32 1
%10 = load i32, i32* %9
%11 = getelementptr inbounds %struct.timeval, %struct.timeval* %0, i64 0, i32 1
%12 = load i32, i32* %11
%13 = xor i32 %12, -1
%14 = add nsw i64 %7, 1000000
%15 = select i1 %8, i64 %14, i64 %7
%16 = sub i32 0, %12
%17 = select i1 %8, i32 %13, i32 %16
%18 = add i32 %10, %17
%19 = sitofp i32 %18 to double
%20 = sitofp i64 %15 to double
%21 = tail call double @llvm.fmuladd.f64(double %20, double 0x3EB0C6F7A0B5ED8D, double %19)
ret double %21
}