void produs(int n, int m, int p, double a[10][10], double b[10][10],
            double c[10][10]) {
  int i, j, k;
  double s;
  for (i = 0; i < n; i++)
    for (j = 0; j < p; j++) {
      s = 0.0;
      for (k = 0; k < m; k++)
        s = s + a[i][k] * b[k][j];
      c[i][j] = s;
    };
}


x86 assembly (clang, -O0):
<produs>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    %rcx,-0x18(%rbp)
mov    %r8,-0x20(%rbp)
mov    %r9,-0x28(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    11e8 <produs+0xe8>
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    11d5 <produs+0xd5>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    11aa <produs+0xaa>
movsd  -0x40(%rbp),%xmm1
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
imul   $0x50,%rcx,%rcx
add    %rcx,%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x34(%rbp),%rcx
imul   $0x50,%rcx,%rcx
add    %rcx,%rax
movslq -0x30(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    114e <produs+0x4e>
movsd  -0x40(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x2c(%rbp),%rcx
imul   $0x50,%rcx,%rcx
add    %rcx,%rax
movslq -0x30(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    1133 <produs+0x33>
jmp    11da <produs+0xda>
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1120 <produs+0x20>
pop    %rbp
ret

x86 assembly (clang, -O2):
<produs>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
test   %edi,%edi
jle    1205 <produs+0x105>
mov    %edi,%r10d
mov    %edx,%r14d
mov    %esi,%r11d
mov    %r11d,%r13d
and    $0xfffffffe,%r13d
lea    0x8(%rcx),%rbx
xor    %r15d,%r15d
jmp    1141 <produs+0x41>
nopl   0x0(%rax,%rax,1)
add    $0x1,%r15
add    $0x50,%rbx
cmp    %r10,%r15
je     1205 <produs+0x105>
test   %edx,%edx
jle    1130 <produs+0x30>
mov    %r8,%r12
xor    %edi,%edi
jmp    1171 <produs+0x71>
nopl   0x0(%rax)
xorpd  %xmm0,%xmm0
lea    (%r15,%r15,4),%rax
shl    $0x4,%rax
add    %r9,%rax
movsd  %xmm0,(%rax,%rdi,8)
add    $0x1,%rdi
add    $0x8,%r12
cmp    %r14,%rdi
je     1130 <produs+0x30>
test   %esi,%esi
jle    1150 <produs+0x50>
cmp    $0x1,%esi
jne    1190 <produs+0x90>
xorpd  %xmm0,%xmm0
xor    %eax,%eax
jmp    11d1 <produs+0xd1>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
xorpd  %xmm1,%xmm1
mov    %r12,%rbp
xor    %eax,%eax
nopl   0x0(%rax)
movsd  -0x8(%rbx,%rax,8),%xmm2
mulsd  0x0(%rbp),%xmm2
movsd  (%rbx,%rax,8),%xmm0
addsd  %xmm1,%xmm2
mulsd  0x50(%rbp),%xmm0
addsd  %xmm2,%xmm0
add    $0x2,%rax
add    $0xa0,%rbp
movapd %xmm0,%xmm1
cmp    %rax,%r13
jne    11a0 <produs+0xa0>
test   $0x1,%r11b
je     1154 <produs+0x54>
lea    (%r15,%r15,4),%rbp
shl    $0x4,%rbp
add    %rcx,%rbp
movsd  0x0(%rbp,%rax,8),%xmm1
lea    (%rax,%rax,4),%rax
shl    $0x4,%rax
add    %r8,%rax
mulsd  (%rax,%rdi,8),%xmm1
addsd  %xmm1,%xmm0
jmp    1154 <produs+0x54>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

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