void matmul_sub(double ablock[5][5], double bblock[5][5], double cblock[5][5]) {
  int j;
  for (j = 0; j < 5; j++) {
    cblock[0][j] = cblock[0][j] - ablock[0][0] * bblock[0][j] -
                   ablock[0][1] * bblock[1][j] - ablock[0][2] * bblock[2][j] -
                   ablock[0][3] * bblock[3][j] - ablock[0][4] * bblock[4][j];
    cblock[1][j] = cblock[1][j] - ablock[1][0] * bblock[0][j] -
                   ablock[1][1] * bblock[1][j] - ablock[1][2] * bblock[2][j] -
                   ablock[1][3] * bblock[3][j] - ablock[1][4] * bblock[4][j];
    cblock[2][j] = cblock[2][j] - ablock[2][0] * bblock[0][j] -
                   ablock[2][1] * bblock[1][j] - ablock[2][2] * bblock[2][j] -
                   ablock[2][3] * bblock[3][j] - ablock[2][4] * bblock[4][j];
    cblock[3][j] = cblock[3][j] - ablock[3][0] * bblock[0][j] -
                   ablock[3][1] * bblock[1][j] - ablock[3][2] * bblock[2][j] -
                   ablock[3][3] * bblock[3][j] - ablock[3][4] * bblock[4][j];
    cblock[4][j] = cblock[4][j] - ablock[4][0] * bblock[0][j] -
                   ablock[4][1] * bblock[1][j] - ablock[4][2] * bblock[2][j] -
                   ablock[4][3] * bblock[3][j] - ablock[4][4] * bblock[4][j];
  }
}


x86 assembly (clang, -O0):
<matmul_sub>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
cmpl   $0x5,-0x1c(%rbp)
jge    1729 <matmul_sub+0x629>
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x28(%rax,%rcx,8),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x50(%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0x18(%rax),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x78(%rax,%rcx,8),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0x20(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0xa0(%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x28(%rax,%rcx,8),%xmm1
mov    -0x8(%rbp),%rax
movsd  0x28(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0x30(%rax),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x28(%rax,%rcx,8),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0x38(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x50(%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0x40(%rax),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x78(%rax,%rcx,8),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0x48(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0xa0(%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  %xmm0,0x28(%rax,%rcx,8)
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x50(%rax,%rcx,8),%xmm1
mov    -0x8(%rbp),%rax
movsd  0x50(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0x58(%rax),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x28(%rax,%rcx,8),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0x60(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x50(%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0x68(%rax),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x78(%rax,%rcx,8),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0x70(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0xa0(%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  %xmm0,0x50(%rax,%rcx,8)
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x78(%rax,%rcx,8),%xmm1
mov    -0x8(%rbp),%rax
movsd  0x78(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0x80(%rax),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x28(%rax,%rcx,8),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0x88(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x50(%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0x90(%rax),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x78(%rax,%rcx,8),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0x98(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0xa0(%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  %xmm0,0x78(%rax,%rcx,8)
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0xa0(%rax,%rcx,8),%xmm1
mov    -0x8(%rbp),%rax
movsd  0xa0(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0xa8(%rax),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x28(%rax,%rcx,8),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0xb0(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x50(%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0xb8(%rax),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0x78(%rax,%rcx,8),%xmm2
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0xc0(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  0xa0(%rax,%rcx,8),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  %xmm0,0xa0(%rax,%rcx,8)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1117 <matmul_sub+0x17>
pop    %rbp
ret

x86 assembly (clang, -O2):
<matmul_sub>:
mov    $0xfffffffffffffffb,%rax
nopw   0x0(%rax,%rax,1)
movsd  (%rdi),%xmm0
mulsd  0x28(%rsi,%rax,8),%xmm0
movsd  0x8(%rdi),%xmm1
movsd  0x28(%rdx,%rax,8),%xmm2
subsd  %xmm0,%xmm2
movsd  0x50(%rdx,%rax,8),%xmm0
mulsd  0x50(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm2
movsd  0x10(%rdi),%xmm1
mulsd  0x78(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm2
movsd  0x18(%rdi),%xmm1
mulsd  0xa0(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm2
movsd  0x20(%rdi),%xmm1
mulsd  0xc8(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm2
movsd  %xmm2,0x28(%rdx,%rax,8)
movsd  0x28(%rdi),%xmm1
movsd  0x30(%rdi),%xmm2
mulsd  0x28(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm0
mulsd  0x50(%rsi,%rax,8),%xmm2
subsd  %xmm2,%xmm0
movsd  0x38(%rdi),%xmm1
mulsd  0x78(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm0
movsd  0x40(%rdi),%xmm1
mulsd  0xa0(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm0
movsd  0x48(%rdi),%xmm1
mulsd  0xc8(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,0x50(%rdx,%rax,8)
movsd  0x78(%rdx,%rax,8),%xmm0
movsd  0x50(%rdi),%xmm1
movsd  0x58(%rdi),%xmm2
mulsd  0x28(%rsi,%rax,8),%xmm1
mulsd  0x50(%rsi,%rax,8),%xmm2
subsd  %xmm1,%xmm0
movsd  0x60(%rdi),%xmm1
mulsd  0x78(%rsi,%rax,8),%xmm1
subsd  %xmm2,%xmm0
movsd  0x68(%rdi),%xmm2
mulsd  0xa0(%rsi,%rax,8),%xmm2
subsd  %xmm1,%xmm0
movsd  0x70(%rdi),%xmm1
mulsd  0xc8(%rsi,%rax,8),%xmm1
subsd  %xmm2,%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,0x78(%rdx,%rax,8)
movsd  0xa0(%rdx,%rax,8),%xmm0
movsd  0x78(%rdi),%xmm1
movsd  0x80(%rdi),%xmm2
mulsd  0x28(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm0
mulsd  0x50(%rsi,%rax,8),%xmm2
subsd  %xmm2,%xmm0
movsd  0x88(%rdi),%xmm1
mulsd  0x78(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm0
movsd  0x90(%rdi),%xmm1
mulsd  0xa0(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm0
movsd  0x98(%rdi),%xmm1
mulsd  0xc8(%rsi,%rax,8),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,0xa0(%rdx,%rax,8)
movsd  0xc8(%rdx,%rax,8),%xmm0
movsd  0xa0(%rdi),%xmm1
movsd  0xa8(%rdi),%xmm2
mulsd  0x28(%rsi,%rax,8),%xmm1
mulsd  0x50(%rsi,%rax,8),%xmm2
subsd  %xmm1,%xmm0
movsd  0xb0(%rdi),%xmm1
mulsd  0x78(%rsi,%rax,8),%xmm1
subsd  %xmm2,%xmm0
movsd  0xb8(%rdi),%xmm2
mulsd  0xa0(%rsi,%rax,8),%xmm2
subsd  %xmm1,%xmm0
movsd  0xc0(%rdi),%xmm1
mulsd  0xc8(%rsi,%rax,8),%xmm1
subsd  %xmm2,%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,0xc8(%rdx,%rax,8)
inc    %rax
jne    1110 <matmul_sub+0x10>
ret

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

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