#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 pow(int, double);
void deriv_prod(double *dpr, double *dpi, double *n, double *intshift,
                double *deriv_real, double *deriv_imag, int nderivs, int g) {
  double nmintshift[g];
  double term_real, term_imag;
  double total_real, total_real_tmp;
  double total_imag, total_imag_tmp;
  int i, j;
  for (i = 0; i < g; i++)
    nmintshift[i] = n[i] - intshift[i];
  total_real = 1;
  total_imag = 0;
  for (i = 0; i < nderivs; i++) {
    term_real = 0;
    term_imag = 0;
    for (j = 0; j < g; j++) {
      term_real += deriv_real[j + g * i] * nmintshift[j];
      term_imag += deriv_imag[j + g * i] * nmintshift[j];
    }
    total_real_tmp = total_real * term_real - total_imag * term_imag;
    total_imag_tmp = total_real * term_imag + total_imag * term_real;
    total_real = total_real_tmp;
    total_imag = total_imag_tmp;
  }
  double pi_mult = pow(2 * 3.14159265358979323846, (double)nderivs);
  if (nderivs % 4 == 0) {
    dpr[0] = pi_mult * total_real;
    dpi[0] = pi_mult * total_imag;
  } else if (nderivs % 4 == 1) {
    dpr[0] = -pi_mult * total_imag;
    dpi[0] = pi_mult * total_real;
  } else if (nderivs % 4 == 2) {
    dpr[0] = -pi_mult * total_real;
    dpi[0] = -pi_mult * total_imag;
  } else if (nderivs % 4 == 3) {
    dpr[0] = pi_mult * total_imag;
    dpi[0] = -pi_mult * total_real;
  }
}


