void core_site_likelihood_derivatives(
    unsigned int states, unsigned int states_padded, unsigned int rate_cats,
    const double *rate_weights, const int *invariant, const double *prop_invar,
    double *const *freqs, const double *sumtable, const double *diagptable,
    double *site_lk) {
  unsigned int i, j;
  double inv_site_lk = 0.0;
  double cat_sitelk[3];
  const double *sum = sumtable;
  const double *diagp = diagptable;
  const double *t_freqs;
  double t_prop_invar;
  site_lk[0] = site_lk[1] = site_lk[2] = 0;
  for (i = 0; i < rate_cats; ++i) {
    t_freqs = freqs[i];
    cat_sitelk[0] = cat_sitelk[1] = cat_sitelk[2] = 0;
    for (j = 0; j < states; ++j) {
      cat_sitelk[0] += sum[j] * diagp[0];
      cat_sitelk[1] += sum[j] * diagp[1];
      cat_sitelk[2] += sum[j] * diagp[2];
      diagp += 4;
    }
    t_prop_invar = prop_invar[i];
    if (t_prop_invar > 0) {
      inv_site_lk =
          (invariant[0] == -1) ? 0 : t_freqs[invariant[0]] * t_prop_invar;
      cat_sitelk[0] = cat_sitelk[0] * (1. - t_prop_invar) + inv_site_lk;
      cat_sitelk[1] = cat_sitelk[1] * (1. - t_prop_invar);
      cat_sitelk[2] = cat_sitelk[2] * (1. - t_prop_invar);
    }
    site_lk[0] += cat_sitelk[0] * rate_weights[i];
    site_lk[1] += cat_sitelk[1] * rate_weights[i];
    site_lk[2] += cat_sitelk[2] * rate_weights[i];
    sum += states_padded;
  }
}


