void EvolveCounts(double *ct, double smx[20][20], double *nct) {
  int r, c;
  for (c = 0; c < 20; c++)
    nct[c] = 0.0;
  for (r = 0; r < 20; r++)
    for (c = 0; c < 20; c++)
      nct[c] += smx[r][c] * ct[r];
}


x86 assembly (clang, -O0):
<EvolveCounts>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x20(%rbp)
cmpl   $0x14,-0x20(%rbp)
jge    113f <EvolveCounts+0x3f>
mov    -0x18(%rbp),%rax
movslq -0x20(%rbp),%rcx
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1117 <EvolveCounts+0x17>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x14,-0x1c(%rbp)
jge    11c4 <EvolveCounts+0xc4>
movl   $0x0,-0x20(%rbp)
cmpl   $0x14,-0x20(%rbp)
jge    11b1 <EvolveCounts+0xb1>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
imul   $0xa0,%rcx,%rcx
add    %rcx,%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x18(%rbp),%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1157 <EvolveCounts+0x57>
jmp    11b6 <EvolveCounts+0xb6>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1146 <EvolveCounts+0x46>
pop    %rbp
ret

x86 assembly (clang, -O2):
<EvolveCounts>:
push   %rbp
push   %r14
push   %rbx
xorpd  %xmm0,%xmm0
movupd %xmm0,0x90(%rdx)
movupd %xmm0,0x80(%rdx)
movupd %xmm0,0x70(%rdx)
movupd %xmm0,0x60(%rdx)
movupd %xmm0,0x50(%rdx)
movupd %xmm0,0x40(%rdx)
movupd %xmm0,0x30(%rdx)
movupd %xmm0,0x20(%rdx)
movupd %xmm0,0x10(%rdx)
movupd %xmm0,(%rdx)
lea    0xa0(%rdx),%r8
xor    %ecx,%ecx
mov    %rsi,%r10
jmp    12c8 <EvolveCounts+0x1c8>
movupd (%rsi,%r9,1),%xmm0
movsd  (%rdi,%rcx,8),%xmm1
unpcklpd %xmm1,%xmm1
mulpd  %xmm0,%xmm1
movupd (%rdx),%xmm0
addpd  %xmm1,%xmm0
movupd 0x10(%rdx),%xmm1
movupd 0x20(%rdx),%xmm2
movupd 0x30(%rdx),%xmm3
movupd %xmm0,(%rdx)
movupd 0x10(%rsi,%r9,1),%xmm0
movsd  (%rdi,%rcx,8),%xmm4
unpcklpd %xmm4,%xmm4
mulpd  %xmm0,%xmm4
addpd  %xmm1,%xmm4
movupd %xmm4,0x10(%rdx)
movupd 0x20(%rsi,%r9,1),%xmm0
movsd  (%rdi,%rcx,8),%xmm1
unpcklpd %xmm1,%xmm1
mulpd  %xmm0,%xmm1
addpd  %xmm2,%xmm1
movupd %xmm1,0x20(%rdx)
movupd 0x30(%rsi,%r9,1),%xmm0
movsd  (%rdi,%rcx,8),%xmm1
unpcklpd %xmm1,%xmm1
mulpd  %xmm0,%xmm1
addpd  %xmm3,%xmm1
movupd %xmm1,0x30(%rdx)
movupd 0x40(%rsi,%r9,1),%xmm0
movsd  (%rdi,%rcx,8),%xmm1
unpcklpd %xmm1,%xmm1
mulpd  %xmm0,%xmm1
movupd 0x40(%rdx),%xmm0
addpd  %xmm1,%xmm0
movupd %xmm0,0x40(%rdx)
movupd 0x50(%rsi,%r9,1),%xmm0
movsd  (%rdi,%rcx,8),%xmm1
unpcklpd %xmm1,%xmm1
mulpd  %xmm0,%xmm1
movupd 0x50(%rdx),%xmm0
addpd  %xmm1,%xmm0
movupd %xmm0,0x50(%rdx)
movupd 0x60(%rsi,%r9,1),%xmm0
movsd  (%rdi,%rcx,8),%xmm1
unpcklpd %xmm1,%xmm1
mulpd  %xmm0,%xmm1
movupd 0x60(%rdx),%xmm0
addpd  %xmm1,%xmm0
movupd %xmm0,0x60(%rdx)
movupd 0x70(%rsi,%r9,1),%xmm0
movsd  (%rdi,%rcx,8),%xmm1
unpcklpd %xmm1,%xmm1
mulpd  %xmm0,%xmm1
movupd 0x70(%rdx),%xmm0
addpd  %xmm1,%xmm0
movupd %xmm0,0x70(%rdx)
movupd 0x80(%rsi,%r9,1),%xmm0
movsd  (%rdi,%rcx,8),%xmm1
unpcklpd %xmm1,%xmm1
mulpd  %xmm0,%xmm1
movupd 0x80(%rdx),%xmm0
addpd  %xmm1,%xmm0
movupd %xmm0,0x80(%rdx)
movupd 0x90(%rsi,%r9,1),%xmm0
movsd  (%rdi,%rcx,8),%xmm1
unpcklpd %xmm1,%xmm1
mulpd  %xmm0,%xmm1
movupd 0x90(%rdx),%xmm0
addpd  %xmm1,%xmm0
movupd %xmm0,0x90(%rdx)
add    $0x1,%rcx
add    $0xa0,%r10
cmp    $0x14,%rcx
je     135c <EvolveCounts+0x25c>
lea    (%rdi,%rcx,8),%r11
add    $0x8,%r11
lea    (%rcx,%rcx,4),%r9
shl    $0x5,%r9
lea    (%rsi,%r9,1),%rax
add    $0xa0,%rax
lea    (%rsi,%r9,1),%rbx
cmp    %rdx,%rax
seta   %r14b
cmp    %r8,%rbx
setb   %bl
cmp    %rdx,%r11
seta   %al
lea    (%rdi,%rcx,8),%rbp
cmp    %r8,%rbp
setb   %r11b
test   %bl,%r14b
jne    1312 <EvolveCounts+0x212>
and    %r11b,%al
je     1150 <EvolveCounts+0x50>
mov    $0x1,%eax
nopw   0x0(%rax,%rax,1)
movsd  -0x8(%r10,%rax,8),%xmm0
mulsd  (%rdi,%rcx,8),%xmm0
addsd  -0x8(%rdx,%rax,8),%xmm0
movsd  %xmm0,-0x8(%rdx,%rax,8)
movsd  (%r10,%rax,8),%xmm0
mulsd  (%rdi,%rcx,8),%xmm0
addsd  (%rdx,%rax,8),%xmm0
movsd  %xmm0,(%rdx,%rax,8)
add    $0x2,%rax
cmp    $0x15,%rax
jne    1320 <EvolveCounts+0x220>
jmp    12b3 <EvolveCounts+0x1b3>
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define void @EvolveCounts(double* %0, [20 x double]* %1, double* %2) {
%4 = alloca double*
%5 = alloca [20 x double]*
%6 = alloca double*
%7 = alloca i32
%8 = alloca i32
store double* %0, double** %4
store [20 x double]* %1, [20 x double]** %5
store double* %2, double** %6
store i32 0, i32* %8
br label %9
9: ; preds = %17, %3
%10 = load i32, i32* %8
%11 = icmp slt i32 %10, 20
br i1 %11, label %12, label %20
12: ; preds = %9
%13 = load double*, double** %6
%14 = load i32, i32* %8
%15 = sext i32 %14 to i64
%16 = getelementptr inbounds double, double* %13, i64 %15
store double 0.000000e+00, double* %16
br label %17
17: ; preds = %12
%18 = load i32, i32* %8
%19 = add nsw i32 %18, 1
store i32 %19, i32* %8
br label %9
20: ; preds = %9
store i32 0, i32* %7
br label %21
21: ; preds = %52, %20
%22 = load i32, i32* %7
%23 = icmp slt i32 %22, 20
br i1 %23, label %24, label %55
24: ; preds = %21
store i32 0, i32* %8
br label %25
25: ; preds = %48, %24
%26 = load i32, i32* %8
%27 = icmp slt i32 %26, 20
br i1 %27, label %28, label %51
28: ; preds = %25
%29 = load [20 x double]*, [20 x double]** %5
%30 = load i32, i32* %7
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds [20 x double], [20 x double]* %29, i64 %31
%33 = load i32, i32* %8
%34 = sext i32 %33 to i64
%35 = getelementptr inbounds [20 x double], [20 x double]* %32, i64 0, i64 %34
%36 = load double, double* %35
%37 = load double*, double** %4
%38 = load i32, i32* %7
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds double, double* %37, i64 %39
%41 = load double, double* %40
%42 = load double*, double** %6
%43 = load i32, i32* %8
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds double, double* %42, i64 %44
%46 = load double, double* %45
%47 = call double @llvm.fmuladd.f64(double %36, double %41, double %46)
store double %47, double* %45
br label %48
48: ; preds = %28
%49 = load i32, i32* %8
%50 = add nsw i32 %49, 1
store i32 %50, i32* %8
br label %25
51: ; preds = %25
br label %52
52: ; preds = %51
%53 = load i32, i32* %7
%54 = add nsw i32 %53, 1
store i32 %54, i32* %7
br label %21
55: ; preds = %21
ret void
}

