void wignerdmat_mem(int L, double *matIn, double *matOut, double *trigs,
                    double *sqrts, double *workspace) {
  int i, j;
  int deg, tmpdim;
  double cosVal, sinVal;
  double *ptrIn, *ptrOut, *ptrTmp;
  double rdeg;
  cosVal = trigs[0];
  sinVal = trigs[1];
  ptrIn = matIn;
  ptrOut = matOut;
  ptrTmp = workspace;
  if (L > 1) {
    memset(ptrTmp, 0, sizeof(double) * (2 * L) * (2 * L));
    memset(matOut, 0, sizeof(double) * (2 * L + 1) * (2 * L + 1));
    memcpy(ptrTmp, matIn, sizeof(double) * (2 * L - 1) * (2 * L - 1));
    for (deg = 2 * L - 1; deg < 2 * L + 1; deg++) {
      rdeg = 1. / ((double)deg);
      tmpdim = deg + 1;
      memset(matOut, 0, sizeof(double) * (tmpdim) * (tmpdim));
      for (i = 0; i < deg; i++)
        for (j = 0; j < deg; j++) {
          matOut[(i * tmpdim) + j] += rdeg * sqrts[deg - i] * sqrts[deg - j] *
                                      ptrTmp[(i * deg) + j] * cosVal;
          matOut[((i + 1) * tmpdim) + j] -= rdeg * sqrts[i + 1] *
                                            sqrts[deg - j] *
                                            ptrTmp[(i * deg) + j] * sinVal;
          matOut[(i * tmpdim) + (j + 1)] += rdeg * sqrts[deg - i] *
                                            sqrts[j + 1] *
                                            ptrTmp[(i * deg) + j] * sinVal;
          matOut[((i + 1) * tmpdim) + (j + 1)] +=
              rdeg * sqrts[i + 1] * sqrts[j + 1] * ptrTmp[(i * deg) + j] *
              cosVal;
        }
      if (deg == 2 * L - 1)
        memcpy(ptrTmp, matOut, sizeof(double) * (tmpdim) * (tmpdim));
    }
  } else if (L == 0) {
    matOut[0] = 1;
  } else {
    matOut[0] = cosVal * cosVal;
    matOut[1] = sqrts[2] * cosVal * sinVal;
    matOut[2] = sinVal * sinVal;
    matOut[3] = -matOut[1];
    matOut[4] = matOut[0] - matOut[2];
    matOut[5] = matOut[1];
    matOut[6] = matOut[2];
    matOut[7] = -matOut[1];
    matOut[8] = matOut[0];
  }
}


