void fillBlock(double **a, int ax, int ay, double **b, int bm, int bn) {
  int i, j;
  for (i = 0; i < bm; i++) {
    for (j = 0; j < bn; j++) {
      a[i + ax][j + ay] = b[i][j];
    }
  }
}


x86 assembly (clang, -O0):
<fillBlock>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %rcx,-0x18(%rbp)
mov    %r8d,-0x1c(%rbp)
mov    %r9d,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1195 <fillBlock+0x95>
movl   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    1182 <fillBlock+0x82>
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x28(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    -0xc(%rbp),%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x28(%rbp),%ecx
add    -0x10(%rbp),%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    1134 <fillBlock+0x34>
jmp    1187 <fillBlock+0x87>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    1121 <fillBlock+0x21>
pop    %rbp
ret

x86 assembly (clang, -O2):
<fillBlock>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %rcx,-0x8(%rsp)
test   %r8d,%r8d
jle    1331 <fillBlock+0x231>
movslq %edx,%r12
movslq %esi,%rcx
mov    %r8d,%r13d
mov    %r9d,%edx
lea    (%r12,%rdx,1),%rax
mov    %rax,-0x18(%rsp)
mov    %edx,%eax
and    $0xfffffffc,%eax
mov    %rax,-0x20(%rsp)
add    $0xfffffffffffffffc,%rax
mov    %rax,-0x28(%rsp)
shr    $0x2,%rax
add    $0x1,%rax
mov    %eax,%ebp
and    $0x3,%ebp
and    $0xfffffffffffffffc,%rax
mov    %rax,-0x38(%rsp)
mov    %edx,%r10d
and    $0x3,%r10d
lea    0xe(%r12),%rax
mov    %rax,-0x40(%rsp)
mov    %rbp,-0x30(%rsp)
shl    $0x5,%rbp
lea    0x3(%r12),%rax
mov    %rax,-0x10(%rsp)
xor    %r14d,%r14d
jmp    118d <fillBlock+0x8d>
nop
add    $0x1,%r14
cmp    %r13,%r14
je     1331 <fillBlock+0x231>
test   %r9d,%r9d
jle    1180 <fillBlock+0x80>
lea    (%r14,%rcx,1),%rax
mov    -0x8(%rsp),%rsi
mov    (%rsi,%r14,8),%r8
mov    (%rdi,%rax,8),%r15
cmp    $0x4,%r9d
jb     11cc <fillBlock+0xcc>
lea    (%r15,%r12,8),%rax
lea    (%r8,%rdx,8),%rsi
cmp    %rsi,%rax
jae    1264 <fillBlock+0x164>
mov    -0x18(%rsp),%rax
lea    (%r15,%rax,8),%rax
cmp    %rax,%r8
jae    1264 <fillBlock+0x164>
xor    %r11d,%r11d
mov    %r11,%rax
not    %rax
add    %rdx,%rax
test   %r10,%r10
je     1206 <fillBlock+0x106>
lea    (%r15,%r12,8),%rsi
mov    %r10,%rbx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movsd  (%r8,%r11,8),%xmm0
movsd  %xmm0,(%rsi,%r11,8)
add    $0x1,%r11
add    $0xffffffffffffffff,%rbx
jne    11f0 <fillBlock+0xf0>
cmp    $0x3,%rax
jb     1180 <fillBlock+0x80>
mov    -0x10(%rsp),%rax
lea    (%r15,%rax,8),%rax
nopl   0x0(%rax)
movsd  (%r8,%r11,8),%xmm0
movsd  %xmm0,-0x18(%rax,%r11,8)
movsd  0x8(%r8,%r11,8),%xmm0
movsd  %xmm0,-0x10(%rax,%r11,8)
movsd  0x10(%r8,%r11,8),%xmm0
movsd  %xmm0,-0x8(%rax,%r11,8)
movsd  0x18(%r8,%r11,8),%xmm0
movsd  %xmm0,(%rax,%r11,8)
add    $0x4,%r11
cmp    %r11,%rdx
jne    1220 <fillBlock+0x120>
jmp    1180 <fillBlock+0x80>
cmpq   $0xc,-0x28(%rsp)
jae    1270 <fillBlock+0x170>
xor    %eax,%eax
jmp    12e0 <fillBlock+0x1e0>
mov    -0x40(%rsp),%rax
lea    (%r15,%rax,8),%rsi
mov    -0x38(%rsp),%rbx
xor    %eax,%eax
movups (%r8,%rax,8),%xmm0
movups 0x10(%r8,%rax,8),%xmm1
movups %xmm0,-0x70(%rsi,%rax,8)
movups %xmm1,-0x60(%rsi,%rax,8)
movups 0x20(%r8,%rax,8),%xmm0
movups 0x30(%r8,%rax,8),%xmm1
movups %xmm0,-0x50(%rsi,%rax,8)
movups %xmm1,-0x40(%rsi,%rax,8)
movups 0x40(%r8,%rax,8),%xmm0
movups 0x50(%r8,%rax,8),%xmm1
movups %xmm0,-0x30(%rsi,%rax,8)
movups %xmm1,-0x20(%rsi,%rax,8)
movups 0x60(%r8,%rax,8),%xmm0
movups 0x70(%r8,%rax,8),%xmm1
movups %xmm0,-0x10(%rsi,%rax,8)
movups %xmm1,(%rsi,%rax,8)
add    $0x10,%rax
add    $0xfffffffffffffffc,%rbx
jne    1280 <fillBlock+0x180>
cmpq   $0x0,-0x30(%rsp)
je     131b <fillBlock+0x21b>
lea    (%r12,%rax,1),%rsi
lea    (%r15,%rsi,8),%rsi
add    $0x10,%rsi
lea    (%r8,%rax,8),%rax
add    $0x10,%rax
xor    %ebx,%ebx
xchg   %ax,%ax
movups -0x10(%rax,%rbx,1),%xmm0
movups (%rax,%rbx,1),%xmm1
movups %xmm0,-0x10(%rsi,%rbx,1)
movups %xmm1,(%rsi,%rbx,1)
add    $0x20,%rbx
cmp    %rbx,%rbp
jne    1300 <fillBlock+0x200>
mov    -0x20(%rsp),%rax
mov    %rax,%r11
cmp    %rdx,%rax
je     1180 <fillBlock+0x80>
jmp    11cf <fillBlock+0xcf>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @fillBlock(double** %0, i32 %1, i32 %2, double** %3, i32 %4, i32 %5) {
%7 = alloca double**
%8 = alloca i32
%9 = alloca i32
%10 = alloca double**
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
store double** %0, double*** %7
store i32 %1, i32* %8
store i32 %2, i32* %9
store double** %3, double*** %10
store i32 %4, i32* %11
store i32 %5, i32* %12
store i32 0, i32* %13
br label %15
15: ; preds = %50, %6
%16 = load i32, i32* %13
%17 = load i32, i32* %11
%18 = icmp slt i32 %16, %17
br i1 %18, label %19, label %53
19: ; preds = %15
store i32 0, i32* %14
br label %20
20: ; preds = %46, %19
%21 = load i32, i32* %14
%22 = load i32, i32* %12
%23 = icmp slt i32 %21, %22
br i1 %23, label %24, label %49
24: ; preds = %20
%25 = load double**, double*** %10
%26 = load i32, i32* %13
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds double*, double** %25, i64 %27
%29 = load double*, double** %28
%30 = load i32, i32* %14
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds double, double* %29, i64 %31
%33 = load double, double* %32
%34 = load double**, double*** %7
%35 = load i32, i32* %13
%36 = load i32, i32* %8
%37 = add nsw i32 %35, %36
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds double*, double** %34, i64 %38
%40 = load double*, double** %39
%41 = load i32, i32* %14
%42 = load i32, i32* %9
%43 = add nsw i32 %41, %42
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds double, double* %40, i64 %44
store double %33, double* %45
br label %46
46: ; preds = %24
%47 = load i32, i32* %14
%48 = add nsw i32 %47, 1
store i32 %48, i32* %14
br label %20
49: ; preds = %20
br label %50
50: ; preds = %49
%51 = load i32, i32* %13
%52 = add nsw i32 %51, 1
store i32 %52, i32* %13
br label %15
53: ; preds = %15
ret void
}

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