void dmat_copy_2x2(double **b11, double **b12, double **b21, double **b22,
                   double **a11, double **a12, double **a21, double **a22,
                   int n) {
  int i;
  int j;
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n; ++j) {
      b11[i][j] = a11[i][j];
      b12[i][j] = a12[i][j];
      b21[i][j] = a21[i][j];
      b22[i][j] = a22[i][j];
    }
  }
}


x86 assembly (clang, -O0):
<dmat_copy_2x2>:
push   %rbp
mov    %rsp,%rbp
mov    0x20(%rbp),%eax
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%rax
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    0x20(%rbp),%eax
jge    1216 <dmat_copy_2x2+0x116>
movl   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%eax
cmp    0x20(%rbp),%eax
jge    1203 <dmat_copy_2x2+0x103>
mov    -0x28(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x38(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x30(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x38(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    0x10(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x38(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    0x18(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x38(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    1141 <dmat_copy_2x2+0x41>
jmp    1208 <dmat_copy_2x2+0x108>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    112e <dmat_copy_2x2+0x2e>
pop    %rbp
ret

x86 assembly (clang, -O2):
<dmat_copy_2x2>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %r9,-0x8(%rsp)
mov    %r8,-0x10(%rsp)
mov    %rcx,-0x18(%rsp)
mov    %rdx,-0x20(%rsp)
cmpl   $0x0,0x48(%rsp)
jle    1251 <dmat_copy_2x2+0x151>
mov    0x48(%rsp),%edx
mov    %edx,%r13d
and    $0xfffffffe,%r13d
xor    %r12d,%r12d
jmp    114d <dmat_copy_2x2+0x4d>
nopl   0x0(%rax)
add    $0x1,%r12
cmp    %rdx,%r12
je     1251 <dmat_copy_2x2+0x151>
mov    -0x10(%rsp),%rax
mov    (%rax,%r12,8),%rax
mov    (%rdi,%r12,8),%rbp
mov    -0x8(%rsp),%rbx
mov    (%rbx,%r12,8),%rbx
mov    (%rsi,%r12,8),%r10
mov    0x38(%rsp),%rcx
mov    (%rcx,%r12,8),%r11
mov    -0x20(%rsp),%rcx
mov    (%rcx,%r12,8),%r14
mov    0x40(%rsp),%rcx
mov    (%rcx,%r12,8),%r15
mov    -0x18(%rsp),%rcx
mov    (%rcx,%r12,8),%r9
xor    %r8d,%r8d
cmpl   $0x1,0x48(%rsp)
je     1212 <dmat_copy_2x2+0x112>
nopl   0x0(%rax)
movsd  (%rax,%r8,8),%xmm0
movsd  %xmm0,0x0(%rbp,%r8,8)
movsd  (%rbx,%r8,8),%xmm0
movsd  %xmm0,(%r10,%r8,8)
movsd  (%r11,%r8,8),%xmm0
movsd  %xmm0,(%r14,%r8,8)
movsd  (%r15,%r8,8),%xmm0
movsd  %xmm0,(%r9,%r8,8)
movsd  0x8(%rax,%r8,8),%xmm0
movsd  %xmm0,0x8(%rbp,%r8,8)
movsd  0x8(%rbx,%r8,8),%xmm0
movsd  %xmm0,0x8(%r10,%r8,8)
movsd  0x8(%r11,%r8,8),%xmm0
movsd  %xmm0,0x8(%r14,%r8,8)
movsd  0x8(%r15,%r8,8),%xmm0
movsd  %xmm0,0x8(%r9,%r8,8)
add    $0x2,%r8
cmp    %r8,%r13
jne    11a0 <dmat_copy_2x2+0xa0>
test   $0x1,%dl
je     1140 <dmat_copy_2x2+0x40>
movsd  (%rax,%r8,8),%xmm0
movsd  %xmm0,0x0(%rbp,%r8,8)
movsd  (%rbx,%r8,8),%xmm0
movsd  %xmm0,(%r10,%r8,8)
movsd  (%r11,%r8,8),%xmm0
movsd  %xmm0,(%r14,%r8,8)
movsd  (%r15,%r8,8),%xmm0
movsd  %xmm0,(%r9,%r8,8)
jmp    1140 <dmat_copy_2x2+0x40>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define void @dmat_copy_2x2(double** nocapture %0, double** nocapture %1, double** nocapture %2, double** nocapture %3, double** nocapture %4, double** nocapture %5, double** nocapture %6, double** nocapture %7, i32 %8) {
%10 = icmp sgt i32 %8, 0
br i1 %10, label %11, label %84
11: ; preds = %9
%12 = zext i32 %8 to i64
%13 = and i64 %12, 1
%14 = icmp eq i32 %8, 1
%15 = and i64 %12, 4294967294
%16 = icmp eq i64 %13, 0
br label %17
17: ; preds = %81, %11
%18 = phi i64 [ 0, %11 ], [ %82, %81 ]
%19 = getelementptr inbounds double*, double** %4, i64 %18
%20 = load double*, double** %19
%21 = getelementptr inbounds double*, double** %0, i64 %18
%22 = load double*, double** %21
%23 = getelementptr inbounds double*, double** %5, i64 %18
%24 = load double*, double** %23
%25 = getelementptr inbounds double*, double** %1, i64 %18
%26 = load double*, double** %25
%27 = getelementptr inbounds double*, double** %6, i64 %18
%28 = load double*, double** %27
%29 = getelementptr inbounds double*, double** %2, i64 %18
%30 = load double*, double** %29
%31 = getelementptr inbounds double*, double** %7, i64 %18
%32 = load double*, double** %31
%33 = getelementptr inbounds double*, double** %3, i64 %18
%34 = load double*, double** %33
br i1 %14, label %66, label %35
35: ; preds = %17, %35
%36 = phi i64 [ %63, %35 ], [ 0, %17 ]
%37 = phi i64 [ %64, %35 ], [ 0, %17 ]
%38 = getelementptr inbounds double, double* %20, i64 %36
%39 = load double, double* %38
%40 = getelementptr inbounds double, double* %22, i64 %36
store double %39, double* %40
%41 = getelementptr inbounds double, double* %24, i64 %36
%42 = load double, double* %41
%43 = getelementptr inbounds double, double* %26, i64 %36
store double %42, double* %43
%44 = getelementptr inbounds double, double* %28, i64 %36
%45 = load double, double* %44
%46 = getelementptr inbounds double, double* %30, i64 %36
store double %45, double* %46
%47 = getelementptr inbounds double, double* %32, i64 %36
%48 = load double, double* %47
%49 = getelementptr inbounds double, double* %34, i64 %36
store double %48, double* %49
%50 = or i64 %36, 1
%51 = getelementptr inbounds double, double* %20, i64 %50
%52 = load double, double* %51
%53 = getelementptr inbounds double, double* %22, i64 %50
store double %52, double* %53
%54 = getelementptr inbounds double, double* %24, i64 %50
%55 = load double, double* %54
%56 = getelementptr inbounds double, double* %26, i64 %50
store double %55, double* %56
%57 = getelementptr inbounds double, double* %28, i64 %50
%58 = load double, double* %57
%59 = getelementptr inbounds double, double* %30, i64 %50
store double %58, double* %59
%60 = getelementptr inbounds double, double* %32, i64 %50
%61 = load double, double* %60
%62 = getelementptr inbounds double, double* %34, i64 %50
store double %61, double* %62
%63 = add nuw nsw i64 %36, 2
%64 = add i64 %37, 2
%65 = icmp eq i64 %64, %15
br i1 %65, label %66, label %35
66: ; preds = %35, %17
%67 = phi i64 [ 0, %17 ], [ %63, %35 ]
br i1 %16, label %81, label %68
68: ; preds = %66
%69 = getelementptr inbounds double, double* %20, i64 %67
%70 = load double, double* %69
%71 = getelementptr inbounds double, double* %22, i64 %67
store double %70, double* %71
%72 = getelementptr inbounds double, double* %24, i64 %67
%73 = load double, double* %72
%74 = getelementptr inbounds double, double* %26, i64 %67
store double %73, double* %74
%75 = getelementptr inbounds double, double* %28, i64 %67
%76 = load double, double* %75
%77 = getelementptr inbounds double, double* %30, i64 %67
store double %76, double* %77
%78 = getelementptr inbounds double, double* %32, i64 %67
%79 = load double, double* %78
%80 = getelementptr inbounds double, double* %34, i64 %67
store double %79, double* %80
br label %81
81: ; preds = %66, %68
%82 = add nuw nsw i64 %18, 1
%83 = icmp eq i64 %82, %12
br i1 %83, label %84, label %17
84: ; preds = %81, %9
ret void
}