x86 assembly (clang, -O0):
<core_site_likelihood_derivatives>:
push   %rbp
mov    %rsp,%rbp
mov    0x28(%rbp),%rax
mov    0x20(%rbp),%rax
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%rax
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    %rcx,-0x18(%rbp)
mov    %r8,-0x20(%rbp)
mov    %r9,-0x28(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    0x18(%rbp),%rax
mov    %rax,-0x58(%rbp)
mov    0x20(%rbp),%rax
mov    %rax,-0x60(%rbp)
mov    0x28(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,0x10(%rax)
mov    0x28(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,0x8(%rax)
mov    0x28(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax)
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jae    138f <core_site_likelihood_derivatives+0x28f>
mov    0x10(%rbp),%rax
mov    -0x2c(%rbp),%ecx
mov    (%rax,%rcx,8),%rax
mov    %rax,-0x68(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x4(%rbp),%eax
jae    123f <core_site_likelihood_derivatives+0x13f>
mov    -0x58(%rbp),%rax
mov    -0x30(%rbp),%ecx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x60(%rbp),%rax
movsd  (%rax),%xmm2
movsd  -0x50(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x58(%rbp),%rax
mov    -0x30(%rbp),%ecx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x60(%rbp),%rax
movsd  0x8(%rax),%xmm2
movsd  -0x48(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x58(%rbp),%rax
mov    -0x30(%rbp),%ecx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x60(%rbp),%rax
movsd  0x10(%rax),%xmm2
movsd  -0x40(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x60(%rbp),%rax
add    $0x20,%rax
mov    %rax,-0x60(%rbp)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    11a5 <core_site_likelihood_derivatives+0xa5>
mov    -0x28(%rbp),%rax
mov    -0x2c(%rbp),%ecx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x70(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    12fa <core_site_likelihood_derivatives+0x1fa>
mov    -0x20(%rbp),%rax
cmpl   $0xffffffff,(%rax)
jne    127c <core_site_likelihood_derivatives+0x17c>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x78(%rbp)
jmp    1296 <core_site_likelihood_derivatives+0x196>
mov    -0x68(%rbp),%rax
mov    -0x20(%rbp),%rcx
movslq (%rcx),%rcx
movsd  (%rax,%rcx,8),%xmm0
mulsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0x78(%rbp)
movsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x50(%rbp),%xmm0
movsd  0xd53(%rip),%xmm2
subsd  -0x70(%rbp),%xmm2
movsd  -0x38(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x48(%rbp),%xmm0
movsd  0xd2f(%rip),%xmm1
subsd  -0x70(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  0xd14(%rip),%xmm1
subsd  -0x70(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x50(%rbp),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x2c(%rbp),%ecx
movsd  (%rax,%rcx,8),%xmm2
mov    0x28(%rbp),%rax
movsd  (%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
movsd  -0x48(%rbp),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x2c(%rbp),%ecx
movsd  (%rax,%rcx,8),%xmm2
mov    0x28(%rbp),%rax
movsd  0x8(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x8(%rax)
movsd  -0x40(%rbp),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x2c(%rbp),%ecx
movsd  (%rax,%rcx,8),%xmm2
mov    0x28(%rbp),%rax
movsd  0x10(%rax),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x10(%rax)
mov    -0x8(%rbp),%ecx
mov    -0x58(%rbp),%rax
mov    %ecx,%ecx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x58(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    116b <core_site_likelihood_derivatives+0x6b>
pop    %rbp
ret

x86 assembly (clang, -O2):
<core_site_likelihood_derivatives>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    0x50(%rsp),%r10
xorpd  %xmm0,%xmm0
movupd %xmm0,(%r10)
movq   $0x0,0x10(%r10)
test   %edx,%edx
je     12d1 <core_site_likelihood_derivatives+0x1d1>
mov    0x48(%rsp),%rax
mov    0x40(%rsp),%r11
mov    0x38(%rsp),%r14
mov    %esi,%r13d
mov    %edx,%r12d
mov    %edi,%r15d
mov    %r15d,%ebx
and    $0xfffffffe,%ebx
shl    $0x3,%r13
xorpd  %xmm9,%xmm9
xor    %edx,%edx
movsd  0xea6(%rip),%xmm8
xorpd  %xmm10,%xmm10
xorpd  %xmm3,%xmm3
xorpd  %xmm4,%xmm4
jmp    11dc <core_site_likelihood_derivatives+0xdc>
nopl   0x0(%rax)
mov    (%r14,%rdx,8),%rbp
movsd  0x0(%rbp,%rsi,8),%xmm7
mulsd  %xmm1,%xmm7
movapd %xmm8,%xmm0
subsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm6
addsd  %xmm7,%xmm6
unpcklpd %xmm0,%xmm0
mulpd  %xmm0,%xmm5
mulsd  (%rcx,%rdx,8),%xmm6
addsd  %xmm6,%xmm4
movsd  %xmm4,(%r10)
movsd  (%rcx,%rdx,8),%xmm0
mulsd  %xmm5,%xmm0
addsd  %xmm0,%xmm3
movsd  %xmm3,0x8(%r10)
unpckhpd %xmm5,%xmm5
mulsd  (%rcx,%rdx,8),%xmm5
addsd  %xmm5,%xmm10
movsd  %xmm10,0x10(%r10)
add    %r13,%r11
add    $0x1,%rdx
cmp    %r12,%rdx
je     12d1 <core_site_likelihood_derivatives+0x1d1>
xorpd  %xmm7,%xmm7
test   %edi,%edi
je     1200 <core_site_likelihood_derivatives+0x100>
cmp    $0x1,%edi
jne    1210 <core_site_likelihood_derivatives+0x110>
xor    %esi,%esi
xorpd  %xmm6,%xmm6
test   $0x1,%r15b
jne    1283 <core_site_likelihood_derivatives+0x183>
jmp    12aa <core_site_likelihood_derivatives+0x1aa>
xchg   %ax,%ax
xorpd  %xmm6,%xmm6
xorpd  %xmm5,%xmm5
jmp    12aa <core_site_likelihood_derivatives+0x1aa>
nopl   (%rax)
xorpd  %xmm7,%xmm7
xorpd  %xmm6,%xmm6
xor    %esi,%esi
nopw   0x0(%rax,%rax,1)
movsd  (%r11,%rsi,8),%xmm0
movsd  0x8(%r11,%rsi,8),%xmm5
movsd  (%rax),%xmm2
mulsd  %xmm0,%xmm2
addsd  %xmm6,%xmm2
unpcklpd %xmm0,%xmm0
movupd 0x8(%rax),%xmm1
mulpd  %xmm0,%xmm1
addpd  %xmm7,%xmm1
movupd 0x28(%rax),%xmm0
movsd  0x20(%rax),%xmm6
mulsd  %xmm5,%xmm6
addsd  %xmm2,%xmm6
unpcklpd %xmm5,%xmm5
mulpd  %xmm0,%xmm5
movapd %xmm5,%xmm7
addpd  %xmm1,%xmm7
add    $0x40,%rax
add    $0x2,%rsi
cmp    %rsi,%rbx
jne    1220 <core_site_likelihood_derivatives+0x120>
addpd  %xmm1,%xmm5
test   $0x1,%r15b
je     12aa <core_site_likelihood_derivatives+0x1aa>
movsd  (%r11,%rsi,8),%xmm5
movsd  (%rax),%xmm0
mulsd  %xmm5,%xmm0
addsd  %xmm0,%xmm6
movupd 0x8(%rax),%xmm0
unpcklpd %xmm5,%xmm5
mulpd  %xmm0,%xmm5
addpd  %xmm7,%xmm5
add    $0x20,%rax
movsd  (%r9,%rdx,8),%xmm1
ucomisd %xmm9,%xmm1
jbe    1197 <core_site_likelihood_derivatives+0x97>
movslq (%r8),%rsi
cmp    $0xffffffffffffffff,%rsi
jne    1170 <core_site_likelihood_derivatives+0x70>
xorpd  %xmm7,%xmm7
jmp    117e <core_site_likelihood_derivatives+0x7e>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @core_site_likelihood_derivatives(i32 %0, i32 %1, i32 %2, double* %3, i32* %4, double* %5, double** %6, double* %7, double* %8, double* %9) {
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca double*
%15 = alloca i32*
%16 = alloca double*
%17 = alloca double**
%18 = alloca double*
%19 = alloca double*
%20 = alloca double*
%21 = alloca i32
%22 = alloca i32
%23 = alloca double
%24 = alloca [3 x double]
%25 = alloca double*
%26 = alloca double*
%27 = alloca double*
%28 = alloca double
store i32 %0, i32* %11
store i32 %1, i32* %12
store i32 %2, i32* %13
store double* %3, double** %14
store i32* %4, i32** %15
store double* %5, double** %16
store double** %6, double*** %17
store double* %7, double** %18
store double* %8, double** %19
store double* %9, double** %20
store double 0.000000e+00, double* %23
%29 = load double*, double** %18
store double* %29, double** %25
%30 = load double*, double** %19
store double* %30, double** %26
%31 = load double*, double** %20
%32 = getelementptr inbounds double, double* %31, i64 2
store double 0.000000e+00, double* %32
%33 = load double*, double** %20
%34 = getelementptr inbounds double, double* %33, i64 1
store double 0.000000e+00, double* %34
%35 = load double*, double** %20
%36 = getelementptr inbounds double, double* %35, i64 0
store double 0.000000e+00, double* %36
store i32 0, i32* %21
br label %37
37: ; preds = %176, %10
%38 = load i32, i32* %21
%39 = load i32, i32* %13
%40 = icmp ult i32 %38, %39
br i1 %40, label %41, label %179
41: ; preds = %37
%42 = load double**, double*** %17
%43 = load i32, i32* %21
%44 = zext i32 %43 to i64
%45 = getelementptr inbounds double*, double** %42, i64 %44
%46 = load double*, double** %45
store double* %46, double** %27
%47 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 2
store double 0.000000e+00, double* %47
%48 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 1
store double 0.000000e+00, double* %48
%49 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 0
store double 0.000000e+00, double* %49
store i32 0, i32* %22
br label %50
50: ; preds = %90, %41
%51 = load i32, i32* %22
%52 = load i32, i32* %11
%53 = icmp ult i32 %51, %52
br i1 %53, label %54, label %93
54: ; preds = %50
%55 = load double*, double** %25
%56 = load i32, i32* %22
%57 = zext i32 %56 to i64
%58 = getelementptr inbounds double, double* %55, i64 %57
%59 = load double, double* %58
%60 = load double*, double** %26
%61 = getelementptr inbounds double, double* %60, i64 0
%62 = load double, double* %61
%63 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 0
%64 = load double, double* %63
%65 = call double @llvm.fmuladd.f64(double %59, double %62, double %64)
store double %65, double* %63
%66 = load double*, double** %25
%67 = load i32, i32* %22
%68 = zext i32 %67 to i64
%69 = getelementptr inbounds double, double* %66, i64 %68
%70 = load double, double* %69
%71 = load double*, double** %26
%72 = getelementptr inbounds double, double* %71, i64 1
%73 = load double, double* %72
%74 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 1
%75 = load double, double* %74
%76 = call double @llvm.fmuladd.f64(double %70, double %73, double %75)
store double %76, double* %74
%77 = load double*, double** %25
%78 = load i32, i32* %22
%79 = zext i32 %78 to i64
%80 = getelementptr inbounds double, double* %77, i64 %79
%81 = load double, double* %80
%82 = load double*, double** %26
%83 = getelementptr inbounds double, double* %82, i64 2
%84 = load double, double* %83
%85 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 2
%86 = load double, double* %85
%87 = call double @llvm.fmuladd.f64(double %81, double %84, double %86)
store double %87, double* %85
%88 = load double*, double** %26
%89 = getelementptr inbounds double, double* %88, i64 4
store double* %89, double** %26
br label %90
90: ; preds = %54
%91 = load i32, i32* %22
%92 = add i32 %91, 1
store i32 %92, i32* %22
br label %50
93: ; preds = %50
%94 = load double*, double** %16
%95 = load i32, i32* %21
%96 = zext i32 %95 to i64
%97 = getelementptr inbounds double, double* %94, i64 %96
%98 = load double, double* %97
store double %98, double* %28
%99 = load double, double* %28
%100 = fcmp ogt double %99, 0.000000e+00
br i1 %100, label %101, label %138
101: ; preds = %93
%102 = load i32*, i32** %15
%103 = getelementptr inbounds i32, i32* %102, i64 0
%104 = load i32, i32* %103
%105 = icmp eq i32 %104, -1
br i1 %105, label %106, label %107
106: ; preds = %101
br label %117
107: ; preds = %101
%108 = load double*, double** %27
%109 = load i32*, i32** %15
%110 = getelementptr inbounds i32, i32* %109, i64 0
%111 = load i32, i32* %110
%112 = sext i32 %111 to i64
%113 = getelementptr inbounds double, double* %108, i64 %112
%114 = load double, double* %113
%115 = load double, double* %28
%116 = fmul double %114, %115
br label %117
117: ; preds = %107, %106
%118 = phi double [ 0.000000e+00, %106 ], [ %116, %107 ]
store double %118, double* %23
%119 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 0
%120 = load double, double* %119
%121 = load double, double* %28
%122 = fsub double 1.000000e+00, %121
%123 = load double, double* %23
%124 = call double @llvm.fmuladd.f64(double %120, double %122, double %123)
%125 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 0
store double %124, double* %125
%126 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 1
%127 = load double, double* %126
%128 = load double, double* %28
%129 = fsub double 1.000000e+00, %128
%130 = fmul double %127, %129
%131 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 1
store double %130, double* %131
%132 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 2
%133 = load double, double* %132
%134 = load double, double* %28
%135 = fsub double 1.000000e+00, %134
%136 = fmul double %133, %135
%137 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 2
store double %136, double* %137
br label %138
138: ; preds = %117, %93
%139 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 0
%140 = load double, double* %139
%141 = load double*, double** %14
%142 = load i32, i32* %21
%143 = zext i32 %142 to i64
%144 = getelementptr inbounds double, double* %141, i64 %143
%145 = load double, double* %144
%146 = load double*, double** %20
%147 = getelementptr inbounds double, double* %146, i64 0
%148 = load double, double* %147
%149 = call double @llvm.fmuladd.f64(double %140, double %145, double %148)
store double %149, double* %147
%150 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 1
%151 = load double, double* %150
%152 = load double*, double** %14
%153 = load i32, i32* %21
%154 = zext i32 %153 to i64
%155 = getelementptr inbounds double, double* %152, i64 %154
%156 = load double, double* %155
%157 = load double*, double** %20
%158 = getelementptr inbounds double, double* %157, i64 1
%159 = load double, double* %158
%160 = call double @llvm.fmuladd.f64(double %151, double %156, double %159)
store double %160, double* %158
%161 = getelementptr inbounds [3 x double], [3 x double]* %24, i64 0, i64 2
%162 = load double, double* %161
%163 = load double*, double** %14
%164 = load i32, i32* %21
%165 = zext i32 %164 to i64
%166 = getelementptr inbounds double, double* %163, i64 %165
%167 = load double, double* %166
%168 = load double*, double** %20
%169 = getelementptr inbounds double, double* %168, i64 2
%170 = load double, double* %169
%171 = call double @llvm.fmuladd.f64(double %162, double %167, double %170)
store double %171, double* %169
%172 = load i32, i32* %12
%173 = load double*, double** %25
%174 = zext i32 %172 to i64
%175 = getelementptr inbounds double, double* %173, i64 %174
store double* %175, double** %25
br label %176
176: ; preds = %138
%177 = load i32, i32* %21
%178 = add i32 %177, 1
store i32 %178, i32* %21
br label %37
179: ; preds = %37
ret void
}

LLVM IR (-O2):
define void @core_site_likelihood_derivatives(i32 %0, i32 %1, i32 %2, double* nocapture %3, i32* nocapture %4, double* nocapture %5, double** nocapture %6, double* nocapture %7, double* nocapture %8, double* nocapture %9) {
%11 = getelementptr inbounds double, double* %9, i64 2
%12 = getelementptr inbounds double, double* %9, i64 1
%13 = icmp eq i32 %2, 0
%14 = bitcast double* %9 to i8*
br i1 %13, label %123, label %15
15: ; preds = %10
%16 = zext i32 %1 to i64
%17 = zext i32 %2 to i64
%18 = zext i32 %0 to i64
%19 = and i64 %18, 1
%20 = icmp eq i32 %0, 1
%21 = and i64 %18, 4294967294
%22 = icmp eq i64 %19, 0
br label %23
23: ; preds = %15, %108
%24 = phi double [ 0.000000e+00, %15 ], [ %119, %108 ]
%25 = phi double [ 0.000000e+00, %15 ], [ %116, %108 ]
%26 = phi double [ 0.000000e+00, %15 ], [ %113, %108 ]
%27 = phi i64 [ 0, %15 ], [ %121, %108 ]
%28 = phi double* [ %8, %15 ], [ %88, %108 ]
%29 = phi double* [ %7, %15 ], [ %120, %108 ]
%30 = getelementptr inbounds double*, double** %6, i64 %27
%31 = load double*, double** %30
switch i32 %0, label %32 [
i32 0, label %86
i32 1, label %66
]
32: ; preds = %23, %32
%33 = phi i64 [ %61, %32 ], [ 0, %23 ]
%34 = phi double* [ %60, %32 ], [ %28, %23 ]
%35 = phi double [ %53, %32 ], [ 0.000000e+00, %23 ]
%36 = phi <2 x double> [ %59, %32 ], [ zeroinitializer, %23 ]
%37 = phi i64 [ %62, %32 ], [ 0, %23 ]
%38 = getelementptr inbounds double, double* %29, i64 %33
%39 = load double, double* %38
%40 = load double, double* %34
%41 = tail call double @llvm.fmuladd.f64(double %39, double %40, double %35)
%42 = getelementptr inbounds double, double* %34, i64 1
%43 = bitcast double* %42 to <2 x double>*
%44 = load <2 x double>, <2 x double>* %43
%45 = insertelement <2 x double> poison, double %39, i64 0
%46 = shufflevector <2 x double> %45, <2 x double> poison, <2 x i32> zeroinitializer
%47 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %46, <2 x double> %44, <2 x double> %36)
%48 = getelementptr inbounds double, double* %34, i64 4
%49 = or i64 %33, 1
%50 = getelementptr inbounds double, double* %29, i64 %49
%51 = load double, double* %50
%52 = load double, double* %48
%53 = tail call double @llvm.fmuladd.f64(double %51, double %52, double %41)
%54 = getelementptr inbounds double, double* %34, i64 5
%55 = bitcast double* %54 to <2 x double>*
%56 = load <2 x double>, <2 x double>* %55
%57 = insertelement <2 x double> poison, double %51, i64 0
%58 = shufflevector <2 x double> %57, <2 x double> poison, <2 x i32> zeroinitializer
%59 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %58, <2 x double> %56, <2 x double> %47)
%60 = getelementptr inbounds double, double* %34, i64 8
%61 = add nuw nsw i64 %33, 2
%62 = add i64 %37, 2
%63 = icmp eq i64 %62, %21
br i1 %63, label %64, label %32
64: ; preds = %32
%65 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %58, <2 x double> %56, <2 x double> %47)
br label %66
66: ; preds = %23, %64
%67 = phi double [ %53, %64 ], [ undef, %23 ]
%68 = phi <2 x double> [ %65, %64 ], [ undef, %23 ]
%69 = phi double* [ %60, %64 ], [ undef, %23 ]
%70 = phi i64 [ %61, %64 ], [ 0, %23 ]
%71 = phi double* [ %60, %64 ], [ %28, %23 ]
%72 = phi double [ %53, %64 ], [ 0.000000e+00, %23 ]
%73 = phi <2 x double> [ %59, %64 ], [ zeroinitializer, %23 ]
br i1 %22, label %86, label %74
74: ; preds = %66
%75 = getelementptr inbounds double, double* %29, i64 %70
%76 = load double, double* %75
%77 = load double, double* %71
%78 = tail call double @llvm.fmuladd.f64(double %76, double %77, double %72)
%79 = getelementptr inbounds double, double* %71, i64 1
%80 = bitcast double* %79 to <2 x double>*
%81 = load <2 x double>, <2 x double>* %80
%82 = insertelement <2 x double> poison, double %76, i64 0
%83 = shufflevector <2 x double> %82, <2 x double> poison, <2 x i32> zeroinitializer
%84 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %83, <2 x double> %81, <2 x double> %73)
%85 = getelementptr inbounds double, double* %71, i64 4
br label %86
86: ; preds = %74, %66, %23
%87 = phi double [ 0.000000e+00, %23 ], [ %67, %66 ], [ %78, %74 ]
%88 = phi double* [ %28, %23 ], [ %69, %66 ], [ %85, %74 ]
%89 = phi <2 x double> [ zeroinitializer, %23 ], [ %68, %66 ], [ %84, %74 ]
%90 = getelementptr inbounds double, double* %5, i64 %27
%91 = load double, double* %90
%92 = fcmp ogt double %91, 0.000000e+00
br i1 %92, label %93, label %108
93: ; preds = %86
%94 = load i32, i32* %4
%95 = icmp eq i32 %94, -1
br i1 %95, label %101, label %96
96: ; preds = %93
%97 = sext i32 %94 to i64
%98 = getelementptr inbounds double, double* %31, i64 %97
%99 = load double, double* %98
%100 = fmul double %91, %99
br label %101
101: ; preds = %93, %96
%102 = phi double [ %100, %96 ], [ 0.000000e+00, %93 ]
%103 = fsub double 1.000000e+00, %91
%104 = tail call double @llvm.fmuladd.f64(double %87, double %103, double %102)
%105 = insertelement <2 x double> poison, double %103, i64 0
%106 = shufflevector <2 x double> %105, <2 x double> poison, <2 x i32> zeroinitializer
%107 = fmul <2 x double> %89, %106
br label %108
108: ; preds = %101, %86
%109 = phi double [ %104, %101 ], [ %87, %86 ]
%110 = phi <2 x double> [ %107, %101 ], [ %89, %86 ]
%111 = getelementptr inbounds double, double* %3, i64 %27
%112 = load double, double* %111
%113 = tail call double @llvm.fmuladd.f64(double %109, double %112, double %26)
store double %113, double* %9
%114 = load double, double* %111
%115 = extractelement <2 x double> %110, i64 0
%116 = tail call double @llvm.fmuladd.f64(double %115, double %114, double %25)
store double %116, double* %12
%117 = load double, double* %111
%118 = extractelement <2 x double> %110, i64 1
%119 = tail call double @llvm.fmuladd.f64(double %118, double %117, double %24)
store double %119, double* %11
%120 = getelementptr inbounds double, double* %29, i64 %16
%121 = add nuw nsw i64 %27, 1
%122 = icmp eq i64 %121, %17
br i1 %122, label %123, label %23
123: ; preds = %108, %10
ret void
}