#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 timespec {
  double tv_sec;
  scalar_t__ tv_nsec;
};

/* Variables and functions */
double timeDiff(struct timespec *startTp, struct timespec *finishTp) {
  double start = startTp->tv_sec + ((double)startTp->tv_nsec) / 1000000000;
  double finish = finishTp->tv_sec + ((double)finishTp->tv_nsec) / 1000000000;
  return (finish - start);
}


x86 assembly (clang, -O0):
<timeDiff>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x8(%rbp),%rax
cvtsi2sdq 0x8(%rax),%xmm1
movsd  0xeda(%rip),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x10(%rbp),%rax
cvtsi2sdq 0x8(%rax),%xmm1
movsd  0xeb3(%rip),%xmm2
divsd  %xmm2,%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<timeDiff>:
cvtsi2sdq 0x8(%rdi),%xmm0
cvtsi2sdq 0x8(%rsi),%xmm1
unpcklpd %xmm0,%xmm1
divpd  0xee8(%rip),%xmm1
movsd  (%rsi),%xmm0
movhpd (%rdi),%xmm0
addpd  %xmm1,%xmm0
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
subsd  %xmm1,%xmm0
ret

LLVM IR (-O0):
%struct.timespec = type { double, i64 }
define double @timeDiff(%struct.timespec* %0, %struct.timespec* %1) {
%3 = alloca %struct.timespec*
%4 = alloca %struct.timespec*
%5 = alloca double
%6 = alloca double
store %struct.timespec* %0, %struct.timespec** %3
store %struct.timespec* %1, %struct.timespec** %4
%7 = load %struct.timespec*, %struct.timespec** %3
%8 = getelementptr inbounds %struct.timespec, %struct.timespec* %7, i32 0, i32 0
%9 = load double, double* %8
%10 = load %struct.timespec*, %struct.timespec** %3
%11 = getelementptr inbounds %struct.timespec, %struct.timespec* %10, i32 0, i32 1
%12 = load i64, i64* %11
%13 = sitofp i64 %12 to double
%14 = fdiv double %13, 1.000000e+09
%15 = fadd double %9, %14
store double %15, double* %5
%16 = load %struct.timespec*, %struct.timespec** %4
%17 = getelementptr inbounds %struct.timespec, %struct.timespec* %16, i32 0, i32 0
%18 = load double, double* %17
%19 = load %struct.timespec*, %struct.timespec** %4
%20 = getelementptr inbounds %struct.timespec, %struct.timespec* %19, i32 0, i32 1
%21 = load i64, i64* %20
%22 = sitofp i64 %21 to double
%23 = fdiv double %22, 1.000000e+09
%24 = fadd double %18, %23
store double %24, double* %6
%25 = load double, double* %6
%26 = load double, double* %5
%27 = fsub double %25, %26
ret double %27
}

LLVM IR (-O2):
%struct.timespec = type { double, i64 }
define double @timeDiff(%struct.timespec* nocapture %0, %struct.timespec* nocapture %1) {
%3 = getelementptr inbounds %struct.timespec, %struct.timespec* %0, i64 0, i32 0
%4 = load double, double* %3
%5 = getelementptr inbounds %struct.timespec, %struct.timespec* %0, i64 0, i32 1
%6 = load i64, i64* %5
%7 = getelementptr inbounds %struct.timespec, %struct.timespec* %1, i64 0, i32 0
%8 = load double, double* %7
%9 = getelementptr inbounds %struct.timespec, %struct.timespec* %1, i64 0, i32 1
%10 = load i64, i64* %9
%11 = insertelement <2 x i64> poison, i64 %10, i64 0
%12 = insertelement <2 x i64> %11, i64 %6, i64 1
%13 = sitofp <2 x i64> %12 to <2 x double>
%14 = fdiv <2 x double> %13, <double 1.000000e+09, double 1.000000e+09>
%15 = insertelement <2 x double> poison, double %8, i64 0
%16 = insertelement <2 x double> %15, double %4, i64 1
%17 = fadd <2 x double> %16, %14
%18 = shufflevector <2 x double> %17, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%19 = fsub <2 x double> %17, %18
%20 = extractelement <2 x double> %19, i64 0
ret double %20
}