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

/* Variables and functions */
scalar_t__ time_gt(struct timespec *, struct timespec *);
void time_diff(struct timespec *a, struct timespec *b, struct timespec *res) {
  if (time_gt(a, b)) {
    res->tv_sec = a->tv_sec - b->tv_sec;
    res->tv_nsec = a->tv_nsec - b->tv_nsec;
    if (res->tv_nsec < 0) {
      res->tv_nsec = 1000000000 + res->tv_nsec;
      res->tv_sec = res->tv_sec - 1;
    }
  } else {
    res->tv_sec = b->tv_sec - a->tv_sec;
    res->tv_nsec = b->tv_nsec - a->tv_nsec;
    if (res->tv_nsec < 0) {
      res->tv_nsec = 1000000000 + res->tv_nsec;
      res->tv_sec = res->tv_sec - 1;
    }
  }
  return;
}


x86 assembly (clang, -O0):
<time_diff>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
call   1030 <time_gt@plt>
cmp    $0x0,%rax
je     11a4 <time_diff+0x94>
mov    -0x8(%rbp),%rax
mov    0x8(%rax),%rcx
mov    -0x10(%rbp),%rax
sub    0x8(%rax),%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,0x8(%rax)
mov    -0x8(%rbp),%rax
mov    (%rax),%rcx
mov    -0x10(%rbp),%rax
sub    (%rax),%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x18(%rbp),%rax
cmpq   $0x0,(%rax)
jge    119f <time_diff+0x8f>
mov    -0x18(%rbp),%rax
mov    (%rax),%rcx
add    $0x3b9aca00,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%rcx
sub    $0x1,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,0x8(%rax)
jmp    120d <time_diff+0xfd>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rcx
mov    -0x8(%rbp),%rax
sub    0x8(%rax),%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,0x8(%rax)
mov    -0x10(%rbp),%rax
mov    (%rax),%rcx
mov    -0x8(%rbp),%rax
sub    (%rax),%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x18(%rbp),%rax
cmpq   $0x0,(%rax)
jge    1208 <time_diff+0xf8>
mov    -0x18(%rbp),%rax
mov    (%rax),%rcx
add    $0x3b9aca00,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x18(%rbp),%rax
mov    0x8(%rax),%rcx
sub    $0x1,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,0x8(%rax)
jmp    120d <time_diff+0xfd>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<time_diff>:
push   %r15
push   %r14
push   %rbx
mov    %rdx,%r14
mov    %rsi,%r15
mov    %rdi,%rbx
call   1030 <time_gt@plt>
test   %rax,%rax
je     1133 <time_diff+0x23>
movdqu (%rbx),%xmm0
movdqu (%r15),%xmm1
jmp    113c <time_diff+0x2c>
movdqu (%r15),%xmm0
movdqu (%rbx),%xmm1
psubq  %xmm1,%xmm0
movdqu %xmm0,(%r14)
movq   %xmm0,%rax
test   %rax,%rax
jns    116a <time_diff+0x5a>
pshufd $0xee,%xmm0,%xmm0
movq   %xmm0,%rcx
add    $0x3b9aca00,%rax
mov    %rax,(%r14)
add    $0xffffffffffffffff,%rcx
mov    %rcx,0x8(%r14)
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
%struct.timespec = type { i64, i64 }
define void @time_diff(%struct.timespec* %0, %struct.timespec* %1, %struct.timespec* %2) {
%4 = alloca %struct.timespec*
%5 = alloca %struct.timespec*
%6 = alloca %struct.timespec*
store %struct.timespec* %0, %struct.timespec** %4
store %struct.timespec* %1, %struct.timespec** %5
store %struct.timespec* %2, %struct.timespec** %6
%7 = load %struct.timespec*, %struct.timespec** %4
%8 = load %struct.timespec*, %struct.timespec** %5
%9 = call i64 @time_gt(%struct.timespec* %7, %struct.timespec* %8)
%10 = icmp ne i64 %9, 0
br i1 %10, label %11, label %48
11: ; preds = %3
%12 = load %struct.timespec*, %struct.timespec** %4
%13 = getelementptr inbounds %struct.timespec, %struct.timespec* %12, i32 0, i32 1
%14 = load i64, i64* %13
%15 = load %struct.timespec*, %struct.timespec** %5
%16 = getelementptr inbounds %struct.timespec, %struct.timespec* %15, i32 0, i32 1
%17 = load i64, i64* %16
%18 = sub nsw i64 %14, %17
%19 = load %struct.timespec*, %struct.timespec** %6
%20 = getelementptr inbounds %struct.timespec, %struct.timespec* %19, i32 0, i32 1
store i64 %18, i64* %20
%21 = load %struct.timespec*, %struct.timespec** %4
%22 = getelementptr inbounds %struct.timespec, %struct.timespec* %21, i32 0, i32 0
%23 = load i64, i64* %22
%24 = load %struct.timespec*, %struct.timespec** %5
%25 = getelementptr inbounds %struct.timespec, %struct.timespec* %24, i32 0, i32 0
%26 = load i64, i64* %25
%27 = sub nsw i64 %23, %26
%28 = load %struct.timespec*, %struct.timespec** %6
%29 = getelementptr inbounds %struct.timespec, %struct.timespec* %28, i32 0, i32 0
store i64 %27, i64* %29
%30 = load %struct.timespec*, %struct.timespec** %6
%31 = getelementptr inbounds %struct.timespec, %struct.timespec* %30, i32 0, i32 0
%32 = load i64, i64* %31
%33 = icmp slt i64 %32, 0
br i1 %33, label %34, label %47
34: ; preds = %11
%35 = load %struct.timespec*, %struct.timespec** %6
%36 = getelementptr inbounds %struct.timespec, %struct.timespec* %35, i32 0, i32 0
%37 = load i64, i64* %36
%38 = add nsw i64 1000000000, %37
%39 = load %struct.timespec*, %struct.timespec** %6
%40 = getelementptr inbounds %struct.timespec, %struct.timespec* %39, i32 0, i32 0
store i64 %38, i64* %40
%41 = load %struct.timespec*, %struct.timespec** %6
%42 = getelementptr inbounds %struct.timespec, %struct.timespec* %41, i32 0, i32 1
%43 = load i64, i64* %42
%44 = sub nsw i64 %43, 1
%45 = load %struct.timespec*, %struct.timespec** %6
%46 = getelementptr inbounds %struct.timespec, %struct.timespec* %45, i32 0, i32 1
store i64 %44, i64* %46
br label %47
47: ; preds = %34, %11
br label %85
48: ; preds = %3
%49 = load %struct.timespec*, %struct.timespec** %5
%50 = getelementptr inbounds %struct.timespec, %struct.timespec* %49, i32 0, i32 1
%51 = load i64, i64* %50
%52 = load %struct.timespec*, %struct.timespec** %4
%53 = getelementptr inbounds %struct.timespec, %struct.timespec* %52, i32 0, i32 1
%54 = load i64, i64* %53
%55 = sub nsw i64 %51, %54
%56 = load %struct.timespec*, %struct.timespec** %6
%57 = getelementptr inbounds %struct.timespec, %struct.timespec* %56, i32 0, i32 1
store i64 %55, i64* %57
%58 = load %struct.timespec*, %struct.timespec** %5
%59 = getelementptr inbounds %struct.timespec, %struct.timespec* %58, i32 0, i32 0
%60 = load i64, i64* %59
%61 = load %struct.timespec*, %struct.timespec** %4
%62 = getelementptr inbounds %struct.timespec, %struct.timespec* %61, i32 0, i32 0
%63 = load i64, i64* %62
%64 = sub nsw i64 %60, %63
%65 = load %struct.timespec*, %struct.timespec** %6
%66 = getelementptr inbounds %struct.timespec, %struct.timespec* %65, i32 0, i32 0
store i64 %64, i64* %66
%67 = load %struct.timespec*, %struct.timespec** %6
%68 = getelementptr inbounds %struct.timespec, %struct.timespec* %67, i32 0, i32 0
%69 = load i64, i64* %68
%70 = icmp slt i64 %69, 0
br i1 %70, label %71, label %84
71: ; preds = %48
%72 = load %struct.timespec*, %struct.timespec** %6
%73 = getelementptr inbounds %struct.timespec, %struct.timespec* %72, i32 0, i32 0
%74 = load i64, i64* %73
%75 = add nsw i64 1000000000, %74
%76 = load %struct.timespec*, %struct.timespec** %6
%77 = getelementptr inbounds %struct.timespec, %struct.timespec* %76, i32 0, i32 0
store i64 %75, i64* %77
%78 = load %struct.timespec*, %struct.timespec** %6
%79 = getelementptr inbounds %struct.timespec, %struct.timespec* %78, i32 0, i32 1
%80 = load i64, i64* %79
%81 = sub nsw i64 %80, 1
%82 = load %struct.timespec*, %struct.timespec** %6
%83 = getelementptr inbounds %struct.timespec, %struct.timespec* %82, i32 0, i32 1
store i64 %81, i64* %83
br label %84
84: ; preds = %71, %48
br label %85
85: ; preds = %84, %47
ret void
}

