void naive_multiplication(double A[][6144], double B[][6144],
                          double C[][6144]) {
  for (int i = 0; i < 6144; ++i) {
    for (int j = 0; j < 6144; ++j) {
      for (int k = 0; k < 6144; ++k) {
        C[i][j] += A[i][k] * B[k][j];
      }
    }
  }
}


x86 assembly (clang, -O0):
<naive_multiplication>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
cmpl   $0x1800,-0x1c(%rbp)
jge    11de <naive_multiplication+0xde>
movl   $0x0,-0x20(%rbp)
cmpl   $0x1800,-0x20(%rbp)
jge    11cb <naive_multiplication+0xcb>
movl   $0x0,-0x24(%rbp)
cmpl   $0x1800,-0x24(%rbp)
jge    11b8 <naive_multiplication+0xb8>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
imul   $0xc000,%rcx,%rcx
add    %rcx,%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
imul   $0xc000,%rcx,%rcx
add    %rcx,%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
imul   $0xc000,%rcx,%rcx
add    %rcx,%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    113f <naive_multiplication+0x3f>
jmp    11bd <naive_multiplication+0xbd>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    112b <naive_multiplication+0x2b>
jmp    11d0 <naive_multiplication+0xd0>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1117 <naive_multiplication+0x17>
pop    %rbp
ret

x86 assembly (clang, -O2):
<naive_multiplication>:
xor    %r8d,%r8d
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %rsi,%r9
xor    %r10d,%r10d
cs nopw 0x0(%rax,%rax,1)
lea    (%r8,%r8,2),%rax
shl    $0xe,%rax
add    %rdx,%rax
lea    (%rax,%r10,8),%r11
movsd  (%rax,%r10,8),%xmm0
mov    $0x1,%eax
mov    %r9,%rcx
nopl   (%rax)
movsd  -0x8(%rdi,%rax,8),%xmm1
mulsd  (%rcx),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,(%r11)
movsd  (%rdi,%rax,8),%xmm0
mulsd  0xc000(%rcx),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%r11)
add    $0x2,%rax
add    $0x18000,%rcx
cmp    $0x1801,%rax
jne    1140 <naive_multiplication+0x40>
add    $0x1,%r10
add    $0x8,%r9
cmp    $0x1800,%r10
jne    1120 <naive_multiplication+0x20>
add    $0x1,%r8
add    $0xc000,%rdi
cmp    $0x1800,%r8
jne    1110 <naive_multiplication+0x10>
ret

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

LLVM IR (-O2):
define void @naive_multiplication([6144 x double]* nocapture %0, [6144 x double]* nocapture %1, [6144 x double]* nocapture %2) {
br label %4
4: ; preds = %3, %11
%5 = phi i64 [ 0, %3 ], [ %12, %11 ]
br label %7
6: ; preds = %11
ret void
7: ; preds = %4, %14
%8 = phi i64 [ 0, %4 ], [ %15, %14 ]
%9 = getelementptr inbounds [6144 x double], [6144 x double]* %2, i64 %5, i64 %8
%10 = load double, double* %9
br label %17
11: ; preds = %14
%12 = add nuw nsw i64 %5, 1
%13 = icmp eq i64 %12, 6144
br i1 %13, label %6, label %4
14: ; preds = %17
%15 = add nuw nsw i64 %8, 1
%16 = icmp eq i64 %15, 6144
br i1 %16, label %11, label %7
17: ; preds = %17, %7
%18 = phi double [ %10, %7 ], [ %30, %17 ]
%19 = phi i64 [ 0, %7 ], [ %31, %17 ]
%20 = getelementptr inbounds [6144 x double], [6144 x double]* %0, i64 %5, i64 %19
%21 = load double, double* %20
%22 = getelementptr inbounds [6144 x double], [6144 x double]* %1, i64 %19, i64 %8
%23 = load double, double* %22
%24 = tail call double @llvm.fmuladd.f64(double %21, double %23, double %18)
store double %24, double* %9
%25 = or i64 %19, 1
%26 = getelementptr inbounds [6144 x double], [6144 x double]* %0, i64 %5, i64 %25
%27 = load double, double* %26
%28 = getelementptr inbounds [6144 x double], [6144 x double]* %1, i64 %25, i64 %8
%29 = load double, double* %28
%30 = tail call double @llvm.fmuladd.f64(double %27, double %29, double %24)
store double %30, double* %9
%31 = add nuw nsw i64 %19, 2
%32 = icmp eq i64 %31, 6144
br i1 %32, label %14, label %17
}