#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 bessi0_spd(double);
double bessi1_spd(double);
double cos(double);
double marginal_j_concentration(int, int, double *, double *, double *,
                                double *);
double marginal_j_mean(int, int, double *, double *, double *, double *);
double sin(double);
double vm_marginalKapa_lambda_partial_naive(int, int, int, int, double *,
                                            double *, double *, double *);
double vm_marginalMu_lambda_partial_naive(int, int, int, int, double *,
                                          double *, double *, double *);
double vm_loglikelihood_lambda_partial_naive(int n, int p, int R, int S,
                                             double *mu, double *kappa,
                                             double *lambda, double *theta) {
  int j, i;
  double acum = 0.;
  double m_rest, k_rest;
  for (j = 0; j < p; j++) {
    if (R == j) {
      for (i = 0; i < n; i++) {
        k_rest =
            marginal_j_concentration(p, j, mu, kappa, lambda, theta + i * p);
        m_rest = marginal_j_mean(p, j, mu, kappa, lambda, theta + i * p);
        acum += (cos(theta[i * p + j] - m_rest) -
                 (bessi1_spd(k_rest) / bessi0_spd(k_rest))) *
                vm_marginalKapa_lambda_partial_naive(p, j, R, S, mu, kappa,
                                                     lambda, theta + i * p);
        acum += k_rest * sin(theta[i * p + j] - m_rest) *
                vm_marginalMu_lambda_partial_naive(p, j, R, S, mu, kappa,
                                                   lambda, theta + i * p);
      }
    }
  }
  return -acum;
}


