void matrix_multiply_double(int l, int m, int n, double A[l][m], double B[m][n],
                            double C[l][n]) {
  int i, j, k;
  int D[100] = {0};
  for (i = 0; i < l; ++i)
    for (k = 0; k < n; ++k) {
      C[i][k] = 0;
      for (j = 0; j < m; ++j) {
        C[i][k] = C[i][k] + A[i][j] * B[k][j] * D[k];
      }
    }
}


x86 assembly (clang, -O0):
<matrix_multiply_double>:
push   %rbp
mov    %rsp,%rbp
sub    $0x1f0,%rsp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    %rcx,-0x18(%rbp)
mov    %r8,-0x20(%rbp)
mov    %r9,-0x28(%rbp)
mov    -0x8(%rbp),%eax
mov    %rax,-0x1e8(%rbp)
mov    -0xc(%rbp),%eax
mov    %rax,-0x1e0(%rbp)
mov    -0xc(%rbp),%eax
mov    %rax,-0x1d8(%rbp)
lea    -0x1d0(%rbp),%rdi
xor    %esi,%esi
mov    $0x190,%edx
call   1030 <memset@plt>
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    128e <matrix_multiply_double+0x17e>
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    127b <matrix_multiply_double+0x16b>
mov    -0x1d8(%rbp),%rdx
mov    -0x28(%rbp),%rax
movslq -0x2c(%rbp),%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x34(%rbp),%rcx
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    1268 <matrix_multiply_double+0x158>
mov    -0x1d8(%rbp),%rdx
mov    -0x1e0(%rbp),%rsi
mov    -0x1e8(%rbp),%rdi
mov    -0x28(%rbp),%rax
movslq -0x2c(%rbp),%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
imul   %rdi,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x30(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x34(%rbp),%rcx
imul   %rsi,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x30(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm0
movslq -0x34(%rbp),%rax
cvtsi2sdl -0x1d0(%rbp,%rax,4),%xmm2
ff ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x28(%rbp),%rax
movslq -0x2c(%rbp),%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x34(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    11b4 <matrix_multiply_double+0xa4>
jmp    126d <matrix_multiply_double+0x15d>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    117b <matrix_multiply_double+0x6b>
jmp    1280 <matrix_multiply_double+0x170>
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1168 <matrix_multiply_double+0x58>
add    $0x1f0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<matrix_multiply_double>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x1c8,%rsp
mov    %r9,0x18(%rsp)
mov    %r8,%r13
mov    %rcx,0x8(%rsp)
mov    %edx,0x4(%rsp)
mov    %esi,%ebp
mov    %edi,%ebx
lea    0x30(%rsp),%rdi
mov    $0x190,%edx
xor    %esi,%esi
call   1030 <memset@plt>
test   %ebx,%ebx
jle    1286 <matrix_multiply_double+0x176>
mov    %ebp,%r8d
mov    0x4(%rsp),%ecx
mov    %ebx,%eax
mov    %rax,0x28(%rsp)
mov    %r8d,%esi
and    $0xfffffffe,%esi
mov    0x8(%rsp),%rax
lea    0x8(%rax),%rdi
lea    0x0(,%r8,8),%rax
mov    %rax,0x20(%rsp)
lea    0x8(%r13),%rax
mov    %rax,0x10(%rsp)
lea    0x0(,%rcx,8),%r10
xor    %r11d,%r11d
mov    0x8(%rsp),%rdx
jmp    11b4 <matrix_multiply_double+0xa4>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
add    $0x1,%r11
add    0x20(%rsp),%rdi
cmp    0x28(%rsp),%r11
je     1286 <matrix_multiply_double+0x176>
cmpl   $0x0,0x4(%rsp)
jle    11a0 <matrix_multiply_double+0x90>
mov    %r11,%rbx
imul   %rcx,%rbx
mov    0x18(%rsp),%rax
lea    (%rax,%rbx,8),%rbx
mov    %r11,%rax
imul   %r8,%rax
lea    (%rdx,%rax,8),%r14
mov    0x10(%rsp),%r9
xor    %r15d,%r15d
jmp    11ec <matrix_multiply_double+0xdc>
add    $0x1,%r15
add    %r10,%r9
cmp    %rcx,%r15
je     11a0 <matrix_multiply_double+0x90>
movq   $0x0,(%rbx,%r15,8)
test   %ebp,%ebp
jle    11e0 <matrix_multiply_double+0xd0>
xorps  %xmm0,%xmm0
cvtsi2sdl 0x30(%rsp,%r15,4),%xmm0
xorpd  %xmm1,%xmm1
xor    %r12d,%r12d
cmp    $0x1,%ebp
je     124f <matrix_multiply_double+0x13f>
xchg   %ax,%ax
movsd  -0x8(%rdi,%r12,8),%xmm2
mulsd  -0x8(%r9,%r12,8),%xmm2
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm2
movsd  %xmm2,(%rbx,%r15,8)
movsd  (%rdi,%r12,8),%xmm1
mulsd  (%r9,%r12,8),%xmm1
mulsd  %xmm0,%xmm1
addsd  %xmm2,%xmm1
movsd  %xmm1,(%rbx,%r15,8)
add    $0x2,%r12
cmp    %r12,%rsi
jne    1210 <matrix_multiply_double+0x100>
test   $0x1,%r8b
je     11e0 <matrix_multiply_double+0xd0>
mov    %r15,%rax
imul   %rcx,%rax
lea    0x0(,%rax,8),%rax
add    %r13,%rax
movsd  (%r14,%r12,8),%xmm2
mulsd  (%rax,%r12,8),%xmm2
mulsd  %xmm0,%xmm2
addsd  %xmm1,%xmm2
movsd  %xmm2,(%rbx,%r15,8)
jmp    11e0 <matrix_multiply_double+0xd0>
add    $0x1c8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @matrix_multiply_double(i32 %0, i32 %1, i32 %2, double* %3, double* %4, double* %5) {
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca double*
%11 = alloca double*
%12 = alloca double*
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca [100 x i32]
store i32 %0, i32* %7
store i32 %1, i32* %8
store i32 %2, i32* %9
store double* %3, double** %10
store double* %4, double** %11
store double* %5, double** %12
%17 = load i32, i32* %7
%18 = zext i32 %17 to i64
%19 = load i32, i32* %8
%20 = zext i32 %19 to i64
%21 = load i32, i32* %8
%22 = zext i32 %21 to i64
%23 = load i32, i32* %9
%24 = zext i32 %23 to i64
%25 = load i32, i32* %7
%26 = zext i32 %25 to i64
%27 = load i32, i32* %9
%28 = zext i32 %27 to i64
%29 = bitcast [100 x i32]* %16 to i8*
store i32 0, i32* %13
br label %30
30: ; preds = %103, %6
%31 = load i32, i32* %13
%32 = load i32, i32* %7
%33 = icmp slt i32 %31, %32
br i1 %33, label %34, label %106
34: ; preds = %30
store i32 0, i32* %15
br label %35
35: ; preds = %99, %34
%36 = load i32, i32* %15
%37 = load i32, i32* %9
%38 = icmp slt i32 %36, %37
br i1 %38, label %39, label %102
39: ; preds = %35
%40 = load double*, double** %12
%41 = load i32, i32* %13
%42 = sext i32 %41 to i64
%43 = mul nsw i64 %42, %28
%44 = getelementptr inbounds double, double* %40, i64 %43
%45 = load i32, i32* %15
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds double, double* %44, i64 %46
store double 0.000000e+00, double* %47
store i32 0, i32* %14
br label %48
48: ; preds = %95, %39
%49 = load i32, i32* %14
%50 = load i32, i32* %8
%51 = icmp slt i32 %49, %50
br i1 %51, label %52, label %98
52: ; preds = %48
%53 = load double*, double** %12
%54 = load i32, i32* %13
%55 = sext i32 %54 to i64
%56 = mul nsw i64 %55, %28
%57 = getelementptr inbounds double, double* %53, i64 %56
%58 = load i32, i32* %15
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds double, double* %57, i64 %59
%61 = load double, double* %60
%62 = load double*, double** %10
%63 = load i32, i32* %13
%64 = sext i32 %63 to i64
%65 = mul nsw i64 %64, %20
%66 = getelementptr inbounds double, double* %62, i64 %65
%67 = load i32, i32* %14
%68 = sext i32 %67 to i64
%69 = getelementptr inbounds double, double* %66, i64 %68
%70 = load double, double* %69
%71 = load double*, double** %11
%72 = load i32, i32* %15
%73 = sext i32 %72 to i64
%74 = mul nsw i64 %73, %24
%75 = getelementptr inbounds double, double* %71, i64 %74
%76 = load i32, i32* %14
%77 = sext i32 %76 to i64
%78 = getelementptr inbounds double, double* %75, i64 %77
%79 = load double, double* %78
%80 = fmul double %70, %79
%81 = load i32, i32* %15
%82 = sext i32 %81 to i64
%83 = getelementptr inbounds [100 x i32], [100 x i32]* %16, i64 0, i64 %82
%84 = load i32, i32* %83
%85 = sitofp i32 %84 to double
%86 = call double @llvm.fmuladd.f64(double %80, double %85, double %61)
%87 = load double*, double** %12
%88 = load i32, i32* %13
%89 = sext i32 %88 to i64
%90 = mul nsw i64 %89, %28
%91 = getelementptr inbounds double, double* %87, i64 %90
%92 = load i32, i32* %15
%93 = sext i32 %92 to i64
%94 = getelementptr inbounds double, double* %91, i64 %93
store double %86, double* %94
br label %95
95: ; preds = %52
%96 = load i32, i32* %14
%97 = add nsw i32 %96, 1
store i32 %97, i32* %14
br label %48
98: ; preds = %48
br label %99
99: ; preds = %98
%100 = load i32, i32* %15
%101 = add nsw i32 %100, 1
store i32 %101, i32* %15
br label %35
102: ; preds = %35
br label %103
103: ; preds = %102
%104 = load i32, i32* %13
%105 = add nsw i32 %104, 1
store i32 %105, i32* %13
br label %30
106: ; preds = %30
ret void
}

LLVM IR (-O2):
define void @matrix_multiply_double(i32 %0, i32 %1, i32 %2, double* nocapture %3, double* nocapture %4, double* nocapture %5) {
%7 = alloca [100 x i32]
%8 = zext i32 %1 to i64
%9 = zext i32 %2 to i64
%10 = bitcast [100 x i32]* %7 to i8*
%11 = icmp sgt i32 %0, 0
br i1 %11, label %12, label %72
12: ; preds = %6
%13 = icmp sgt i32 %2, 0
%14 = icmp sgt i32 %1, 0
%15 = zext i32 %0 to i64
%16 = and i64 %8, 1
%17 = icmp eq i32 %1, 1
%18 = and i64 %8, 4294967294
%19 = icmp eq i64 %16, 0
br label %20
20: ; preds = %12, %69
%21 = phi i64 [ 0, %12 ], [ %70, %69 ]
br i1 %13, label %22, label %69
22: ; preds = %20
%23 = mul nuw nsw i64 %21, %9
%24 = getelementptr inbounds double, double* %5, i64 %23
%25 = mul nuw nsw i64 %21, %8
%26 = getelementptr inbounds double, double* %3, i64 %25
br label %27
27: ; preds = %22, %66
%28 = phi i64 [ 0, %22 ], [ %67, %66 ]
%29 = getelementptr inbounds double, double* %24, i64 %28
store double 0.000000e+00, double* %29
br i1 %14, label %30, label %66
30: ; preds = %27
%31 = mul nuw nsw i64 %28, %9
%32 = getelementptr inbounds double, double* %4, i64 %31
%33 = getelementptr inbounds [100 x i32], [100 x i32]* %7, i64 0, i64 %28
%34 = load i32, i32* %33
%35 = sitofp i32 %34 to double
br i1 %17, label %56, label %36
36: ; preds = %30, %36
%37 = phi double [ %52, %36 ], [ 0.000000e+00, %30 ]
%38 = phi i64 [ %53, %36 ], [ 0, %30 ]
%39 = phi i64 [ %54, %36 ], [ 0, %30 ]
%40 = getelementptr inbounds double, double* %26, i64 %38
%41 = load double, double* %40
%42 = getelementptr inbounds double, double* %32, i64 %38
%43 = load double, double* %42
%44 = fmul double %41, %43
%45 = tail call double @llvm.fmuladd.f64(double %44, double %35, double %37)
store double %45, double* %29
%46 = or i64 %38, 1
%47 = getelementptr inbounds double, double* %26, i64 %46
%48 = load double, double* %47
%49 = getelementptr inbounds double, double* %32, i64 %46
%50 = load double, double* %49
%51 = fmul double %48, %50
%52 = tail call double @llvm.fmuladd.f64(double %51, double %35, double %45)
store double %52, double* %29
%53 = add nuw nsw i64 %38, 2
%54 = add i64 %39, 2
%55 = icmp eq i64 %54, %18
br i1 %55, label %56, label %36
56: ; preds = %36, %30
%57 = phi double [ 0.000000e+00, %30 ], [ %52, %36 ]
%58 = phi i64 [ 0, %30 ], [ %53, %36 ]
br i1 %19, label %66, label %59
59: ; preds = %56
%60 = getelementptr inbounds double, double* %26, i64 %58
%61 = load double, double* %60
%62 = getelementptr inbounds double, double* %32, i64 %58
%63 = load double, double* %62
%64 = fmul double %61, %63
%65 = tail call double @llvm.fmuladd.f64(double %64, double %35, double %57)
store double %65, double* %29
br label %66
66: ; preds = %59, %56, %27
%67 = add nuw nsw i64 %28, 1
%68 = icmp eq i64 %67, %9
br i1 %68, label %69, label %27
69: ; preds = %66, %20
%70 = add nuw nsw i64 %21, 1
%71 = icmp eq i64 %70, %15
br i1 %71, label %72, label %20
72: ; preds = %69, %6
ret void
}