#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 */

/* Variables and functions */
double fb_hGetFirstWeekOfYear(int, int, int);
int fb_hGetWeeksOfYear(int ref_year, int first_day_of_year,
                       int first_day_of_week) {
  double serial_start =
      fb_hGetFirstWeekOfYear(ref_year, first_day_of_year, first_day_of_week);
  double serial_end = fb_hGetFirstWeekOfYear(ref_year + 1, first_day_of_year,
                                             first_day_of_week);
  return (int)((serial_end - serial_start) / 7.0l);
}


x86 assembly (clang, -O0):
<fb_hGetWeeksOfYear>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    -0x4(%rbp),%edi
mov    -0x8(%rbp),%esi
mov    -0xc(%rbp),%edx
call   1030 <fb_hGetFirstWeekOfYear@plt>
movsd  %xmm0,-0x18(%rbp)
mov    -0x4(%rbp),%edi
add    $0x1,%edi
mov    -0x8(%rbp),%esi
mov    -0xc(%rbp),%edx
call   1030 <fb_hGetFirstWeekOfYear@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
fldl   -0x30(%rbp)
flds   0xe9a(%rip)
fdivrp %st,%st(1)
fnstcw -0x32(%rbp)
movzwl -0x32(%rbp),%eax
or     $0xc00,%eax
mov    %ax,-0x34(%rbp)
fldcw  -0x34(%rbp)
fistpl -0x24(%rbp)
fldcw  -0x32(%rbp)
mov    -0x24(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fb_hGetWeeksOfYear>:
push   %rbp
push   %r14
push   %rbx
sub    $0x20,%rsp
mov    %edx,%r14d
mov    %esi,%ebp
mov    %edi,%ebx
call   1030 <fb_hGetFirstWeekOfYear@plt>
movsd  %xmm0,0x10(%rsp)
add    $0x1,%ebx
mov    %ebx,%edi
mov    %ebp,%esi
mov    %r14d,%edx
call   1030 <fb_hGetFirstWeekOfYear@plt>
subsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x18(%rsp)
fldl   0x18(%rsp)
fdivs  0xeb1(%rip)
fnstcw 0x8(%rsp)
movzwl 0x8(%rsp),%eax
or     $0xc00,%eax
mov    %ax,0xa(%rsp)
fldcw  0xa(%rsp)
fistpl 0xc(%rsp)
fldcw  0x8(%rsp)
mov    0xc(%rsp),%eax
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define i32 @fb_hGetWeeksOfYear(i32 %0, i32 %1, i32 %2) {
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca double
%8 = alloca double
store i32 %0, i32* %4
store i32 %1, i32* %5
store i32 %2, i32* %6
%9 = load i32, i32* %4
%10 = load i32, i32* %5
%11 = load i32, i32* %6
%12 = call double @fb_hGetFirstWeekOfYear(i32 %9, i32 %10, i32 %11)
store double %12, double* %7
%13 = load i32, i32* %4
%14 = add nsw i32 %13, 1
%15 = load i32, i32* %5
%16 = load i32, i32* %6
%17 = call double @fb_hGetFirstWeekOfYear(i32 %14, i32 %15, i32 %16)
store double %17, double* %8
%18 = load double, double* %8
%19 = load double, double* %7
%20 = fsub double %18, %19
%21 = fpext double %20 to x86_fp80
%22 = fdiv x86_fp80 %21, 0xK4001E000000000000000
%23 = fptosi x86_fp80 %22 to i32
ret i32 %23
}

LLVM IR (-O2):
define i32 @fb_hGetWeeksOfYear(i32 %0, i32 %1, i32 %2) {
%4 = tail call double @fb_hGetFirstWeekOfYear(i32 %0, i32 %1, i32 %2)
%5 = add nsw i32 %0, 1
%6 = tail call double @fb_hGetFirstWeekOfYear(i32 %5, i32 %1, i32 %2)
%7 = fsub double %6, %4
%8 = fpext double %7 to x86_fp80
%9 = fdiv x86_fp80 %8, 0xK4001E000000000000000
%10 = fptosi x86_fp80 %9 to i32
ret i32 %10
}