x86 assembly (clang, -O0):
<vm_loglikelihood_lambda_partial_naive>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%rax
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    %ecx,-0x10(%rbp)
mov    %r8,-0x18(%rbp)
mov    %r9,-0x20(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x30(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    13a8 <vm_loglikelihood_lambda_partial_naive+0x228>
mov    -0xc(%rbp),%eax
cmp    -0x24(%rbp),%eax
jne    1395 <vm_loglikelihood_lambda_partial_naive+0x215>
movl   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    1390 <vm_loglikelihood_lambda_partial_naive+0x210>
mov    -0x8(%rbp),%edi
mov    -0x24(%rbp),%esi
mov    -0x18(%rbp),%rdx
mov    -0x20(%rbp),%rcx
mov    0x10(%rbp),%r8
mov    0x18(%rbp),%r9
mov    -0x28(%rbp),%eax
imul   -0x8(%rbp),%eax
cltq
shl    $0x3,%rax
add    %rax,%r9
call   1030 <marginal_j_concentration@plt>
movsd  %xmm0,-0x40(%rbp)
mov    -0x8(%rbp),%edi
mov    -0x24(%rbp),%esi
mov    -0x18(%rbp),%rdx
mov    -0x20(%rbp),%rcx
mov    0x10(%rbp),%r8
mov    0x18(%rbp),%r9
mov    -0x28(%rbp),%eax
imul   -0x8(%rbp),%eax
cltq
shl    $0x3,%rax
add    %rax,%r9
call   1050 <marginal_j_mean@plt>
movsd  %xmm0,-0x38(%rbp)
mov    0x18(%rbp),%rax
mov    -0x28(%rbp),%ecx
imul   -0x8(%rbp),%ecx
add    -0x24(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
subsd  -0x38(%rbp),%xmm0
call   1090 <cos@plt>
movsd  %xmm0,-0x60(%rbp)
movsd  -0x40(%rbp),%xmm0
call   10a0 <bessi1_spd@plt>
movsd  %xmm0,-0x68(%rbp)
movsd  -0x40(%rbp),%xmm0
call   1060 <bessi0_spd@plt>
movsd  -0x68(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x60(%rbp),%xmm0
divsd  %xmm2,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x8(%rbp),%edi
mov    -0x24(%rbp),%esi
mov    -0xc(%rbp),%edx
mov    -0x10(%rbp),%ecx
mov    -0x18(%rbp),%r8
mov    -0x20(%rbp),%r9
mov    0x10(%rbp),%r10
mov    0x18(%rbp),%rax
mov    -0x28(%rbp),%r11d
imul   -0x8(%rbp),%r11d
movslq %r11d,%r11
shl    $0x3,%r11
add    %r11,%rax
mov    %r10,(%rsp)
mov    %rax,0x8(%rsp)
call   1080 <vm_marginalKapa_lambda_partial_naive@plt>
movaps %xmm0,%xmm2
movsd  -0x58(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    0x18(%rbp),%rax
mov    -0x28(%rbp),%ecx
imul   -0x8(%rbp),%ecx
add    -0x24(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
subsd  -0x38(%rbp),%xmm0
call   1040 <sin@plt>
movaps %xmm0,%xmm1
movsd  -0x50(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x8(%rbp),%edi
mov    -0x24(%rbp),%esi
mov    -0xc(%rbp),%edx
mov    -0x10(%rbp),%ecx
mov    -0x18(%rbp),%r8
mov    -0x20(%rbp),%r9
mov    0x10(%rbp),%r10
mov    0x18(%rbp),%rax
mov    -0x28(%rbp),%r11d
imul   -0x8(%rbp),%r11d
movslq %r11d,%r11
shl    $0x3,%r11
add    %r11,%rax
mov    %r10,(%rsp)
mov    %rax,0x8(%rsp)
call   1070 <vm_marginalMu_lambda_partial_naive@plt>
movaps %xmm0,%xmm2
movsd  -0x48(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    11d5 <vm_loglikelihood_lambda_partial_naive+0x55>
jmp    1395 <vm_loglikelihood_lambda_partial_naive+0x215>
jmp    139a <vm_loglikelihood_lambda_partial_naive+0x21a>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    11b6 <vm_loglikelihood_lambda_partial_naive+0x36>
movsd  -0x30(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<vm_loglikelihood_lambda_partial_naive>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x88,%rsp
test   %esi,%esi
jle    136a <vm_loglikelihood_lambda_partial_naive+0x1ea>
mov    %edx,%ebp
mov    %r8,0x50(%rsp)
mov    %r9,0x28(%rsp)
mov    %esi,0x24(%rsp)
mov    %esi,%eax
mov    %edx,%edx
mov    %edi,%esi
mov    %rsi,0x30(%rsp)
mov    %rax,0x38(%rsp)
lea    0x0(,%rax,8),%rax
xorpd  %xmm0,%xmm0
xor    %esi,%esi
mov    %edi,0x1c(%rsp)
mov    %rax,0x48(%rsp)
mov    %ecx,0x20(%rsp)
mov    %rdx,0x10(%rsp)
mov    0x24(%rsp),%r14d
jmp    11fd <vm_loglikelihood_lambda_partial_naive+0x7d>
mov    0x40(%rsp),%rsi
add    $0x1,%rsi
cmp    0x38(%rsp),%rsi
mov    0x1c(%rsp),%edi
mov    0x10(%rsp),%rdx
je     136e <vm_loglikelihood_lambda_partial_naive+0x1ee>
cmp    %rdx,%rsi
mov    %rsi,0x40(%rsp)
jne    11e0 <vm_loglikelihood_lambda_partial_naive+0x60>
test   %edi,%edi
jle    11e0 <vm_loglikelihood_lambda_partial_naive+0x60>
mov    0x30(%rsp),%r13
mov    0xc8(%rsp),%r15
nopl   0x0(%rax,%rax,1)
movapd %xmm0,0x70(%rsp)
mov    %r13,0x68(%rsp)
mov    %r14d,%edi
mov    %ebp,%esi
mov    0x50(%rsp),%r13
mov    %r13,%rdx
mov    0x28(%rsp),%rbx
mov    %rbx,%rcx
mov    0xc0(%rsp),%r12
mov    %r12,%r8
mov    %r15,%r9
call   1030 <marginal_j_concentration@plt>
movsd  %xmm0,0x8(%rsp)
mov    %r14d,%edi
mov    %ebp,%esi
mov    %r13,%rdx
mov    %rbx,%rcx
mov    %r12,%r8
mov    %r15,%r9
call   1050 <marginal_j_mean@plt>
movapd %xmm0,%xmm1
movsd  %xmm0,0x60(%rsp)
mov    0x10(%rsp),%rax
movsd  (%r15,%rax,8),%xmm0
subsd  %xmm1,%xmm0
call   1090 <cos@plt>
movsd  %xmm0,(%rsp)
movsd  0x8(%rsp),%xmm0
call   10a0 <bessi1_spd@plt>
movsd  %xmm0,0x58(%rsp)
movsd  0x8(%rsp),%xmm0
call   1060 <bessi0_spd@plt>
movsd  0x58(%rsp),%xmm1
divsd  %xmm0,%xmm1
movsd  (%rsp),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,(%rsp)
mov    %r14d,%edi
mov    %ebp,%esi
mov    %ebp,%edx
mov    0x20(%rsp),%ebx
mov    %ebx,%ecx
mov    %r13,%r8
mov    0x28(%rsp),%r12
mov    %r12,%r9
push   %r15
push   0xc8(%rsp)
call   1080 <vm_marginalKapa_lambda_partial_naive@plt>
add    $0x10,%rsp
mulsd  (%rsp),%xmm0
addsd  0x70(%rsp),%xmm0
movsd  %xmm0,(%rsp)
mov    0x10(%rsp),%rax
movsd  (%r15,%rax,8),%xmm0
subsd  0x60(%rsp),%xmm0
call   1040 <sin@plt>
mulsd  0x8(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
mov    %r14d,%edi
mov    %ebp,%esi
mov    %ebp,%edx
mov    %ebx,%ecx
mov    %r13,%r8
mov    %r12,%r9
push   %r15
push   0xc8(%rsp)
call   1070 <vm_marginalMu_lambda_partial_naive@plt>
mov    0x78(%rsp),%r13
mov    0x58(%rsp),%rax
add    $0x10,%rsp
mulsd  0x8(%rsp),%xmm0
addsd  (%rsp),%xmm0
add    %rax,%r15
add    $0xffffffffffffffff,%r13
jne    1220 <vm_loglikelihood_lambda_partial_naive+0xa0>
jmp    11e0 <vm_loglikelihood_lambda_partial_naive+0x60>
xorpd  %xmm0,%xmm0
xorpd  0xc8a(%rip),%xmm0
add    $0x88,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define double @vm_loglikelihood_lambda_partial_naive(i32 %0, i32 %1, i32 %2, i32 %3, double* %4, double* %5, double* %6, double* %7) {
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca double*
%14 = alloca double*
%15 = alloca double*
%16 = alloca double*
%17 = alloca i32
%18 = alloca i32
%19 = alloca double
%20 = alloca double
%21 = alloca double
store i32 %0, i32* %9
store i32 %1, i32* %10
store i32 %2, i32* %11
store i32 %3, i32* %12
store double* %4, double** %13
store double* %5, double** %14
store double* %6, double** %15
store double* %7, double** %16
store double 0.000000e+00, double* %19
store i32 0, i32* %17
br label %22
22: ; preds = %129, %8
%23 = load i32, i32* %17
%24 = load i32, i32* %10
%25 = icmp slt i32 %23, %24
br i1 %25, label %26, label %132
26: ; preds = %22
%27 = load i32, i32* %11
%28 = load i32, i32* %17
%29 = icmp eq i32 %27, %28
br i1 %29, label %30, label %128
30: ; preds = %26
store i32 0, i32* %18
br label %31
31: ; preds = %124, %30
%32 = load i32, i32* %18
%33 = load i32, i32* %9
%34 = icmp slt i32 %32, %33
br i1 %34, label %35, label %127
35: ; preds = %31
%36 = load i32, i32* %10
%37 = load i32, i32* %17
%38 = load double*, double** %13
%39 = load double*, double** %14
%40 = load double*, double** %15
%41 = load double*, double** %16
%42 = load i32, i32* %18
%43 = load i32, i32* %10
%44 = mul nsw i32 %42, %43
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds double, double* %41, i64 %45
%47 = call double @marginal_j_concentration(i32 %36, i32 %37, double* %38, double* %39, double* %40, double* %46)
store double %47, double* %21
%48 = load i32, i32* %10
%49 = load i32, i32* %17
%50 = load double*, double** %13
%51 = load double*, double** %14
%52 = load double*, double** %15
%53 = load double*, double** %16
%54 = load i32, i32* %18
%55 = load i32, i32* %10
%56 = mul nsw i32 %54, %55
%57 = sext i32 %56 to i64
%58 = getelementptr inbounds double, double* %53, i64 %57
%59 = call double @marginal_j_mean(i32 %48, i32 %49, double* %50, double* %51, double* %52, double* %58)
store double %59, double* %20
%60 = load double*, double** %16
%61 = load i32, i32* %18
%62 = load i32, i32* %10
%63 = mul nsw i32 %61, %62
%64 = load i32, i32* %17
%65 = add nsw i32 %63, %64
%66 = sext i32 %65 to i64
%67 = getelementptr inbounds double, double* %60, i64 %66
%68 = load double, double* %67
%69 = load double, double* %20
%70 = fsub double %68, %69
%71 = call double @cos(double %70)
%72 = load double, double* %21
%73 = call double @bessi1_spd(double %72)
%74 = load double, double* %21
%75 = call double @bessi0_spd(double %74)
%76 = fdiv double %73, %75
%77 = fsub double %71, %76
%78 = load i32, i32* %10
%79 = load i32, i32* %17
%80 = load i32, i32* %11
%81 = load i32, i32* %12
%82 = load double*, double** %13
%83 = load double*, double** %14
%84 = load double*, double** %15
%85 = load double*, double** %16
%86 = load i32, i32* %18
%87 = load i32, i32* %10
%88 = mul nsw i32 %86, %87
%89 = sext i32 %88 to i64
%90 = getelementptr inbounds double, double* %85, i64 %89
%91 = call double @vm_marginalKapa_lambda_partial_naive(i32 %78, i32 %79, i32 %80, i32 %81, double* %82, double* %83, double* %84, double* %90)
%92 = load double, double* %19
%93 = call double @llvm.fmuladd.f64(double %77, double %91, double %92)
store double %93, double* %19
%94 = load double, double* %21
%95 = load double*, double** %16
%96 = load i32, i32* %18
%97 = load i32, i32* %10
%98 = mul nsw i32 %96, %97
%99 = load i32, i32* %17
%100 = add nsw i32 %98, %99
%101 = sext i32 %100 to i64
%102 = getelementptr inbounds double, double* %95, i64 %101
%103 = load double, double* %102
%104 = load double, double* %20
%105 = fsub double %103, %104
%106 = call double @sin(double %105)
%107 = fmul double %94, %106
%108 = load i32, i32* %10
%109 = load i32, i32* %17
%110 = load i32, i32* %11
%111 = load i32, i32* %12
%112 = load double*, double** %13
%113 = load double*, double** %14
%114 = load double*, double** %15
%115 = load double*, double** %16
%116 = load i32, i32* %18
%117 = load i32, i32* %10
%118 = mul nsw i32 %116, %117
%119 = sext i32 %118 to i64
%120 = getelementptr inbounds double, double* %115, i64 %119
%121 = call double @vm_marginalMu_lambda_partial_naive(i32 %108, i32 %109, i32 %110, i32 %111, double* %112, double* %113, double* %114, double* %120)
%122 = load double, double* %19
%123 = call double @llvm.fmuladd.f64(double %107, double %121, double %122)
store double %123, double* %19
br label %124
124: ; preds = %35
%125 = load i32, i32* %18
%126 = add nsw i32 %125, 1
store i32 %126, i32* %18
br label %31
127: ; preds = %31
br label %128
128: ; preds = %127, %26
br label %129
129: ; preds = %128
%130 = load i32, i32* %17
%131 = add nsw i32 %130, 1
store i32 %131, i32* %17
br label %22
132: ; preds = %22
%133 = load double, double* %19
%134 = fneg double %133
ret double %134
}

LLVM IR (-O2):
define double @vm_loglikelihood_lambda_partial_naive(i32 %0, i32 %1, i32 %2, i32 %3, double* %4, double* %5, double* %6, double* %7) {
%9 = icmp sgt i32 %1, 0
br i1 %9, label %10, label %51
10: ; preds = %8
%11 = icmp slt i32 %0, 1
%12 = zext i32 %1 to i64
%13 = zext i32 %2 to i64
%14 = zext i32 %1 to i64
%15 = zext i32 %0 to i64
br label %16
16: ; preds = %10, %47
%17 = phi i64 [ 0, %10 ], [ %49, %47 ]
%18 = phi double [ 0.000000e+00, %10 ], [ %48, %47 ]
%19 = icmp ne i64 %17, %13
%20 = or i1 %19, %11
br i1 %20, label %47, label %21
21: ; preds = %16, %21
%22 = phi i64 [ %45, %21 ], [ 0, %16 ]
%23 = phi double [ %44, %21 ], [ %18, %16 ]
%24 = mul nsw i64 %22, %12
%25 = getelementptr inbounds double, double* %7, i64 %24
%26 = tail call double @marginal_j_concentration(i32 %1, i32 %2, double* %4, double* %5, double* %6, double* %25)
%27 = tail call double @marginal_j_mean(i32 %1, i32 %2, double* %4, double* %5, double* %6, double* %25)
%28 = add nuw nsw i64 %24, %13
%29 = getelementptr inbounds double, double* %7, i64 %28
%30 = load double, double* %29
%31 = fsub double %30, %27
%32 = tail call double @cos(double %31)
%33 = tail call double @bessi1_spd(double %26)
%34 = tail call double @bessi0_spd(double %26)
%35 = fdiv double %33, %34
%36 = fsub double %32, %35
%37 = tail call double @vm_marginalKapa_lambda_partial_naive(i32 %1, i32 %2, i32 %2, i32 %3, double* %4, double* %5, double* %6, double* %25)
%38 = tail call double @llvm.fmuladd.f64(double %36, double %37, double %23)
%39 = load double, double* %29
%40 = fsub double %39, %27
%41 = tail call double @sin(double %40)
%42 = fmul double %26, %41
%43 = tail call double @vm_marginalMu_lambda_partial_naive(i32 %1, i32 %2, i32 %2, i32 %3, double* %4, double* %5, double* %6, double* %25)
%44 = tail call double @llvm.fmuladd.f64(double %42, double %43, double %38)
%45 = add nuw nsw i64 %22, 1
%46 = icmp eq i64 %45, %15
br i1 %46, label %47, label %21
47: ; preds = %21, %16
%48 = phi double [ %18, %16 ], [ %44, %21 ]
%49 = add nuw nsw i64 %17, 1
%50 = icmp eq i64 %49, %14
br i1 %50, label %51, label %16
51: ; preds = %47, %8
%52 = phi double [ 0.000000e+00, %8 ], [ %48, %47 ]
%53 = fneg double %52
ret double %53
}