LLVM IR (-O2):
%struct.timespec = type { i64, i64 }
define void @time_diff(%struct.timespec* %0, %struct.timespec* %1, %struct.timespec* nocapture %2) {
%4 = tail call i64 @time_gt(%struct.timespec* %0, %struct.timespec* %1)
%5 = icmp eq i64 %4, 0
br i1 %5, label %16, label %6
6: ; preds = %3
%7 = bitcast %struct.timespec* %0 to <2 x i64>*
%8 = load <2 x i64>, <2 x i64>* %7
%9 = bitcast %struct.timespec* %1 to <2 x i64>*
%10 = load <2 x i64>, <2 x i64>* %9
%11 = sub nsw <2 x i64> %8, %10
%12 = bitcast %struct.timespec* %2 to <2 x i64>*
store <2 x i64> %11, <2 x i64>* %12
%13 = extractelement <2 x i64> %11, i64 0
%14 = icmp slt i64 %13, 0
%15 = extractelement <2 x i64> %11, i64 1
br i1 %14, label %26, label %33
16: ; preds = %3
%17 = bitcast %struct.timespec* %1 to <2 x i64>*
%18 = load <2 x i64>, <2 x i64>* %17
%19 = bitcast %struct.timespec* %0 to <2 x i64>*
%20 = load <2 x i64>, <2 x i64>* %19
%21 = sub nsw <2 x i64> %18, %20
%22 = bitcast %struct.timespec* %2 to <2 x i64>*
store <2 x i64> %21, <2 x i64>* %22
%23 = extractelement <2 x i64> %21, i64 0
%24 = icmp slt i64 %23, 0
%25 = extractelement <2 x i64> %21, i64 1
br i1 %24, label %26, label %33
26: ; preds = %16, %6
%27 = phi i64 [ %13, %6 ], [ %23, %16 ]
%28 = phi i64 [ %15, %6 ], [ %25, %16 ]
%29 = getelementptr inbounds %struct.timespec, %struct.timespec* %2, i64 0, i32 1
%30 = getelementptr %struct.timespec, %struct.timespec* %2, i64 0, i32 0
%31 = add nsw i64 %27, 1000000000
store i64 %31, i64* %30
%32 = add nsw i64 %28, -1
store i64 %32, i64* %29
br label %33
33: ; preds = %26, %16, %6
ret void
}