int main(int argc, char *argv[]) {
  int i, j, k;
  double **a = (double **)malloc(sizeof(double *) * 800);
  for (i = 0; i < 800; i++)
    a[i] = (double *)malloc(sizeof(double) * 800);
  double **b = (double **)malloc(sizeof(double *) * 800);
  for (i = 0; i < 800; i++)
    b[i] = (double *)malloc(sizeof(double) * 800);
  double **c = (double **)malloc(sizeof(double *) * 800);
  for (i = 0; i < 800; i++)
    c[i] = (double *)malloc(sizeof(double) * 800);
  printf("Initializing matrices...\n");
  omp_set_num_threads(4);
  for (i = 0; i < 800; i++)
    for (j = 0; j < 800; j++)
      a[i][j] = i + j;
  for (i = 0; i < 800; i++)
    for (j = 0; j < 800; j++)
      b[i][j] = i * j;
  for (i = 0; i < 800; i++)
    for (j = 0; j < 800; j++)
      c[i][j] = 0;
#pragma omp parallel for schedule(guided, 1) private(j, k)
  for (i = 0; i < 800; i++)
    for (j = 0; j < 800; j++)
      for (k = 0; k < 800; k++)
        c[i][j] += a[i][k] * b[k][j];
  for (i = 0; i < 800; i++)
    free(a[i]);
  free(a);
  for (i = 0; i < 800; i++)
    free(b[i]);
  free(b);
  for (i = 0; i < 800; i++)
    free(c[i]);
  free(c);
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    $0x1900,%edi
call   1050 <malloc@plt>
mov    %rax,-0x28(%rbp)
movl   $0x0,-0x14(%rbp)
cmpl   $0x320,-0x14(%rbp)
jge    119f <main+0x5f>
mov    $0x1900,%edi
call   1050 <malloc@plt>
mov    %rax,%rdx
mov    -0x28(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    116b <main+0x2b>
mov    $0x1900,%edi
call   1050 <malloc@plt>
mov    %rax,-0x30(%rbp)
movl   $0x0,-0x14(%rbp)
cmpl   $0x320,-0x14(%rbp)
jge    11e8 <main+0xa8>
mov    $0x1900,%edi
call   1050 <malloc@plt>
mov    %rax,%rdx
mov    -0x30(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    11b4 <main+0x74>
mov    $0x1900,%edi
call   1050 <malloc@plt>
mov    %rax,-0x38(%rbp)
movl   $0x0,-0x14(%rbp)
cmpl   $0x320,-0x14(%rbp)
jge    1231 <main+0xf1>
mov    $0x1900,%edi
call   1050 <malloc@plt>
mov    %rax,%rdx
mov    -0x38(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    11fd <main+0xbd>
lea    0xdc8(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
mov    $0x4,%edi
mov    $0x0,%al
call   1060 <omp_set_num_threads@plt>
movl   $0x0,-0x14(%rbp)
cmpl   $0x320,-0x14(%rbp)
jge    12b3 <main+0x173>
movl   $0x0,-0x18(%rbp)
cmpl   $0x320,-0x18(%rbp)
jge    12a0 <main+0x160>
mov    -0x14(%rbp),%eax
add    -0x18(%rbp),%eax
cvtsi2sd %eax,%xmm0
mov    -0x28(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x18(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1266 <main+0x126>
jmp    12a5 <main+0x165>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1252 <main+0x112>
movl   $0x0,-0x14(%rbp)
cmpl   $0x320,-0x14(%rbp)
jge    131c <main+0x1dc>
movl   $0x0,-0x18(%rbp)
cmpl   $0x320,-0x18(%rbp)
jge    1309 <main+0x1c9>
mov    -0x14(%rbp),%eax
imul   -0x18(%rbp),%eax
cvtsi2sd %eax,%xmm0
mov    -0x30(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x18(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    12ce <main+0x18e>
jmp    130e <main+0x1ce>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    12ba <main+0x17a>
movl   $0x0,-0x14(%rbp)
cmpl   $0x320,-0x14(%rbp)
jge    137d <main+0x23d>
movl   $0x0,-0x18(%rbp)
cmpl   $0x320,-0x18(%rbp)
jge    136a <main+0x22a>
mov    -0x38(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x18(%rbp),%rcx
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1337 <main+0x1f7>
jmp    136f <main+0x22f>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1323 <main+0x1e3>
movl   $0x0,-0x14(%rbp)
cmpl   $0x320,-0x14(%rbp)
jge    1439 <main+0x2f9>
movl   $0x0,-0x18(%rbp)
cmpl   $0x320,-0x18(%rbp)
jge    1426 <main+0x2e6>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x320,-0x1c(%rbp)
jge    1413 <main+0x2d3>
mov    -0x28(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x30(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x18(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x38(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x18(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    13ac <main+0x26c>
jmp    1418 <main+0x2d8>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1398 <main+0x258>
jmp    142b <main+0x2eb>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1384 <main+0x244>
movl   $0x0,-0x14(%rbp)
cmpl   $0x320,-0x14(%rbp)
jge    146c <main+0x32c>
mov    -0x28(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rdi
call   1030 <free@plt>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1440 <main+0x300>
mov    -0x28(%rbp),%rdi
call   1030 <free@plt>
movl   $0x0,-0x14(%rbp)
cmpl   $0x320,-0x14(%rbp)
jge    14a8 <main+0x368>
mov    -0x30(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rdi
call   1030 <free@plt>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    147c <main+0x33c>
mov    -0x30(%rbp),%rdi
call   1030 <free@plt>
movl   $0x0,-0x14(%rbp)
cmpl   $0x320,-0x14(%rbp)
jge    14e4 <main+0x3a4>
mov    -0x38(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rdi
call   1030 <free@plt>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    14b8 <main+0x378>
mov    -0x38(%rbp),%rdi
call   1030 <free@plt>
xor    %eax,%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %r15
push   %r14
push   %r12
push   %rbx
push   %rax
mov    $0x1900,%edi
call   1060 <malloc@plt>
mov    %rax,%r14
xor    %ebx,%ebx
nopw   0x0(%rax,%rax,1)
mov    $0x1900,%edi
call   1060 <malloc@plt>
mov    %rax,(%r14,%rbx,8)
add    $0x1,%rbx
cmp    $0x320,%rbx
jne    1170 <main+0x20>
mov    $0x1900,%edi
call   1060 <malloc@plt>
mov    %rax,%rbx
xor    %r15d,%r15d
nopl   0x0(%rax,%rax,1)
mov    $0x1900,%edi
call   1060 <malloc@plt>
mov    %rax,(%rbx,%r15,8)
add    $0x1,%r15
cmp    $0x320,%r15
jne    11a0 <main+0x50>
mov    $0x1900,%edi
call   1060 <malloc@plt>
mov    %rax,%r15
xor    %r12d,%r12d
nopl   0x0(%rax,%rax,1)
mov    $0x1900,%edi
call   1060 <malloc@plt>
mov    %rax,(%r15,%r12,8)
add    $0x1,%r12
cmp    $0x320,%r12
jne    11d0 <main+0x80>
lea    0xe2e(%rip),%rdi
call   1040 <puts@plt>
xor    %r12d,%r12d
mov    $0x4,%edi
xor    %eax,%eax
call   1070 <omp_set_num_threads@plt>
movdqa 0xdf2(%rip),%xmm0
movdqa 0xdfa(%rip),%xmm1
cs nopw 0x0(%rax,%rax,1)
mov    (%r14,%r12,8),%rax
movq   %r12,%xmm2
pshufd $0x44,%xmm2,%xmm2
lea    0x2(%r12),%rcx
movq   %rcx,%xmm3
pshufd $0x44,%xmm3,%xmm3
mov    $0x2,%ecx
movdqa %xmm0,%xmm4
cs nopw 0x0(%rax,%rax,1)
movdqa %xmm4,%xmm5
paddq  %xmm2,%xmm5
movdqa %xmm3,%xmm6
paddq  %xmm4,%xmm6
pshufd $0xe8,%xmm5,%xmm5
cvtdq2pd %xmm5,%xmm5
pshufd $0xe8,%xmm6,%xmm6
cvtdq2pd %xmm6,%xmm6
movups %xmm5,-0x10(%rax,%rcx,8)
movups %xmm6,(%rax,%rcx,8)
paddq  %xmm1,%xmm4
add    $0x4,%rcx
cmp    $0x322,%rcx
jne    1250 <main+0x100>
add    $0x1,%r12
cmp    $0x320,%r12
jne    1220 <main+0xd0>
xor    %r8d,%r8d
xor    %r9d,%r9d
nop
mov    (%rbx,%r9,8),%rdx
mov    $0x4,%esi
xor    %edi,%edi
xor    %eax,%eax
nopl   (%rax)
xorps  %xmm0,%xmm0
cvtsi2sd %edi,%xmm0
movsd  %xmm0,-0x20(%rdx,%rsi,8)
lea    0x1(%rax),%ecx
imul   %r9d,%ecx
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
lea    0x2(%rax),%ecx
imul   %r9d,%ecx
xorps  %xmm1,%xmm1
cvtsi2sd %ecx,%xmm1
movsd  %xmm0,-0x18(%rdx,%rsi,8)
movsd  %xmm1,-0x10(%rdx,%rsi,8)
lea    0x3(%rax),%ecx
imul   %r9d,%ecx
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
movsd  %xmm0,-0x8(%rdx,%rsi,8)
lea    0x4(%rax),%ecx
imul   %r9d,%ecx
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
movsd  %xmm0,(%rdx,%rsi,8)
add    $0x5,%rax
add    $0x5,%rsi
add    %r8d,%edi
cmp    $0x324,%rsi
jne    12b0 <main+0x160>
add    $0x1,%r9
add    $0x5,%r8d
cmp    $0x320,%r9
jne    12a0 <main+0x150>
mov    $0x7,%r12d
nopl   0x0(%rax,%rax,1)
mov    -0x38(%r15,%r12,8),%rdi
mov    $0x1900,%edx
xor    %esi,%esi
call   1050 <memset@plt>
mov    -0x30(%r15,%r12,8),%rdi
mov    $0x1900,%edx
xor    %esi,%esi
call   1050 <memset@plt>
mov    -0x28(%r15,%r12,8),%rdi
mov    $0x1900,%edx
xor    %esi,%esi
call   1050 <memset@plt>
mov    -0x20(%r15,%r12,8),%rdi
mov    $0x1900,%edx
xor    %esi,%esi
call   1050 <memset@plt>
mov    -0x18(%r15,%r12,8),%rdi
mov    $0x1900,%edx
xor    %esi,%esi
call   1050 <memset@plt>
mov    -0x10(%r15,%r12,8),%rdi
mov    $0x1900,%edx
xor    %esi,%esi
call   1050 <memset@plt>
mov    -0x8(%r15,%r12,8),%rdi
mov    $0x1900,%edx
xor    %esi,%esi
call   1050 <memset@plt>
mov    (%r15,%r12,8),%rdi
mov    $0x1900,%edx
xor    %esi,%esi
call   1050 <memset@plt>
add    $0x8,%r12
cmp    $0x327,%r12
jne    1340 <main+0x1f0>
xor    %r8d,%r8d
nopl   0x0(%rax,%rax,1)
mov    (%r14,%r8,8),%rcx
mov    (%r15,%r8,8),%rdx
xor    %esi,%esi
nopw   0x0(%rax,%rax,1)
movsd  (%rdx,%rsi,8),%xmm0
mov    $0x1,%edi
nopw   0x0(%rax,%rax,1)
movsd  -0x8(%rcx,%rdi,8),%xmm1
mov    -0x8(%rbx,%rdi,8),%rax
mulsd  (%rax,%rsi,8),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,(%rdx,%rsi,8)
movsd  (%rcx,%rdi,8),%xmm0
mov    (%rbx,%rdi,8),%rax
mulsd  (%rax,%rsi,8),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rdx,%rsi,8)
add    $0x2,%rdi
cmp    $0x321,%rdi
jne    1400 <main+0x2b0>
add    $0x1,%rsi
cmp    $0x320,%rsi
jne    13f0 <main+0x2a0>
add    $0x1,%r8
cmp    $0x320,%r8
jne    13e0 <main+0x290>
xor    %r12d,%r12d
nopw   0x0(%rax,%rax,1)
mov    (%r14,%r12,8),%rdi
call   1030 <free@plt>
add    $0x1,%r12
cmp    $0x320,%r12
jne    1460 <main+0x310>
mov    %r14,%rdi
call   1030 <free@plt>
xor    %r14d,%r14d
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    (%rbx,%r14,8),%rdi
call   1030 <free@plt>
add    $0x1,%r14
cmp    $0x320,%r14
jne    1490 <main+0x340>
mov    %rbx,%rdi
call   1030 <free@plt>
xor    %ebx,%ebx
mov    (%r15,%rbx,8),%rdi
call   1030 <free@plt>
add    $0x1,%rbx
cmp    $0x320,%rbx
jne    14b0 <main+0x360>
mov    %r15,%rdi
call   1030 <free@plt>
xor    %eax,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@.str = [26 x i8] c"Initializing matrices...\0A\00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca double**
%10 = alloca double**
%11 = alloca double**
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%12 = call i8* @malloc(i64 6400)
%13 = bitcast i8* %12 to double**
store double** %13, double*** %9
store i32 0, i32* %6
br label %14
14: ; preds = %24, %2
%15 = load i32, i32* %6
%16 = icmp slt i32 %15, 800
br i1 %16, label %17, label %27
17: ; preds = %14
%18 = call i8* @malloc(i64 6400)
%19 = bitcast i8* %18 to double*
%20 = load double**, double*** %9
%21 = load i32, i32* %6
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds double*, double** %20, i64 %22
store double* %19, double** %23
br label %24
24: ; preds = %17
%25 = load i32, i32* %6
%26 = add nsw i32 %25, 1
store i32 %26, i32* %6
br label %14
27: ; preds = %14
%28 = call i8* @malloc(i64 6400)
%29 = bitcast i8* %28 to double**
store double** %29, double*** %10
store i32 0, i32* %6
br label %30
30: ; preds = %40, %27
%31 = load i32, i32* %6
%32 = icmp slt i32 %31, 800
br i1 %32, label %33, label %43
33: ; preds = %30
%34 = call i8* @malloc(i64 6400)
%35 = bitcast i8* %34 to double*
%36 = load double**, double*** %10
%37 = load i32, i32* %6
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds double*, double** %36, i64 %38
store double* %35, double** %39
br label %40
40: ; preds = %33
%41 = load i32, i32* %6
%42 = add nsw i32 %41, 1
store i32 %42, i32* %6
br label %30
43: ; preds = %30
%44 = call i8* @malloc(i64 6400)
%45 = bitcast i8* %44 to double**
store double** %45, double*** %11
store i32 0, i32* %6
br label %46
46: ; preds = %56, %43
%47 = load i32, i32* %6
%48 = icmp slt i32 %47, 800
br i1 %48, label %49, label %59
49: ; preds = %46
%50 = call i8* @malloc(i64 6400)
%51 = bitcast i8* %50 to double*
%52 = load double**, double*** %11
%53 = load i32, i32* %6
%54 = sext i32 %53 to i64
%55 = getelementptr inbounds double*, double** %52, i64 %54
store double* %51, double** %55
br label %56
56: ; preds = %49
%57 = load i32, i32* %6
%58 = add nsw i32 %57, 1
store i32 %58, i32* %6
br label %46
59: ; preds = %46
%60 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str, i64 0, i64 0))
%61 = call i32 (i32, ...) bitcast (i32 (...)* @omp_set_num_threads to i32 (i32, ...)*)(i32 4)
store i32 0, i32* %6
br label %62
62: ; preds = %86, %59
%63 = load i32, i32* %6
%64 = icmp slt i32 %63, 800
br i1 %64, label %65, label %89
65: ; preds = %62
store i32 0, i32* %7
br label %66
66: ; preds = %82, %65
%67 = load i32, i32* %7
%68 = icmp slt i32 %67, 800
br i1 %68, label %69, label %85
69: ; preds = %66
%70 = load i32, i32* %6
%71 = load i32, i32* %7
%72 = add nsw i32 %70, %71
%73 = sitofp i32 %72 to double
%74 = load double**, double*** %9
%75 = load i32, i32* %6
%76 = sext i32 %75 to i64
%77 = getelementptr inbounds double*, double** %74, i64 %76
%78 = load double*, double** %77
%79 = load i32, i32* %7
%80 = sext i32 %79 to i64
%81 = getelementptr inbounds double, double* %78, i64 %80
store double %73, double* %81
br label %82
82: ; preds = %69
%83 = load i32, i32* %7
%84 = add nsw i32 %83, 1
store i32 %84, i32* %7
br label %66
85: ; preds = %66
br label %86
86: ; preds = %85
%87 = load i32, i32* %6
%88 = add nsw i32 %87, 1
store i32 %88, i32* %6
br label %62
89: ; preds = %62
store i32 0, i32* %6
br label %90
90: ; preds = %114, %89
%91 = load i32, i32* %6
%92 = icmp slt i32 %91, 800
br i1 %92, label %93, label %117
93: ; preds = %90
store i32 0, i32* %7
br label %94
94: ; preds = %110, %93
%95 = load i32, i32* %7
%96 = icmp slt i32 %95, 800
br i1 %96, label %97, label %113
97: ; preds = %94
%98 = load i32, i32* %6
%99 = load i32, i32* %7
%100 = mul nsw i32 %98, %99
%101 = sitofp i32 %100 to double
%102 = load double**, double*** %10
%103 = load i32, i32* %6
%104 = sext i32 %103 to i64
%105 = getelementptr inbounds double*, double** %102, i64 %104
%106 = load double*, double** %105
%107 = load i32, i32* %7
%108 = sext i32 %107 to i64
%109 = getelementptr inbounds double, double* %106, i64 %108
store double %101, double* %109
br label %110
110: ; preds = %97
%111 = load i32, i32* %7
%112 = add nsw i32 %111, 1
store i32 %112, i32* %7
br label %94
113: ; preds = %94
br label %114
114: ; preds = %113
%115 = load i32, i32* %6
%116 = add nsw i32 %115, 1
store i32 %116, i32* %6
br label %90
117: ; preds = %90
store i32 0, i32* %6
br label %118
118: ; preds = %138, %117
%119 = load i32, i32* %6
%120 = icmp slt i32 %119, 800
br i1 %120, label %121, label %141
121: ; preds = %118
store i32 0, i32* %7
br label %122
122: ; preds = %134, %121
%123 = load i32, i32* %7
%124 = icmp slt i32 %123, 800
br i1 %124, label %125, label %137
125: ; preds = %122
%126 = load double**, double*** %11
%127 = load i32, i32* %6
%128 = sext i32 %127 to i64
%129 = getelementptr inbounds double*, double** %126, i64 %128
%130 = load double*, double** %129
%131 = load i32, i32* %7
%132 = sext i32 %131 to i64
%133 = getelementptr inbounds double, double* %130, i64 %132
store double 0.000000e+00, double* %133
br label %134
134: ; preds = %125
%135 = load i32, i32* %7
%136 = add nsw i32 %135, 1
store i32 %136, i32* %7
br label %122
137: ; preds = %122
br label %138
138: ; preds = %137
%139 = load i32, i32* %6
%140 = add nsw i32 %139, 1
store i32 %140, i32* %6
br label %118
141: ; preds = %118
store i32 0, i32* %6
br label %142
142: ; preds = %190, %141
%143 = load i32, i32* %6
%144 = icmp slt i32 %143, 800
br i1 %144, label %145, label %193
145: ; preds = %142
store i32 0, i32* %7
br label %146
146: ; preds = %186, %145
%147 = load i32, i32* %7
%148 = icmp slt i32 %147, 800
br i1 %148, label %149, label %189
149: ; preds = %146
store i32 0, i32* %8
br label %150
150: ; preds = %182, %149
%151 = load i32, i32* %8
%152 = icmp slt i32 %151, 800
br i1 %152, label %153, label %185
153: ; preds = %150
%154 = load double**, double*** %9
%155 = load i32, i32* %6
%156 = sext i32 %155 to i64
%157 = getelementptr inbounds double*, double** %154, i64 %156
%158 = load double*, double** %157
%159 = load i32, i32* %8
%160 = sext i32 %159 to i64
%161 = getelementptr inbounds double, double* %158, i64 %160
%162 = load double, double* %161
%163 = load double**, double*** %10
%164 = load i32, i32* %8
%165 = sext i32 %164 to i64
%166 = getelementptr inbounds double*, double** %163, i64 %165
%167 = load double*, double** %166
%168 = load i32, i32* %7
%169 = sext i32 %168 to i64
%170 = getelementptr inbounds double, double* %167, i64 %169
%171 = load double, double* %170
%172 = load double**, double*** %11
%173 = load i32, i32* %6
%174 = sext i32 %173 to i64
%175 = getelementptr inbounds double*, double** %172, i64 %174
%176 = load double*, double** %175
%177 = load i32, i32* %7
%178 = sext i32 %177 to i64
%179 = getelementptr inbounds double, double* %176, i64 %178
%180 = load double, double* %179
%181 = call double @llvm.fmuladd.f64(double %162, double %171, double %180)
store double %181, double* %179
br label %182
182: ; preds = %153
%183 = load i32, i32* %8
%184 = add nsw i32 %183, 1
store i32 %184, i32* %8
br label %150
185: ; preds = %150
br label %186
186: ; preds = %185
%187 = load i32, i32* %7
%188 = add nsw i32 %187, 1
store i32 %188, i32* %7
br label %146
189: ; preds = %146
br label %190
190: ; preds = %189
%191 = load i32, i32* %6
%192 = add nsw i32 %191, 1
store i32 %192, i32* %6
br label %142
193: ; preds = %142
store i32 0, i32* %6
br label %194
194: ; preds = %204, %193
%195 = load i32, i32* %6
%196 = icmp slt i32 %195, 800
br i1 %196, label %197, label %207
197: ; preds = %194
%198 = load double**, double*** %9
%199 = load i32, i32* %6
%200 = sext i32 %199 to i64
%201 = getelementptr inbounds double*, double** %198, i64 %200
%202 = load double*, double** %201
%203 = bitcast double* %202 to i8*
br label %204
204: ; preds = %197
%205 = load i32, i32* %6
%206 = add nsw i32 %205, 1
store i32 %206, i32* %6
br label %194
207: ; preds = %194
%208 = load double**, double*** %9
%209 = bitcast double** %208 to i8*
store i32 0, i32* %6
br label %210
210: ; preds = %220, %207
%211 = load i32, i32* %6
%212 = icmp slt i32 %211, 800
br i1 %212, label %213, label %223
213: ; preds = %210
%214 = load double**, double*** %10
%215 = load i32, i32* %6
%216 = sext i32 %215 to i64
%217 = getelementptr inbounds double*, double** %214, i64 %216
%218 = load double*, double** %217
%219 = bitcast double* %218 to i8*
br label %220
220: ; preds = %213
%221 = load i32, i32* %6
%222 = add nsw i32 %221, 1
store i32 %222, i32* %6
br label %210
223: ; preds = %210
%224 = load double**, double*** %10
%225 = bitcast double** %224 to i8*
store i32 0, i32* %6
br label %226
226: ; preds = %236, %223
%227 = load i32, i32* %6
%228 = icmp slt i32 %227, 800
br i1 %228, label %229, label %239
229: ; preds = %226
%230 = load double**, double*** %11
%231 = load i32, i32* %6
%232 = sext i32 %231 to i64
%233 = getelementptr inbounds double*, double** %230, i64 %232
%234 = load double*, double** %233
%235 = bitcast double* %234 to i8*
br label %236
236: ; preds = %229
%237 = load i32, i32* %6
%238 = add nsw i32 %237, 1
store i32 %238, i32* %6
br label %226
239: ; preds = %226
%240 = load double**, double*** %11
%241 = bitcast double** %240 to i8*
ret i32 0
}

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