LLVM IR (-O2):
define void @EvolveCounts(double* nocapture %0, [20 x double]* nocapture %1, double* nocapture %2) {
%4 = bitcast double* %2 to i8*
%5 = getelementptr double, double* %2, i64 20
%6 = bitcast double* %2 to <2 x double>*
%7 = bitcast double* %2 to <2 x double>*
%8 = getelementptr inbounds double, double* %2, i64 2
%9 = bitcast double* %8 to <2 x double>*
%10 = bitcast double* %8 to <2 x double>*
%11 = getelementptr inbounds double, double* %2, i64 4
%12 = bitcast double* %11 to <2 x double>*
%13 = bitcast double* %11 to <2 x double>*
%14 = getelementptr inbounds double, double* %2, i64 6
%15 = bitcast double* %14 to <2 x double>*
%16 = bitcast double* %14 to <2 x double>*
%17 = getelementptr inbounds double, double* %2, i64 8
%18 = bitcast double* %17 to <2 x double>*
%19 = bitcast double* %17 to <2 x double>*
%20 = getelementptr inbounds double, double* %2, i64 10
%21 = bitcast double* %20 to <2 x double>*
%22 = bitcast double* %20 to <2 x double>*
%23 = getelementptr inbounds double, double* %2, i64 12
%24 = bitcast double* %23 to <2 x double>*
%25 = bitcast double* %23 to <2 x double>*
%26 = getelementptr inbounds double, double* %2, i64 14
%27 = bitcast double* %26 to <2 x double>*
%28 = bitcast double* %26 to <2 x double>*
%29 = getelementptr inbounds double, double* %2, i64 16
%30 = bitcast double* %29 to <2 x double>*
%31 = bitcast double* %29 to <2 x double>*
%32 = getelementptr inbounds double, double* %2, i64 18
%33 = bitcast double* %32 to <2 x double>*
%34 = bitcast double* %32 to <2 x double>*
br label %35
35: ; preds = %3, %148
%36 = phi i64 [ 0, %3 ], [ %149, %148 ]
%37 = add nuw i64 %36, 1
%38 = getelementptr inbounds double, double* %0, i64 %36
%39 = getelementptr double, double* %0, i64 %37
%40 = getelementptr double, double* %0, i64 %36
%41 = getelementptr [20 x double], [20 x double]* %1, i64 %37, i64 0
%42 = getelementptr [20 x double], [20 x double]* %1, i64 %36, i64 0
%43 = icmp ugt double* %41, %2
%44 = icmp ult double* %42, %5
%45 = and i1 %43, %44
%46 = icmp ugt double* %39, %2
%47 = icmp ult double* %40, %5
%48 = and i1 %46, %47
%49 = or i1 %45, %48
br i1 %49, label %131, label %50
50: ; preds = %35
%51 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 0
%52 = bitcast double* %51 to <2 x double>*
%53 = load <2 x double>, <2 x double>* %52
%54 = load double, double* %38
%55 = insertelement <2 x double> poison, double %54, i64 0
%56 = shufflevector <2 x double> %55, <2 x double> poison, <2 x i32> zeroinitializer
%57 = load <2 x double>, <2 x double>* %6
%58 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %53, <2 x double> %56, <2 x double> %57)
store <2 x double> %58, <2 x double>* %7
%59 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 2
%60 = bitcast double* %59 to <2 x double>*
%61 = load <2 x double>, <2 x double>* %60
%62 = load double, double* %38
%63 = insertelement <2 x double> poison, double %62, i64 0
%64 = shufflevector <2 x double> %63, <2 x double> poison, <2 x i32> zeroinitializer
%65 = load <2 x double>, <2 x double>* %9
%66 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %61, <2 x double> %64, <2 x double> %65)
store <2 x double> %66, <2 x double>* %10
%67 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 4
%68 = bitcast double* %67 to <2 x double>*
%69 = load <2 x double>, <2 x double>* %68
%70 = load double, double* %38
%71 = insertelement <2 x double> poison, double %70, i64 0
%72 = shufflevector <2 x double> %71, <2 x double> poison, <2 x i32> zeroinitializer
%73 = load <2 x double>, <2 x double>* %12
%74 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %69, <2 x double> %72, <2 x double> %73)
store <2 x double> %74, <2 x double>* %13
%75 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 6
%76 = bitcast double* %75 to <2 x double>*
%77 = load <2 x double>, <2 x double>* %76
%78 = load double, double* %38
%79 = insertelement <2 x double> poison, double %78, i64 0
%80 = shufflevector <2 x double> %79, <2 x double> poison, <2 x i32> zeroinitializer
%81 = load <2 x double>, <2 x double>* %15
%82 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %77, <2 x double> %80, <2 x double> %81)
store <2 x double> %82, <2 x double>* %16
%83 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 8
%84 = bitcast double* %83 to <2 x double>*
%85 = load <2 x double>, <2 x double>* %84
%86 = load double, double* %38
%87 = insertelement <2 x double> poison, double %86, i64 0
%88 = shufflevector <2 x double> %87, <2 x double> poison, <2 x i32> zeroinitializer
%89 = load <2 x double>, <2 x double>* %18
%90 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %85, <2 x double> %88, <2 x double> %89)
store <2 x double> %90, <2 x double>* %19
%91 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 10
%92 = bitcast double* %91 to <2 x double>*
%93 = load <2 x double>, <2 x double>* %92
%94 = load double, double* %38
%95 = insertelement <2 x double> poison, double %94, i64 0
%96 = shufflevector <2 x double> %95, <2 x double> poison, <2 x i32> zeroinitializer
%97 = load <2 x double>, <2 x double>* %21
%98 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %93, <2 x double> %96, <2 x double> %97)
store <2 x double> %98, <2 x double>* %22
%99 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 12
%100 = bitcast double* %99 to <2 x double>*
%101 = load <2 x double>, <2 x double>* %100
%102 = load double, double* %38
%103 = insertelement <2 x double> poison, double %102, i64 0
%104 = shufflevector <2 x double> %103, <2 x double> poison, <2 x i32> zeroinitializer
%105 = load <2 x double>, <2 x double>* %24
%106 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %101, <2 x double> %104, <2 x double> %105)
store <2 x double> %106, <2 x double>* %25
%107 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 14
%108 = bitcast double* %107 to <2 x double>*
%109 = load <2 x double>, <2 x double>* %108
%110 = load double, double* %38
%111 = insertelement <2 x double> poison, double %110, i64 0
%112 = shufflevector <2 x double> %111, <2 x double> poison, <2 x i32> zeroinitializer
%113 = load <2 x double>, <2 x double>* %27
%114 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %109, <2 x double> %112, <2 x double> %113)
store <2 x double> %114, <2 x double>* %28
%115 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 16
%116 = bitcast double* %115 to <2 x double>*
%117 = load <2 x double>, <2 x double>* %116
%118 = load double, double* %38
%119 = insertelement <2 x double> poison, double %118, i64 0
%120 = shufflevector <2 x double> %119, <2 x double> poison, <2 x i32> zeroinitializer
%121 = load <2 x double>, <2 x double>* %30
%122 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %117, <2 x double> %120, <2 x double> %121)
store <2 x double> %122, <2 x double>* %31
%123 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 18
%124 = bitcast double* %123 to <2 x double>*
%125 = load <2 x double>, <2 x double>* %124
%126 = load double, double* %38
%127 = insertelement <2 x double> poison, double %126, i64 0
%128 = shufflevector <2 x double> %127, <2 x double> poison, <2 x i32> zeroinitializer
%129 = load <2 x double>, <2 x double>* %33
%130 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %125, <2 x double> %128, <2 x double> %129)
store <2 x double> %130, <2 x double>* %34
br label %148
131: ; preds = %35, %131
%132 = phi i64 [ %146, %131 ], [ 0, %35 ]
%133 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 %132
%134 = load double, double* %133
%135 = load double, double* %38
%136 = getelementptr inbounds double, double* %2, i64 %132
%137 = load double, double* %136
%138 = tail call double @llvm.fmuladd.f64(double %134, double %135, double %137)
store double %138, double* %136
%139 = or i64 %132, 1
%140 = getelementptr inbounds [20 x double], [20 x double]* %1, i64 %36, i64 %139
%141 = load double, double* %140
%142 = load double, double* %38
%143 = getelementptr inbounds double, double* %2, i64 %139
%144 = load double, double* %143
%145 = tail call double @llvm.fmuladd.f64(double %141, double %142, double %144)
store double %145, double* %143
%146 = add nuw nsw i64 %132, 2
%147 = icmp eq i64 %146, 20
br i1 %147, label %148, label %131
148: ; preds = %131, %50
%149 = add nuw nsw i64 %36, 1
%150 = icmp eq i64 %149, 20
br i1 %150, label %151, label %35
151: ; preds = %148
ret void
}