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

/* Variables and functions */
long long LONG_MAX;
void diff(struct timespec t1, struct timespec t2, struct timespec *res) {
  long long res_nsec = 0;
  long nsec_diff = 0;
  long sec_diff = 0;
  long long res_sec = 0;
  if ((t2.tv_nsec) - (t1.tv_nsec) < 0) {
    nsec_diff = 1e9;
    sec_diff = 1;
  }
  res_nsec = res->tv_nsec + t2.tv_nsec + nsec_diff - t1.tv_nsec + 0LL;
  if (res_nsec > LONG_MAX) {
    res->tv_nsec = LONG_MAX;
    res_sec = (res_nsec - LONG_MAX) / (1e9);
  } else
    res->tv_nsec = (long)res_nsec;
  res->tv_sec = (long)res_sec + res->tv_sec + t2.tv_sec - sec_diff - t1.tv_sec;
}


x86 assembly (clang, -O0):
<diff>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x8(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x18(%rbp)
mov    %r8,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
movq   $0x0,-0x38(%rbp)
movq   $0x0,-0x40(%rbp)
movq   $0x0,-0x48(%rbp)
mov    -0x20(%rbp),%rax
sub    -0x10(%rbp),%rax
cmp    $0x0,%rax
jge    115a <diff+0x5a>
movq   $0x3b9aca00,-0x38(%rbp)
3b
movq   $0x1,-0x40(%rbp)
mov    -0x28(%rbp),%rax
mov    (%rax),%rax
add    -0x20(%rbp),%rax
add    -0x38(%rbp),%rax
sub    -0x10(%rbp),%rax
add    $0x0,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
mov    0x2e60(%rip),%rcx
cmp    (%rcx),%rax
jle    11c7 <diff+0xc7>
mov    0x2e50(%rip),%rax
mov    (%rax),%rcx
mov    -0x28(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x30(%rbp),%rax
mov    0x2e3b(%rip),%rcx
sub    (%rcx),%rax
cvtsi2sd %rax,%xmm0
movsd  0xe4b(%rip),%xmm1
divsd  %xmm1,%xmm0
cvttsd2si %xmm0,%rax
mov    %rax,-0x48(%rbp)
jmp    11d2 <diff+0xd2>
mov    -0x30(%rbp),%rcx
mov    -0x28(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x48(%rbp),%rcx
mov    -0x28(%rbp),%rax
add    0x8(%rax),%rcx
add    -0x18(%rbp),%rcx
sub    -0x40(%rbp),%rcx
sub    -0x8(%rbp),%rcx
mov    -0x28(%rbp),%rax
mov    %rcx,0x8(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<diff>:
mov    %rdx,%r9
sub    %rdi,%r9
add    $0x3b9aca00,%r9
mov    %rdx,%r11
sub    %rdi,%r11
cmovl  %r9,%r11
add    (%r8),%r11
mov    0x2ebf(%rip),%rax
mov    (%rax),%r9
mov    %r11,%r10
sub    %r9,%r10
jle    1143 <diff+0x43>
mov    %r9,(%r8)
cvtsi2sd %r10,%xmm0
divsd  0xec4(%rip),%xmm0
cvttsd2si %xmm0,%r9
jmp    1149 <diff+0x49>
mov    %r11,(%r8)
xor    %r9d,%r9d
xor    %eax,%eax
cmp    %rdi,%rdx
setl   %al
sub    %rsi,%rcx
sub    %rax,%rcx
add    %r9,%rcx
add    %rcx,0x8(%r8)
ret

LLVM IR (-O0):
%struct.timespec = type { i64, i64 }
@LONG_MAX = global i64 0
define void @diff(i64 %0, i64 %1, i64 %2, i64 %3, %struct.timespec* %4) {
%6 = alloca %struct.timespec
%7 = alloca %struct.timespec
%8 = alloca %struct.timespec*
%9 = alloca i64
%10 = alloca i64
%11 = alloca i64
%12 = alloca i64
%13 = bitcast %struct.timespec* %6 to { i64, i64 }*
%14 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %13, i32 0, i32 0
store i64 %0, i64* %14
%15 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %13, i32 0, i32 1
store i64 %1, i64* %15
%16 = bitcast %struct.timespec* %7 to { i64, i64 }*
%17 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %16, i32 0, i32 0
store i64 %2, i64* %17
%18 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %16, i32 0, i32 1
store i64 %3, i64* %18
store %struct.timespec* %4, %struct.timespec** %8
store i64 0, i64* %9
store i64 0, i64* %10
store i64 0, i64* %11
store i64 0, i64* %12
%19 = getelementptr inbounds %struct.timespec, %struct.timespec* %7, i32 0, i32 0
%20 = load i64, i64* %19
%21 = getelementptr inbounds %struct.timespec, %struct.timespec* %6, i32 0, i32 0
%22 = load i64, i64* %21
%23 = sub nsw i64 %20, %22
%24 = icmp slt i64 %23, 0
br i1 %24, label %25, label %26
25: ; preds = %5
store i64 1000000000, i64* %10
store i64 1, i64* %11
br label %26
26: ; preds = %25, %5
%27 = load %struct.timespec*, %struct.timespec** %8
%28 = getelementptr inbounds %struct.timespec, %struct.timespec* %27, i32 0, i32 0
%29 = load i64, i64* %28
%30 = getelementptr inbounds %struct.timespec, %struct.timespec* %7, i32 0, i32 0
%31 = load i64, i64* %30
%32 = add nsw i64 %29, %31
%33 = load i64, i64* %10
%34 = add nsw i64 %32, %33
%35 = getelementptr inbounds %struct.timespec, %struct.timespec* %6, i32 0, i32 0
%36 = load i64, i64* %35
%37 = sub nsw i64 %34, %36
%38 = add nsw i64 %37, 0
store i64 %38, i64* %9
%39 = load i64, i64* %9
%40 = load i64, i64* @LONG_MAX
%41 = icmp sgt i64 %39, %40
br i1 %41, label %42, label %52
42: ; preds = %26
%43 = load i64, i64* @LONG_MAX
%44 = load %struct.timespec*, %struct.timespec** %8
%45 = getelementptr inbounds %struct.timespec, %struct.timespec* %44, i32 0, i32 0
store i64 %43, i64* %45
%46 = load i64, i64* %9
%47 = load i64, i64* @LONG_MAX
%48 = sub nsw i64 %46, %47
%49 = sitofp i64 %48 to double
%50 = fdiv double %49, 1.000000e+09
%51 = fptosi double %50 to i64
store i64 %51, i64* %12
br label %56
52: ; preds = %26
%53 = load i64, i64* %9
%54 = load %struct.timespec*, %struct.timespec** %8
%55 = getelementptr inbounds %struct.timespec, %struct.timespec* %54, i32 0, i32 0
store i64 %53, i64* %55
br label %56
56: ; preds = %52, %42
%57 = load i64, i64* %12
%58 = load %struct.timespec*, %struct.timespec** %8
%59 = getelementptr inbounds %struct.timespec, %struct.timespec* %58, i32 0, i32 1
%60 = load i64, i64* %59
%61 = add nsw i64 %57, %60
%62 = getelementptr inbounds %struct.timespec, %struct.timespec* %7, i32 0, i32 1
%63 = load i64, i64* %62
%64 = add nsw i64 %61, %63
%65 = load i64, i64* %11
%66 = sub nsw i64 %64, %65
%67 = getelementptr inbounds %struct.timespec, %struct.timespec* %6, i32 0, i32 1
%68 = load i64, i64* %67
%69 = sub nsw i64 %66, %68
%70 = load %struct.timespec*, %struct.timespec** %8
%71 = getelementptr inbounds %struct.timespec, %struct.timespec* %70, i32 0, i32 1
store i64 %69, i64* %71
ret void
}

LLVM IR (-O2):
%struct.timespec = type { i64, i64 }
@LONG_MAX = global i64 0
define void @diff(i64 %0, i64 %1, i64 %2, i64 %3, %struct.timespec* nocapture %4) {
%6 = icmp slt i64 %2, %0
%7 = select i1 %6, i64 1000000000, i64 0
%8 = getelementptr inbounds %struct.timespec, %struct.timespec* %4, i64 0, i32 0
%9 = load i64, i64* %8
%10 = sub i64 %2, %0
%11 = add i64 %10, %7
%12 = add i64 %11, %9
%13 = load i64, i64* @LONG_MAX
%14 = icmp sgt i64 %12, %13
br i1 %14, label %15, label %20
15: ; preds = %5
store i64 %13, i64* %8
%16 = sub nsw i64 %12, %13
%17 = sitofp i64 %16 to double
%18 = fdiv double %17, 1.000000e+09
%19 = fptosi double %18 to i64
br label %21
20: ; preds = %5
store i64 %12, i64* %8
br label %21
21: ; preds = %20, %15
%22 = phi i64 [ %19, %15 ], [ 0, %20 ]
%23 = sext i1 %6 to i64
%24 = getelementptr inbounds %struct.timespec, %struct.timespec* %4, i64 0, i32 1
%25 = load i64, i64* %24
%26 = sub i64 %3, %1
%27 = add i64 %26, %23
%28 = add i64 %27, %22
%29 = add i64 %28, %25
store i64 %29, i64* %24
ret void
}