void copy_matrix(double **a, long nr, long nc, double **o) {
  long i, j;
  for (i = 1; i <= nr; i++)
    for (j = 1; j <= nc; j++)
      o[i][j] = a[i][j];
}


x86 assembly (clang, -O0):
<copy_matrix>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
movq   $0x1,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x10(%rbp),%rax
jg     1191 <copy_matrix+0x91>
movq   $0x1,-0x30(%rbp)
mov    -0x30(%rbp),%rax
cmp    -0x18(%rbp),%rax
jg     117b <copy_matrix+0x7b>
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x30(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x30(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
jmp    1132 <copy_matrix+0x32>
jmp    1180 <copy_matrix+0x80>
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    111c <copy_matrix+0x1c>
pop    %rbp
ret

x86 assembly (clang, -O2):
<copy_matrix>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
test   %rsi,%rsi
jle    132c <copy_matrix+0x22c>
lea    0x1(%rdx),%r11
lea    -0x4(%rdx),%r9
mov    %r9,-0x8(%rsp)
shr    $0x2,%r9
add    $0x1,%r9
mov    %rdx,%r10
and    $0xfffffffffffffffc,%r10
lea    0x1(%r10),%rax
mov    %rax,-0x10(%rsp)
mov    %r9d,%r14d
and    $0x3,%r14d
and    $0xfffffffffffffffc,%r9
mov    $0x1,%r12d
jmp    1161 <copy_matrix+0x61>
nopl   0x0(%rax,%rax,1)
lea    0x1(%r12),%rax
cmp    %rsi,%r12
mov    %rax,%r12
je     132c <copy_matrix+0x22c>
test   %rdx,%rdx
jle    1150 <copy_matrix+0x50>
mov    (%rdi,%r12,8),%r13
mov    (%rcx,%r12,8),%r8
mov    $0x1,%eax
cmp    $0x4,%rdx
jb     1280 <copy_matrix+0x180>
lea    0x8(%r8),%r15
lea    0x0(,%r11,8),%rbp
add    %r13,%rbp
cmp    %rbp,%r15
jae    11a2 <copy_matrix+0xa2>
lea    (%r8,%r11,8),%r15
lea    0x8(%r13),%rbp
cmp    %r15,%rbp
jb     1280 <copy_matrix+0x180>
cmpq   $0xc,-0x8(%rsp)
jae    11ae <copy_matrix+0xae>
xor    %eax,%eax
jmp    122a <copy_matrix+0x12a>
mov    %r9,%rbp
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movups 0x8(%r13,%rax,8),%xmm0
movups 0x18(%r13,%rax,8),%xmm1
movups %xmm0,0x8(%r8,%rax,8)
movups %xmm1,0x18(%r8,%rax,8)
movups 0x28(%r13,%rax,8),%xmm0
movups 0x38(%r13,%rax,8),%xmm1
movups %xmm0,0x28(%r8,%rax,8)
movups %xmm1,0x38(%r8,%rax,8)
movups 0x48(%r13,%rax,8),%xmm0
movups 0x58(%r13,%rax,8),%xmm1
movups %xmm0,0x48(%r8,%rax,8)
movups %xmm1,0x58(%r8,%rax,8)
movups 0x68(%r13,%rax,8),%xmm0
movups 0x78(%r13,%rax,8),%xmm1
movups %xmm0,0x68(%r8,%rax,8)
movups %xmm1,0x78(%r8,%rax,8)
add    $0x10,%rax
add    $0xfffffffffffffffc,%rbp
jne    11c0 <copy_matrix+0xc0>
test   %r14,%r14
je     126d <copy_matrix+0x16d>
mov    %r14,%rbp
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
lea    0x0(,%rax,8),%rbx
or     $0x8,%rbx
movups 0x0(%r13,%rbx,1),%xmm0
movups 0x10(%r13,%rbx,1),%xmm1
movups %xmm0,(%r8,%rbx,1)
movups %xmm1,0x10(%r8,%rbx,1)
add    $0x4,%rax
add    $0xffffffffffffffff,%rbp
jne    1240 <copy_matrix+0x140>
mov    -0x10(%rsp),%rax
cmp    %rdx,%r10
je     1150 <copy_matrix+0x50>
nopl   0x0(%rax,%rax,1)
mov    %r11d,%r15d
sub    %eax,%r15d
mov    %rdx,%rbp
sub    %rax,%rbp
and    $0x3,%r15
je     12b7 <copy_matrix+0x1b7>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movsd  0x0(%r13,%rax,8),%xmm0
movsd  %xmm0,(%r8,%rax,8)
add    $0x1,%rax
add    $0xffffffffffffffff,%r15
jne    12a0 <copy_matrix+0x1a0>
cmp    $0x3,%rbp
jb     1150 <copy_matrix+0x50>
mov    %rdx,%r15
sub    %rax,%r15
lea    (%r8,%rax,8),%rbx
add    $0x18,%rbx
lea    0x18(,%rax,8),%rax
add    %r13,%rax
mov    $0xffffffffffffffff,%rbp
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movsd  -0x10(%rax,%rbp,8),%xmm0
movsd  %xmm0,-0x10(%rbx,%rbp,8)
movsd  -0x8(%rax,%rbp,8),%xmm0
movsd  %xmm0,-0x8(%rbx,%rbp,8)
movsd  (%rax,%rbp,8),%xmm0
movsd  %xmm0,(%rbx,%rbp,8)
movsd  0x8(%rax,%rbp,8),%xmm0
movsd  %xmm0,0x8(%rbx,%rbp,8)
add    $0x4,%rbp
cmp    %rbp,%r15
jne    12f0 <copy_matrix+0x1f0>
jmp    1150 <copy_matrix+0x50>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @copy_matrix(double** %0, i64 %1, i64 %2, double** %3) {
%5 = alloca double**
%6 = alloca i64
%7 = alloca i64
%8 = alloca double**
%9 = alloca i64
%10 = alloca i64
store double** %0, double*** %5
store i64 %1, i64* %6
store i64 %2, i64* %7
store double** %3, double*** %8
store i64 1, i64* %9
br label %11
11: ; preds = %38, %4
%12 = load i64, i64* %9
%13 = load i64, i64* %6
%14 = icmp sle i64 %12, %13
br i1 %14, label %15, label %41
15: ; preds = %11
store i64 1, i64* %10
br label %16
16: ; preds = %34, %15
%17 = load i64, i64* %10
%18 = load i64, i64* %7
%19 = icmp sle i64 %17, %18
br i1 %19, label %20, label %37
20: ; preds = %16
%21 = load double**, double*** %5
%22 = load i64, i64* %9
%23 = getelementptr inbounds double*, double** %21, i64 %22
%24 = load double*, double** %23
%25 = load i64, i64* %10
%26 = getelementptr inbounds double, double* %24, i64 %25
%27 = load double, double* %26
%28 = load double**, double*** %8
%29 = load i64, i64* %9
%30 = getelementptr inbounds double*, double** %28, i64 %29
%31 = load double*, double** %30
%32 = load i64, i64* %10
%33 = getelementptr inbounds double, double* %31, i64 %32
store double %27, double* %33
br label %34
34: ; preds = %20
%35 = load i64, i64* %10
%36 = add nsw i64 %35, 1
store i64 %36, i64* %10
br label %16
37: ; preds = %16
br label %38
38: ; preds = %37
%39 = load i64, i64* %9
%40 = add nsw i64 %39, 1
store i64 %40, i64* %9
br label %11
41: ; preds = %11
ret void
}

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