x86 assembly (clang, -O0):
<deriv_prod>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
mov    0x18(%rbp),%eax
mov    0x10(%rbp),%eax
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
mov    0x18(%rbp),%eax
mov    %rsp,%rcx
mov    %rcx,-0x38(%rbp)
lea    0xf(,%rax,8),%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x88(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x40(%rbp)
movl   $0x0,-0x74(%rbp)
mov    -0x74(%rbp),%eax
cmp    0x18(%rbp),%eax
jge    11ae <deriv_prod+0x9e>
mov    -0x88(%rbp),%rax
mov    -0x18(%rbp),%rcx
movslq -0x74(%rbp),%rdx
movsd  (%rcx,%rdx,8),%xmm0
mov    -0x20(%rbp),%rcx
movslq -0x74(%rbp),%rdx
subsd  (%rcx,%rdx,8),%xmm0
movslq -0x74(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x74(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x74(%rbp)
jmp    116a <deriv_prod+0x5a>
movsd  0xe4a(%rip),%xmm0
movsd  %xmm0,-0x58(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x68(%rbp)
movl   $0x0,-0x74(%rbp)
mov    -0x74(%rbp),%eax
cmp    0x10(%rbp),%eax
jge    12ef <deriv_prod+0x1df>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
movl   $0x0,-0x78(%rbp)
mov    -0x78(%rbp),%eax
cmp    0x18(%rbp),%eax
jge    1274 <deriv_prod+0x164>
mov    -0x88(%rbp),%rax
mov    -0x28(%rbp),%rcx
mov    -0x78(%rbp),%edx
mov    0x18(%rbp),%esi
imul   -0x74(%rbp),%esi
add    %esi,%edx
movslq %edx,%rdx
movsd  (%rcx,%rdx,8),%xmm0
movslq -0x78(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x48(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x30(%rbp),%rcx
mov    -0x78(%rbp),%edx
mov    0x18(%rbp),%esi
imul   -0x74(%rbp),%esi
add    %esi,%edx
movslq %edx,%rdx
movsd  (%rcx,%rdx,8),%xmm0
movslq -0x78(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x50(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x78(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x78(%rbp)
jmp    11ed <deriv_prod+0xdd>
movsd  -0x58(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm2
movsd  -0x68(%rbp),%xmm1
mulsd  -0x50(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x58(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x68(%rbp),%xmm1
mulsd  -0x48(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x74(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x74(%rbp)
jmp    11ca <deriv_prod+0xba>
cvtsi2sdl 0x10(%rbp),%xmm0
mov    $0x6,%edi
call   1030 <pow@plt>
movsd  %xmm0,-0x80(%rbp)
mov    0x10(%rbp),%eax
mov    $0x4,%ecx
cltd
idiv   %ecx
cmp    $0x0,%edx
jne    1340 <deriv_prod+0x230>
movsd  -0x80(%rbp),%xmm0
mulsd  -0x58(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x80(%rbp),%xmm0
mulsd  -0x68(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
jmp    145d <deriv_prod+0x34d>
mov    0x10(%rbp),%eax
mov    $0x4,%ecx
cltd
idiv   %ecx
cmp    $0x1,%edx
jne    1394 <deriv_prod+0x284>
movsd  -0x80(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  -0x68(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x80(%rbp),%xmm0
mulsd  -0x58(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
jmp    1458 <deriv_prod+0x348>
mov    0x10(%rbp),%eax
mov    $0x4,%ecx
cltd
idiv   %ecx
cmp    $0x2,%edx
jne    13ff <deriv_prod+0x2ef>
movsd  -0x80(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  -0x58(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x80(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  -0x68(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
jmp    1453 <deriv_prod+0x343>
mov    0x10(%rbp),%eax
mov    $0x4,%ecx
cltd
idiv   %ecx
cmp    $0x3,%edx
jne    144e <deriv_prod+0x33e>
movsd  -0x80(%rbp),%xmm0
mulsd  -0x68(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x80(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  -0x58(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
jmp    1453 <deriv_prod+0x343>
jmp    1458 <deriv_prod+0x348>
jmp    145d <deriv_prod+0x34d>
mov    -0x38(%rbp),%rax
mov    %rax,%rsp
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<deriv_prod>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %rdi,-0x30(%rbp)
mov    0x18(%rbp),%r11d
mov    0x10(%rbp),%r14d
mov    %rsp,%r12
lea    0xf(,%r11,8),%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%r12
mov    %r12,%rsp
test   %r11d,%r11d
jle    1239 <deriv_prod+0x129>
cmp    $0x4,%r11d
jae    1158 <deriv_prod+0x48>
xor    %eax,%eax
jmp    1220 <deriv_prod+0x110>
mov    %r11d,%eax
and    $0xfffffffc,%eax
lea    -0x4(%rax),%rdi
mov    %rdi,%r10
shr    $0x2,%r10
add    $0x1,%r10
test   %rdi,%rdi
je     146f <deriv_prod+0x35f>
mov    %r10,%rbx
and    $0xfffffffffffffffe,%rbx
xor    %edi,%edi
nop
movupd (%rdx,%rdi,8),%xmm0
movupd 0x10(%rdx,%rdi,8),%xmm1
movupd (%rcx,%rdi,8),%xmm2
subpd  %xmm2,%xmm0
movupd 0x10(%rcx,%rdi,8),%xmm2
subpd  %xmm2,%xmm1
movapd %xmm0,(%r12,%rdi,8)
movapd %xmm1,0x10(%r12,%rdi,8)
movupd 0x20(%rdx,%rdi,8),%xmm0
movupd 0x30(%rdx,%rdi,8),%xmm1
movupd 0x20(%rcx,%rdi,8),%xmm2
subpd  %xmm2,%xmm0
movupd 0x30(%rcx,%rdi,8),%xmm2
subpd  %xmm2,%xmm1
movapd %xmm0,0x20(%r12,%rdi,8)
movapd %xmm1,0x30(%r12,%rdi,8)
add    $0x8,%rdi
add    $0xfffffffffffffffe,%rbx
jne    1180 <deriv_prod+0x70>
test   $0x1,%r10b
je     1214 <deriv_prod+0x104>
movupd (%rdx,%rdi,8),%xmm0
movupd 0x10(%rdx,%rdi,8),%xmm1
movupd (%rcx,%rdi,8),%xmm2
subpd  %xmm2,%xmm0
movupd 0x10(%rcx,%rdi,8),%xmm2
subpd  %xmm2,%xmm1
movapd %xmm0,(%r12,%rdi,8)
movapd %xmm1,0x10(%r12,%rdi,8)
cmp    %r11,%rax
je     1239 <deriv_prod+0x129>
nopl   0x0(%rax)
movsd  (%rdx,%rax,8),%xmm0
subsd  (%rcx,%rax,8),%xmm0
movsd  %xmm0,(%r12,%rax,8)
add    $0x1,%rax
cmp    %rax,%r11
jne    1220 <deriv_prod+0x110>
test   %r14d,%r14d
mov    %rsi,-0x38(%rbp)
jle    1377 <deriv_prod+0x267>
movslq %r11d,%r10
mov    %r14d,%r13d
mov    %r11d,%edi
and    $0xfffffffe,%edi
lea    0x8(%r9),%rbx
lea    0x0(,%r10,8),%rcx
lea    0x8(%r8),%rax
movsd  0xd96(%rip),%xmm7
xorpd  %xmm1,%xmm1
xor    %r15d,%r15d
movapd 0xd97(%rip),%xmm0
jmp    12c0 <deriv_prod+0x1b0>
nopl   0x0(%rax,%rax,1)
xorpd  %xmm2,%xmm2
movapd %xmm2,%xmm3
shufpd $0x1,%xmm1,%xmm3
xorpd  %xmm0,%xmm1
unpcklpd %xmm2,%xmm1
mulpd  %xmm3,%xmm1
unpcklpd %xmm7,%xmm7
mulpd  %xmm2,%xmm7
addpd  %xmm1,%xmm7
add    $0x1,%r15
movapd %xmm7,%xmm1
unpckhpd %xmm7,%xmm1
add    %rcx,%rbx
add    %rcx,%rax
cmp    %r13,%r15
je     137f <deriv_prod+0x26f>
test   %r11d,%r11d
jle    1280 <deriv_prod+0x170>
xorpd  %xmm3,%xmm3
cmp    $0x1,%r11d
jne    12e0 <deriv_prod+0x1d0>
xor    %r14d,%r14d
test   $0x1,%r11b
je     1284 <deriv_prod+0x174>
jmp    134a <deriv_prod+0x23a>
nopw   0x0(%rax,%rax,1)
xor    %r14d,%r14d
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movsd  -0x8(%rax,%r14,8),%xmm5
movsd  (%rax,%r14,8),%xmm6
movhpd -0x8(%rbx,%r14,8),%xmm5
movsd  (%r12,%r14,8),%xmm4
movsd  0x8(%r12,%r14,8),%xmm2
unpcklpd %xmm4,%xmm4
mulpd  %xmm5,%xmm4
addpd  %xmm3,%xmm4
movhpd (%rbx,%r14,8),%xmm6
unpcklpd %xmm2,%xmm2
mulpd  %xmm6,%xmm2
movapd %xmm2,%xmm3
addpd  %xmm4,%xmm3
add    $0x2,%r14
cmp    %r14,%rdi
jne    12f0 <deriv_prod+0x1e0>
addpd  %xmm4,%xmm2
test   $0x1,%r11b
je     1284 <deriv_prod+0x174>
mov    %r15,%rdx
imul   %r10,%rdx
add    %r14,%rdx
movsd  (%r8,%rdx,8),%xmm4
movhpd (%r9,%rdx,8),%xmm4
movsd  (%r12,%r14,8),%xmm2
unpcklpd %xmm2,%xmm2
mulpd  %xmm4,%xmm2
addpd  %xmm3,%xmm2
jmp    1284 <deriv_prod+0x174>
movsd  0xc81(%rip),%xmm7
movapd %xmm7,-0x50(%rbp)
mov    0x10(%rbp),%ebx
xorps  %xmm0,%xmm0
cvtsi2sd %ebx,%xmm0
mov    $0x6,%edi
call   1030 <pow@plt>
lea    0x3(%rbx),%eax
test   %ebx,%ebx
cmovns %ebx,%eax
and    $0xfffffffc,%eax
sub    %eax,%ebx
cmp    $0x3,%ebx
ja     1460 <deriv_prod+0x350>
lea    0xc6b(%rip),%rax
movslq (%rax,%rbx,4),%rcx
add    %rax,%rcx
jmp    *%rcx
movapd -0x50(%rbp),%xmm3
movapd %xmm3,%xmm1
mulsd  %xmm0,%xmm1
mov    -0x30(%rbp),%rax
movsd  %xmm1,(%rax)
unpckhpd %xmm3,%xmm3
mulsd  %xmm0,%xmm3
jmp    1458 <deriv_prod+0x348>
movapd 0xc2b(%rip),%xmm1
xorpd  %xmm0,%xmm1
movapd -0x50(%rbp),%xmm3
movapd %xmm3,%xmm2
unpckhpd %xmm3,%xmm2
mulsd  %xmm1,%xmm2
mov    -0x30(%rbp),%rax
movsd  %xmm2,(%rax)
mulsd  %xmm0,%xmm3
jmp    1458 <deriv_prod+0x348>
movapd 0xc00(%rip),%xmm1
xorpd  %xmm0,%xmm1
movapd -0x50(%rbp),%xmm3
movapd %xmm3,%xmm0
mulsd  %xmm1,%xmm0
mov    -0x30(%rbp),%rax
movsd  %xmm0,(%rax)
unpckhpd %xmm3,%xmm3
jmp    1454 <deriv_prod+0x344>
movapd -0x50(%rbp),%xmm3
movapd %xmm3,%xmm1
unpckhpd %xmm3,%xmm1
mulsd  %xmm0,%xmm1
mov    -0x30(%rbp),%rax
movsd  %xmm1,(%rax)
movapd 0xbc0(%rip),%xmm1
xorpd  %xmm0,%xmm1
mulsd  %xmm1,%xmm3
mov    -0x38(%rbp),%rax
movsd  %xmm3,(%rax)
lea    -0x28(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
xor    %edi,%edi
test   $0x1,%r10b
jne    11e9 <deriv_prod+0xd9>
jmp    1214 <deriv_prod+0x104>

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

LLVM IR (-O2):
define void @deriv_prod(double* nocapture writeonly %0, double* nocapture writeonly %1, double* nocapture %2, double* nocapture %3, double* nocapture %4, double* nocapture %5, i32 %6, i32 %7) {
%9 = zext i32 %7 to i64
%10 = alloca double, i64 %9
%11 = icmp sgt i32 %7, 0
br i1 %11, label %12, label %92
12: ; preds = %8
%13 = icmp ult i32 %7, 4
br i1 %13, label %90, label %14
14: ; preds = %12
%15 = and i64 %9, 4294967292
%16 = add nsw i64 %15, -4
%17 = lshr exact i64 %16, 2
%18 = add nuw nsw i64 %17, 1
%19 = and i64 %18, 1
%20 = icmp eq i64 %16, 0
br i1 %20, label %66, label %21
21: ; preds = %14
%22 = and i64 %18, 9223372036854775806
br label %23
23: ; preds = %23, %21
%24 = phi i64 [ 0, %21 ], [ %63, %23 ]
%25 = phi i64 [ 0, %21 ], [ %64, %23 ]
%26 = getelementptr inbounds double, double* %2, i64 %24
%27 = bitcast double* %26 to <2 x double>*
%28 = load <2 x double>, <2 x double>* %27
%29 = getelementptr inbounds double, double* %26, i64 2
%30 = bitcast double* %29 to <2 x double>*
%31 = load <2 x double>, <2 x double>* %30
%32 = getelementptr inbounds double, double* %3, i64 %24
%33 = bitcast double* %32 to <2 x double>*
%34 = load <2 x double>, <2 x double>* %33
%35 = getelementptr inbounds double, double* %32, i64 2
%36 = bitcast double* %35 to <2 x double>*
%37 = load <2 x double>, <2 x double>* %36
%38 = fsub <2 x double> %28, %34
%39 = fsub <2 x double> %31, %37
%40 = getelementptr inbounds double, double* %10, i64 %24
%41 = bitcast double* %40 to <2 x double>*
store <2 x double> %38, <2 x double>* %41
%42 = getelementptr inbounds double, double* %40, i64 2
%43 = bitcast double* %42 to <2 x double>*
store <2 x double> %39, <2 x double>* %43
%44 = or i64 %24, 4
%45 = getelementptr inbounds double, double* %2, i64 %44
%46 = bitcast double* %45 to <2 x double>*
%47 = load <2 x double>, <2 x double>* %46
%48 = getelementptr inbounds double, double* %45, i64 2
%49 = bitcast double* %48 to <2 x double>*
%50 = load <2 x double>, <2 x double>* %49
%51 = getelementptr inbounds double, double* %3, i64 %44
%52 = bitcast double* %51 to <2 x double>*
%53 = load <2 x double>, <2 x double>* %52
%54 = getelementptr inbounds double, double* %51, i64 2
%55 = bitcast double* %54 to <2 x double>*
%56 = load <2 x double>, <2 x double>* %55
%57 = fsub <2 x double> %47, %53
%58 = fsub <2 x double> %50, %56
%59 = getelementptr inbounds double, double* %10, i64 %44
%60 = bitcast double* %59 to <2 x double>*
store <2 x double> %57, <2 x double>* %60
%61 = getelementptr inbounds double, double* %59, i64 2
%62 = bitcast double* %61 to <2 x double>*
store <2 x double> %58, <2 x double>* %62
%63 = add nuw i64 %24, 8
%64 = add i64 %25, 2
%65 = icmp eq i64 %64, %22
br i1 %65, label %66, label %23
66: ; preds = %23, %14
%67 = phi i64 [ 0, %14 ], [ %63, %23 ]
%68 = icmp eq i64 %19, 0
br i1 %68, label %88, label %69
69: ; preds = %66
%70 = getelementptr inbounds double, double* %2, i64 %67
%71 = bitcast double* %70 to <2 x double>*
%72 = load <2 x double>, <2 x double>* %71
%73 = getelementptr inbounds double, double* %70, i64 2
%74 = bitcast double* %73 to <2 x double>*
%75 = load <2 x double>, <2 x double>* %74
%76 = getelementptr inbounds double, double* %3, i64 %67
%77 = bitcast double* %76 to <2 x double>*
%78 = load <2 x double>, <2 x double>* %77
%79 = getelementptr inbounds double, double* %76, i64 2
%80 = bitcast double* %79 to <2 x double>*
%81 = load <2 x double>, <2 x double>* %80
%82 = fsub <2 x double> %72, %78
%83 = fsub <2 x double> %75, %81
%84 = getelementptr inbounds double, double* %10, i64 %67
%85 = bitcast double* %84 to <2 x double>*
store <2 x double> %82, <2 x double>* %85
%86 = getelementptr inbounds double, double* %84, i64 2
%87 = bitcast double* %86 to <2 x double>*
store <2 x double> %83, <2 x double>* %87
br label %88
88: ; preds = %66, %69
%89 = icmp eq i64 %15, %9
br i1 %89, label %92, label %90
90: ; preds = %12, %88
%91 = phi i64 [ 0, %12 ], [ %15, %88 ]
br label %101
92: ; preds = %101, %88, %8
%93 = icmp sgt i32 %6, 0
br i1 %93, label %94, label %184
94: ; preds = %92
%95 = sext i32 %7 to i64
%96 = zext i32 %6 to i64
%97 = and i64 %9, 1
%98 = icmp eq i32 %7, 1
%99 = and i64 %9, 4294967294
%100 = icmp eq i64 %97, 0
br label %111
101: ; preds = %90, %101
%102 = phi i64 [ %109, %101 ], [ %91, %90 ]
%103 = getelementptr inbounds double, double* %2, i64 %102
%104 = load double, double* %103
%105 = getelementptr inbounds double, double* %3, i64 %102
%106 = load double, double* %105
%107 = fsub double %104, %106
%108 = getelementptr inbounds double, double* %10, i64 %102
store double %107, double* %108
%109 = add nuw nsw i64 %102, 1
%110 = icmp eq i64 %109, %9
br i1 %110, label %92, label %101
111: ; preds = %94, %168
%112 = phi i64 [ 0, %94 ], [ %180, %168 ]
%113 = phi double [ 0.000000e+00, %94 ], [ %183, %168 ]
%114 = phi double [ 1.000000e+00, %94 ], [ %182, %168 ]
br i1 %11, label %115, label %168
115: ; preds = %111
%116 = mul nsw i64 %112, %95
br i1 %98, label %151, label %117
117: ; preds = %115, %117
%118 = phi i64 [ %146, %117 ], [ 0, %115 ]
%119 = phi <2 x double> [ %145, %117 ], [ zeroinitializer, %115 ]
%120 = phi i64 [ %147, %117 ], [ 0, %115 ]
%121 = add nsw i64 %118, %116
%122 = getelementptr inbounds double, double* %4, i64 %121
%123 = load double, double* %122
%124 = getelementptr inbounds double, double* %10, i64 %118
%125 = load double, double* %124
%126 = getelementptr inbounds double, double* %5, i64 %121
%127 = load double, double* %126
%128 = insertelement <2 x double> poison, double %123, i64 0
%129 = insertelement <2 x double> %128, double %127, i64 1
%130 = insertelement <2 x double> poison, double %125, i64 0
%131 = shufflevector <2 x double> %130, <2 x double> poison, <2 x i32> zeroinitializer
%132 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %129, <2 x double> %131, <2 x double> %119)
%133 = or i64 %118, 1
%134 = add nsw i64 %133, %116
%135 = getelementptr inbounds double, double* %4, i64 %134
%136 = load double, double* %135
%137 = getelementptr inbounds double, double* %10, i64 %133
%138 = load double, double* %137
%139 = getelementptr inbounds double, double* %5, i64 %134
%140 = load double, double* %139
%141 = insertelement <2 x double> poison, double %136, i64 0
%142 = insertelement <2 x double> %141, double %140, i64 1
%143 = insertelement <2 x double> poison, double %138, i64 0
%144 = shufflevector <2 x double> %143, <2 x double> poison, <2 x i32> zeroinitializer
%145 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %142, <2 x double> %144, <2 x double> %132)
%146 = add nuw nsw i64 %118, 2
%147 = add i64 %120, 2
%148 = icmp eq i64 %147, %99
br i1 %148, label %149, label %117
149: ; preds = %117
%150 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %142, <2 x double> %144, <2 x double> %132)
br label %151
151: ; preds = %149, %115
%152 = phi <2 x double> [ undef, %115 ], [ %150, %149 ]
%153 = phi i64 [ 0, %115 ], [ %146, %149 ]
%154 = phi <2 x double> [ zeroinitializer, %115 ], [ %145, %149 ]
br i1 %100, label %168, label %155
155: ; preds = %151
%156 = add nsw i64 %153, %116
%157 = getelementptr inbounds double, double* %4, i64 %156
%158 = load double, double* %157
%159 = getelementptr inbounds double, double* %10, i64 %153
%160 = load double, double* %159
%161 = getelementptr inbounds double, double* %5, i64 %156
%162 = load double, double* %161
%163 = insertelement <2 x double> poison, double %158, i64 0
%164 = insertelement <2 x double> %163, double %162, i64 1
%165 = insertelement <2 x double> poison, double %160, i64 0
%166 = shufflevector <2 x double> %165, <2 x double> poison, <2 x i32> zeroinitializer
%167 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %164, <2 x double> %166, <2 x double> %154)
br label %168
168: ; preds = %155, %151, %111
%169 = phi <2 x double> [ zeroinitializer, %111 ], [ %152, %151 ], [ %167, %155 ]
%170 = fneg double %113
%171 = extractelement <2 x double> %169, i64 1
%172 = insertelement <2 x double> poison, double %171, i64 0
%173 = insertelement <2 x double> %172, double %113, i64 1
%174 = insertelement <2 x double> poison, double %170, i64 0
%175 = shufflevector <2 x double> %174, <2 x double> %169, <2 x i32> <i32 0, i32 2>
%176 = fmul <2 x double> %173, %175
%177 = insertelement <2 x double> poison, double %114, i64 0
%178 = shufflevector <2 x double> %177, <2 x double> poison, <2 x i32> zeroinitializer
%179 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %178, <2 x double> %169, <2 x double> %176)
%180 = add nuw nsw i64 %112, 1
%181 = icmp eq i64 %180, %96
%182 = extractelement <2 x double> %179, i64 0
%183 = extractelement <2 x double> %179, i64 1
br i1 %181, label %184, label %111
184: ; preds = %168, %92
%185 = phi <2 x double> [ <double 1.000000e+00, double 0.000000e+00>, %92 ], [ %179, %168 ]
%186 = sitofp i32 %6 to double
%187 = tail call double @pow(i32 6, double %186)
%188 = srem i32 %6, 4
switch i32 %188, label %214 [
i32 0, label %189
i32 1, label %194
i32 2, label %200
i32 3, label %206
]
189: ; preds = %184
%190 = extractelement <2 x double> %185, i64 0
%191 = fmul double %190, %187
store double %191, double* %0
%192 = extractelement <2 x double> %185, i64 1
%193 = fmul double %192, %187
br label %212
194: ; preds = %184
%195 = fneg double %187
%196 = extractelement <2 x double> %185, i64 1
%197 = fmul double %196, %195
store double %197, double* %0
%198 = extractelement <2 x double> %185, i64 0
%199 = fmul double %198, %187
br label %212
200: ; preds = %184
%201 = fneg double %187
%202 = extractelement <2 x double> %185, i64 0
%203 = fmul double %202, %201
store double %203, double* %0
%204 = extractelement <2 x double> %185, i64 1
%205 = fmul double %204, %201
br label %212
206: ; preds = %184
%207 = extractelement <2 x double> %185, i64 1
%208 = fmul double %207, %187
store double %208, double* %0
%209 = fneg double %187
%210 = extractelement <2 x double> %185, i64 0
%211 = fmul double %210, %209
br label %212
212: ; preds = %189, %200, %206, %194
%213 = phi double [ %199, %194 ], [ %211, %206 ], [ %205, %200 ], [ %193, %189 ]
store double %213, double* %1
br label %214
214: ; preds = %212, %184
ret void
}