x86 assembly (clang, -O0):
<wignerdmat_mem>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x58(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x60(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,-0x68(%rbp)
cmpl   $0x1,-0x4(%rbp)
jle    14a3 <wignerdmat_mem+0x383>
mov    -0x68(%rbp),%rdi
mov    -0x4(%rbp),%eax
shl    $0x1,%eax
movslq %eax,%rdx
shl    $0x3,%rdx
mov    -0x4(%rbp),%eax
shl    $0x1,%eax
cltq
imul   %rax,%rdx
xor    %esi,%esi
call   1030 <memset@plt>
mov    -0x18(%rbp),%rdi
mov    -0x4(%rbp),%eax
shl    $0x1,%eax
add    $0x1,%eax
movslq %eax,%rdx
shl    $0x3,%rdx
mov    -0x4(%rbp),%eax
shl    $0x1,%eax
add    $0x1,%eax
cltq
imul   %rax,%rdx
xor    %esi,%esi
call   1030 <memset@plt>
mov    -0x68(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x4(%rbp),%eax
shl    $0x1,%eax
sub    $0x1,%eax
movslq %eax,%rdx
shl    $0x3,%rdx
mov    -0x4(%rbp),%eax
shl    $0x1,%eax
sub    $0x1,%eax
cltq
imul   %rax,%rdx
call   1040 <memcpy@plt>
mov    -0x4(%rbp),%eax
shl    $0x1,%eax
sub    $0x1,%eax
mov    %eax,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
mov    -0x4(%rbp),%ecx
shl    $0x1,%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jge    149e <wignerdmat_mem+0x37e>
cvtsi2sdl -0x3c(%rbp),%xmm1
movsd  0xddd(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x40(%rbp)
mov    -0x18(%rbp),%rdi
movslq -0x40(%rbp),%rdx
shl    $0x3,%rdx
movslq -0x40(%rbp),%rax
imul   %rax,%rdx
xor    %esi,%esi
call   1030 <memset@plt>
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x3c(%rbp),%eax
jge    145a <wignerdmat_mem+0x33a>
movl   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%eax
cmp    -0x3c(%rbp),%eax
jge    1447 <wignerdmat_mem+0x327>
movsd  -0x70(%rbp),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x3c(%rbp),%ecx
sub    -0x34(%rbp),%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x3c(%rbp),%ecx
sub    -0x38(%rbp),%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
mov    -0x68(%rbp),%rax
mov    -0x34(%rbp),%ecx
imul   -0x3c(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
movsd  -0x48(%rbp),%xmm2
mov    -0x18(%rbp),%rax
mov    -0x34(%rbp),%ecx
imul   -0x40(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x70(%rbp),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x3c(%rbp),%ecx
sub    -0x38(%rbp),%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
mov    -0x68(%rbp),%rax
mov    -0x34(%rbp),%ecx
imul   -0x3c(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
movsd  -0x50(%rbp),%xmm2
mov    -0x18(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0x1,%ecx
imul   -0x40(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
movq   %xmm0,%rdx
movabs $0x8000000000000000,%rsi
xor    %rsi,%rdx
movq   %rdx,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x70(%rbp),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x3c(%rbp),%ecx
sub    -0x34(%rbp),%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x38(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
mov    -0x68(%rbp),%rax
mov    -0x34(%rbp),%ecx
imul   -0x3c(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
movsd  -0x50(%rbp),%xmm2
mov    -0x18(%rbp),%rax
mov    -0x34(%rbp),%ecx
imul   -0x40(%rbp),%ecx
mov    -0x38(%rbp),%edx
add    $0x1,%edx
add    %edx,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x70(%rbp),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x38(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
mov    -0x68(%rbp),%rax
mov    -0x34(%rbp),%ecx
imul   -0x3c(%rbp),%ecx
add    -0x38(%rbp),%ecx
movslq %ecx,%rcx
mulsd  (%rax,%rcx,8),%xmm0
movsd  -0x48(%rbp),%xmm2
mov    -0x18(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0x1,%ecx
imul   -0x40(%rbp),%ecx
mov    -0x38(%rbp),%edx
add    $0x1,%edx
add    %edx,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    126a <wignerdmat_mem+0x14a>
jmp    144c <wignerdmat_mem+0x32c>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1257 <wignerdmat_mem+0x137>
mov    -0x3c(%rbp),%eax
mov    -0x4(%rbp),%ecx
shl    $0x1,%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jne    148b <wignerdmat_mem+0x36b>
mov    -0x68(%rbp),%rdi
mov    -0x18(%rbp),%rsi
movslq -0x40(%rbp),%rdx
shl    $0x3,%rdx
movslq -0x40(%rbp),%rax
imul   %rax,%rdx
call   1040 <memcpy@plt>
jmp    1490 <wignerdmat_mem+0x370>
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    1202 <wignerdmat_mem+0xe2>
jmp    15a9 <wignerdmat_mem+0x489>
cmpl   $0x0,-0x4(%rbp)
jne    14c2 <wignerdmat_mem+0x3a2>
mov    -0x18(%rbp),%rax
movsd  0xb47(%rip),%xmm0
movsd  %xmm0,(%rax)
jmp    15a4 <wignerdmat_mem+0x484>
movsd  -0x48(%rbp),%xmm0
mulsd  -0x48(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x28(%rbp),%rax
movsd  0x10(%rax),%xmm0
mulsd  -0x48(%rbp),%xmm0
mulsd  -0x50(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x8(%rax)
movsd  -0x50(%rbp),%xmm0
mulsd  -0x50(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x10(%rax)
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x18(%rax)
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
subsd  0x10(%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x20(%rax)
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x28(%rax)
mov    -0x18(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x30(%rax)
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x38(%rax)
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x40(%rax)
jmp    15a9 <wignerdmat_mem+0x489>
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<wignerdmat_mem>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x68,%rsp
mov    %r8,%rbx
mov    %rdx,%r15
mov    %edi,%ebp
movsd  (%rcx),%xmm3
movsd  0x8(%rcx),%xmm4
cmp    $0x2,%edi
jl     1379 <wignerdmat_mem+0x259>
mov    %r9,%r14
mov    %rsi,%r12
movsd  %xmm4,0x30(%rsp)
movapd %xmm3,0x50(%rsp)
lea    0x0(%rbp,%rbp,1),%eax
movslq %eax,%rdx
imul   %rdx,%rdx
shl    $0x3,%rdx
mov    %r9,%rdi
xor    %esi,%esi
call   1030 <memset@plt>
lea    0x1(%rbp,%rbp,1),%eax
mov    %eax,0xc(%rsp)
movslq %eax,%rdx
imul   %rdx,%rdx
shl    $0x3,%rdx
mov    %r15,%rdi
xor    %esi,%esi
call   1030 <memset@plt>
lea    -0x1(%rbp,%rbp,1),%eax
movslq %eax,%r13
mov    %r13,%rdx
imul   %r13,%rdx
shl    $0x3,%rdx
mov    %r14,0x10(%rsp)
mov    %r14,%rdi
mov    %r12,%rsi
call   1040 <memcpy@plt>
lea    (%r15,%r13,8),%rax
add    $0x10,%rax
mov    %rax,0x18(%rsp)
mov    %r15,%rbp
lea    0x8(,%r13,8),%r15
lea    0x8(%rbp),%rax
mov    %rax,0x20(%rsp)
lea    0x0(,%r13,8),%r12
lea    (%rbx,%r13,8),%r14
mov    %r13,0x28(%rsp)
mov    %rbp,0x38(%rsp)
jmp    1214 <wignerdmat_mem+0xf4>
nopl   0x0(%rax,%rax,1)
addq   $0x8,0x18(%rsp)
add    $0x8,%r15
add    $0x8,%r12
add    $0x8,%r14
mov    0x48(%rsp),%rax
mov    %rax,%r13
cmp    %eax,0xc(%rsp)
je     13ea <wignerdmat_mem+0x2ca>
lea    0x1(%r13),%rax
mov    %rax,0x48(%rsp)
mov    %rax,%rdx
imul   %rax,%rdx
shl    $0x3,%rdx
mov    %rbp,%rdi
xor    %esi,%esi
mov    %rdx,0x40(%rsp)
call   1030 <memset@plt>
test   %r13,%r13
movapd 0x50(%rsp),%xmm3
movsd  0x30(%rsp),%xmm4
jle    1352 <wignerdmat_mem+0x232>
mov    %r13d,%r9d
cvtsi2sd %r13d,%xmm1
movsd  0xdb4(%rip),%xmm0
divsd  %xmm1,%xmm0
movapd %xmm0,%xmm1
xorpd  0xd94(%rip),%xmm1
mov    %r13d,%r8d
mov    0x10(%rsp),%rdx
mov    0x20(%rsp),%rsi
mov    0x18(%rsp),%rdi
xor    %r10d,%r10d
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    %r13,%r11
sub    %r10,%r11
add    $0x1,%r10
mov    %r14,%rax
xor    %ebp,%ebp
nop
movsd  (%rbx,%r11,8),%xmm2
mulsd  %xmm0,%xmm2
mulsd  (%rax),%xmm2
mulsd  (%rdx,%rbp,8),%xmm2
mulsd  %xmm3,%xmm2
addsd  -0x8(%rsi,%rbp,8),%xmm2
movsd  %xmm2,-0x8(%rsi,%rbp,8)
movsd  (%rbx,%r10,8),%xmm2
mulsd  %xmm1,%xmm2
mulsd  (%rax),%xmm2
mulsd  (%rdx,%rbp,8),%xmm2
mulsd  %xmm4,%xmm2
addsd  -0x8(%rdi,%rbp,8),%xmm2
movsd  %xmm2,-0x8(%rdi,%rbp,8)
movsd  (%rbx,%r11,8),%xmm2
mulsd  %xmm0,%xmm2
mulsd  0x8(%rbx,%rbp,8),%xmm2
mulsd  (%rdx,%rbp,8),%xmm2
mulsd  %xmm4,%xmm2
addsd  (%rsi,%rbp,8),%xmm2
movsd  %xmm2,(%rsi,%rbp,8)
movsd  (%rbx,%r10,8),%xmm2
mulsd  %xmm0,%xmm2
mulsd  0x8(%rbx,%rbp,8),%xmm2
mulsd  (%rdx,%rbp,8),%xmm2
mulsd  %xmm3,%xmm2
addsd  (%rdi,%rbp,8),%xmm2
movsd  %xmm2,(%rdi,%rbp,8)
lea    0x1(%rbp),%rcx
add    $0xfffffffffffffff8,%rax
mov    %rcx,%rbp
cmp    %rcx,%r9
jne    12a0 <wignerdmat_mem+0x180>
add    %r15,%rdi
add    %r15,%rsi
add    %r12,%rdx
cmp    %r8,%r10
jne    1290 <wignerdmat_mem+0x170>
cmp    0x28(%rsp),%r13
mov    0x38(%rsp),%rbp
jne    11f0 <wignerdmat_mem+0xd0>
mov    0x10(%rsp),%rdi
mov    %rbp,%rsi
mov    0x40(%rsp),%rdx
call   1040 <memcpy@plt>
jmp    11f0 <wignerdmat_mem+0xd0>
test   %ebp,%ebp
je     13dd <wignerdmat_mem+0x2bd>
movapd %xmm3,%xmm0
mulsd  %xmm3,%xmm0
movsd  %xmm0,(%r15)
mulsd  0x10(%rbx),%xmm3
mulsd  %xmm4,%xmm3
movsd  %xmm3,0x8(%r15)
mulsd  %xmm4,%xmm4
movsd  %xmm4,0x10(%r15)
movapd 0xc55(%rip),%xmm1
xorpd  %xmm3,%xmm1
movlpd %xmm1,0x18(%r15)
movapd %xmm0,%xmm2
subsd  %xmm4,%xmm2
movsd  %xmm2,0x20(%r15)
movsd  %xmm3,0x28(%r15)
movsd  %xmm4,0x30(%r15)
movlpd %xmm1,0x38(%r15)
movsd  %xmm0,0x40(%r15)
jmp    13ea <wignerdmat_mem+0x2ca>
movabs $0x3ff0000000000000,%rax
mov    %rax,(%r15)
add    $0x68,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @wignerdmat_mem(i32 %0, double* %1, double* %2, double* %3, double* %4, double* %5) {
%7 = alloca i32
%8 = alloca double*
%9 = alloca double*
%10 = alloca double*
%11 = alloca double*
%12 = alloca double*
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca double
%18 = alloca double
%19 = alloca double*
%20 = alloca double*
%21 = alloca double*
%22 = alloca double
store i32 %0, i32* %7
store double* %1, double** %8
store double* %2, double** %9
store double* %3, double** %10
store double* %4, double** %11
store double* %5, double** %12
%23 = load double*, double** %10
%24 = getelementptr inbounds double, double* %23, i64 0
%25 = load double, double* %24
store double %25, double* %17
%26 = load double*, double** %10
%27 = getelementptr inbounds double, double* %26, i64 1
%28 = load double, double* %27
store double %28, double* %18
%29 = load double*, double** %8
store double* %29, double** %19
%30 = load double*, double** %9
store double* %30, double** %20
%31 = load double*, double** %12
store double* %31, double** %21
%32 = load i32, i32* %7
%33 = icmp sgt i32 %32, 1
br i1 %33, label %34, label %286
34: ; preds = %6
%35 = load double*, double** %21
%36 = bitcast double* %35 to i8*
%37 = load i32, i32* %7
%38 = mul nsw i32 2, %37
%39 = sext i32 %38 to i64
%40 = mul i64 8, %39
%41 = load i32, i32* %7
%42 = mul nsw i32 2, %41
%43 = sext i32 %42 to i64
%44 = mul i64 %40, %43
%45 = load double*, double** %9
%46 = bitcast double* %45 to i8*
%47 = load i32, i32* %7
%48 = mul nsw i32 2, %47
%49 = add nsw i32 %48, 1
%50 = sext i32 %49 to i64
%51 = mul i64 8, %50
%52 = load i32, i32* %7
%53 = mul nsw i32 2, %52
%54 = add nsw i32 %53, 1
%55 = sext i32 %54 to i64
%56 = mul i64 %51, %55
%57 = load double*, double** %21
%58 = bitcast double* %57 to i8*
%59 = load double*, double** %8
%60 = bitcast double* %59 to i8*
%61 = load i32, i32* %7
%62 = mul nsw i32 2, %61
%63 = sub nsw i32 %62, 1
%64 = sext i32 %63 to i64
%65 = mul i64 8, %64
%66 = load i32, i32* %7
%67 = mul nsw i32 2, %66
%68 = sub nsw i32 %67, 1
%69 = sext i32 %68 to i64
%70 = mul i64 %65, %69
%71 = load i32, i32* %7
%72 = mul nsw i32 2, %71
%73 = sub nsw i32 %72, 1
store i32 %73, i32* %15
br label %74
74: ; preds = %282, %34
%75 = load i32, i32* %15
%76 = load i32, i32* %7
%77 = mul nsw i32 2, %76
%78 = add nsw i32 %77, 1
%79 = icmp slt i32 %75, %78
br i1 %79, label %80, label %285
80: ; preds = %74
%81 = load i32, i32* %15
%82 = sitofp i32 %81 to double
%83 = fdiv double 1.000000e+00, %82
store double %83, double* %22
%84 = load i32, i32* %15
%85 = add nsw i32 %84, 1
store i32 %85, i32* %16
%86 = load double*, double** %9
%87 = bitcast double* %86 to i8*
%88 = load i32, i32* %16
%89 = sext i32 %88 to i64
%90 = mul i64 8, %89
%91 = load i32, i32* %16
%92 = sext i32 %91 to i64
%93 = mul i64 %90, %92
store i32 0, i32* %13
br label %94
94: ; preds = %261, %80
%95 = load i32, i32* %13
%96 = load i32, i32* %15
%97 = icmp slt i32 %95, %96
br i1 %97, label %98, label %264
98: ; preds = %94
store i32 0, i32* %14
br label %99
99: ; preds = %257, %98
%100 = load i32, i32* %14
%101 = load i32, i32* %15
%102 = icmp slt i32 %100, %101
br i1 %102, label %103, label %260
103: ; preds = %99
%104 = load double, double* %22
%105 = load double*, double** %11
%106 = load i32, i32* %15
%107 = load i32, i32* %13
%108 = sub nsw i32 %106, %107
%109 = sext i32 %108 to i64
%110 = getelementptr inbounds double, double* %105, i64 %109
%111 = load double, double* %110
%112 = fmul double %104, %111
%113 = load double*, double** %11
%114 = load i32, i32* %15
%115 = load i32, i32* %14
%116 = sub nsw i32 %114, %115
%117 = sext i32 %116 to i64
%118 = getelementptr inbounds double, double* %113, i64 %117
%119 = load double, double* %118
%120 = fmul double %112, %119
%121 = load double*, double** %21
%122 = load i32, i32* %13
%123 = load i32, i32* %15
%124 = mul nsw i32 %122, %123
%125 = load i32, i32* %14
%126 = add nsw i32 %124, %125
%127 = sext i32 %126 to i64
%128 = getelementptr inbounds double, double* %121, i64 %127
%129 = load double, double* %128
%130 = fmul double %120, %129
%131 = load double, double* %17
%132 = load double*, double** %9
%133 = load i32, i32* %13
%134 = load i32, i32* %16
%135 = mul nsw i32 %133, %134
%136 = load i32, i32* %14
%137 = add nsw i32 %135, %136
%138 = sext i32 %137 to i64
%139 = getelementptr inbounds double, double* %132, i64 %138
%140 = load double, double* %139
%141 = call double @llvm.fmuladd.f64(double %130, double %131, double %140)
store double %141, double* %139
%142 = load double, double* %22
%143 = load double*, double** %11
%144 = load i32, i32* %13
%145 = add nsw i32 %144, 1
%146 = sext i32 %145 to i64
%147 = getelementptr inbounds double, double* %143, i64 %146
%148 = load double, double* %147
%149 = fmul double %142, %148
%150 = load double*, double** %11
%151 = load i32, i32* %15
%152 = load i32, i32* %14
%153 = sub nsw i32 %151, %152
%154 = sext i32 %153 to i64
%155 = getelementptr inbounds double, double* %150, i64 %154
%156 = load double, double* %155
%157 = fmul double %149, %156
%158 = load double*, double** %21
%159 = load i32, i32* %13
%160 = load i32, i32* %15
%161 = mul nsw i32 %159, %160
%162 = load i32, i32* %14
%163 = add nsw i32 %161, %162
%164 = sext i32 %163 to i64
%165 = getelementptr inbounds double, double* %158, i64 %164
%166 = load double, double* %165
%167 = fmul double %157, %166
%168 = load double, double* %18
%169 = load double*, double** %9
%170 = load i32, i32* %13
%171 = add nsw i32 %170, 1
%172 = load i32, i32* %16
%173 = mul nsw i32 %171, %172
%174 = load i32, i32* %14
%175 = add nsw i32 %173, %174
%176 = sext i32 %175 to i64
%177 = getelementptr inbounds double, double* %169, i64 %176
%178 = load double, double* %177
%179 = fneg double %167
%180 = call double @llvm.fmuladd.f64(double %179, double %168, double %178)
store double %180, double* %177
%181 = load double, double* %22
%182 = load double*, double** %11
%183 = load i32, i32* %15
%184 = load i32, i32* %13
%185 = sub nsw i32 %183, %184
%186 = sext i32 %185 to i64
%187 = getelementptr inbounds double, double* %182, i64 %186
%188 = load double, double* %187
%189 = fmul double %181, %188
%190 = load double*, double** %11
%191 = load i32, i32* %14
%192 = add nsw i32 %191, 1
%193 = sext i32 %192 to i64
%194 = getelementptr inbounds double, double* %190, i64 %193
%195 = load double, double* %194
%196 = fmul double %189, %195
%197 = load double*, double** %21
%198 = load i32, i32* %13
%199 = load i32, i32* %15
%200 = mul nsw i32 %198, %199
%201 = load i32, i32* %14
%202 = add nsw i32 %200, %201
%203 = sext i32 %202 to i64
%204 = getelementptr inbounds double, double* %197, i64 %203
%205 = load double, double* %204
%206 = fmul double %196, %205
%207 = load double, double* %18
%208 = load double*, double** %9
%209 = load i32, i32* %13
%210 = load i32, i32* %16
%211 = mul nsw i32 %209, %210
%212 = load i32, i32* %14
%213 = add nsw i32 %212, 1
%214 = add nsw i32 %211, %213
%215 = sext i32 %214 to i64
%216 = getelementptr inbounds double, double* %208, i64 %215
%217 = load double, double* %216
%218 = call double @llvm.fmuladd.f64(double %206, double %207, double %217)
store double %218, double* %216
%219 = load double, double* %22
%220 = load double*, double** %11
%221 = load i32, i32* %13
%222 = add nsw i32 %221, 1
%223 = sext i32 %222 to i64
%224 = getelementptr inbounds double, double* %220, i64 %223
%225 = load double, double* %224
%226 = fmul double %219, %225
%227 = load double*, double** %11
%228 = load i32, i32* %14
%229 = add nsw i32 %228, 1
%230 = sext i32 %229 to i64
%231 = getelementptr inbounds double, double* %227, i64 %230
%232 = load double, double* %231
%233 = fmul double %226, %232
%234 = load double*, double** %21
%235 = load i32, i32* %13
%236 = load i32, i32* %15
%237 = mul nsw i32 %235, %236
%238 = load i32, i32* %14
%239 = add nsw i32 %237, %238
%240 = sext i32 %239 to i64
%241 = getelementptr inbounds double, double* %234, i64 %240
%242 = load double, double* %241
%243 = fmul double %233, %242
%244 = load double, double* %17
%245 = load double*, double** %9
%246 = load i32, i32* %13
%247 = add nsw i32 %246, 1
%248 = load i32, i32* %16
%249 = mul nsw i32 %247, %248
%250 = load i32, i32* %14
%251 = add nsw i32 %250, 1
%252 = add nsw i32 %249, %251
%253 = sext i32 %252 to i64
%254 = getelementptr inbounds double, double* %245, i64 %253
%255 = load double, double* %254
%256 = call double @llvm.fmuladd.f64(double %243, double %244, double %255)
store double %256, double* %254
br label %257
257: ; preds = %103
%258 = load i32, i32* %14
%259 = add nsw i32 %258, 1
store i32 %259, i32* %14
br label %99
260: ; preds = %99
br label %261
261: ; preds = %260
%262 = load i32, i32* %13
%263 = add nsw i32 %262, 1
store i32 %263, i32* %13
br label %94
264: ; preds = %94
%265 = load i32, i32* %15
%266 = load i32, i32* %7
%267 = mul nsw i32 2, %266
%268 = sub nsw i32 %267, 1
%269 = icmp eq i32 %265, %268
br i1 %269, label %270, label %281
270: ; preds = %264
%271 = load double*, double** %21
%272 = bitcast double* %271 to i8*
%273 = load double*, double** %9
%274 = bitcast double* %273 to i8*
%275 = load i32, i32* %16
%276 = sext i32 %275 to i64
%277 = mul i64 8, %276
%278 = load i32, i32* %16
%279 = sext i32 %278 to i64
%280 = mul i64 %277, %279
br label %281
281: ; preds = %270, %264
br label %282
282: ; preds = %281
%283 = load i32, i32* %15
%284 = add nsw i32 %283, 1
store i32 %284, i32* %15
br label %74
285: ; preds = %74
br label %349
286: ; preds = %6
%287 = load i32, i32* %7
%288 = icmp eq i32 %287, 0
br i1 %288, label %289, label %292
289: ; preds = %286
%290 = load double*, double** %9
%291 = getelementptr inbounds double, double* %290, i64 0
store double 1.000000e+00, double* %291
br label %348
292: ; preds = %286
%293 = load double, double* %17
%294 = load double, double* %17
%295 = fmul double %293, %294
%296 = load double*, double** %9
%297 = getelementptr inbounds double, double* %296, i64 0
store double %295, double* %297
%298 = load double*, double** %11
%299 = getelementptr inbounds double, double* %298, i64 2
%300 = load double, double* %299
%301 = load double, double* %17
%302 = fmul double %300, %301
%303 = load double, double* %18
%304 = fmul double %302, %303
%305 = load double*, double** %9
%306 = getelementptr inbounds double, double* %305, i64 1
store double %304, double* %306
%307 = load double, double* %18
%308 = load double, double* %18
%309 = fmul double %307, %308
%310 = load double*, double** %9
%311 = getelementptr inbounds double, double* %310, i64 2
store double %309, double* %311
%312 = load double*, double** %9
%313 = getelementptr inbounds double, double* %312, i64 1
%314 = load double, double* %313
%315 = fneg double %314
%316 = load double*, double** %9
%317 = getelementptr inbounds double, double* %316, i64 3
store double %315, double* %317
%318 = load double*, double** %9
%319 = getelementptr inbounds double, double* %318, i64 0
%320 = load double, double* %319
%321 = load double*, double** %9
%322 = getelementptr inbounds double, double* %321, i64 2
%323 = load double, double* %322
%324 = fsub double %320, %323
%325 = load double*, double** %9
%326 = getelementptr inbounds double, double* %325, i64 4
store double %324, double* %326
%327 = load double*, double** %9
%328 = getelementptr inbounds double, double* %327, i64 1
%329 = load double, double* %328
%330 = load double*, double** %9
%331 = getelementptr inbounds double, double* %330, i64 5
store double %329, double* %331
%332 = load double*, double** %9
%333 = getelementptr inbounds double, double* %332, i64 2
%334 = load double, double* %333
%335 = load double*, double** %9
%336 = getelementptr inbounds double, double* %335, i64 6
store double %334, double* %336
%337 = load double*, double** %9
%338 = getelementptr inbounds double, double* %337, i64 1
%339 = load double, double* %338
%340 = fneg double %339
%341 = load double*, double** %9
%342 = getelementptr inbounds double, double* %341, i64 7
store double %340, double* %342
%343 = load double*, double** %9
%344 = getelementptr inbounds double, double* %343, i64 0
%345 = load double, double* %344
%346 = load double*, double** %9
%347 = getelementptr inbounds double, double* %346, i64 8
store double %345, double* %347
br label %348
348: ; preds = %292, %289
br label %349
349: ; preds = %348, %285
ret void
}

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