void Add2DFloatArrays(float **arr1, float **arr2, long nrow, long ncol) {
  long row, col;
  for (row = 0; row < nrow; row++) {
    for (col = 0; col < ncol; col++) {
      arr1[row][col] += arr2[row][col];
    }
  }
}


x86 assembly (clang, -O0):
<Add2DFloatArrays>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
movq   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x18(%rbp),%rax
jge    1196 <Add2DFloatArrays+0x96>
movq   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%rax
cmp    -0x20(%rbp),%rax
jge    1180 <Add2DFloatArrays+0x80>
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x30(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x30(%rbp),%rcx
addss  (%rax,%rcx,4),%xmm0
movss  %xmm0,(%rax,%rcx,4)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
jmp    1132 <Add2DFloatArrays+0x32>
jmp    1185 <Add2DFloatArrays+0x85>
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    111c <Add2DFloatArrays+0x1c>
pop    %rbp
ret

x86 assembly (clang, -O2):
<Add2DFloatArrays>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
test   %rdx,%rdx
jle    12ad <Add2DFloatArrays+0x1ad>
lea    -0x8(%rcx),%r8
mov    %r8,%r9
shr    $0x3,%r9
add    $0x1,%r9
mov    %rcx,%r11
and    $0xfffffffffffffff8,%r11
mov    %r9,%r10
and    $0xfffffffffffffffe,%r10
mov    %ecx,%r14d
and    $0x3,%r14d
xor    %r15d,%r15d
jmp    114d <Add2DFloatArrays+0x4d>
nopl   0x0(%rax)
add    $0x1,%r15
cmp    %rdx,%r15
je     12ad <Add2DFloatArrays+0x1ad>
test   %rcx,%rcx
jle    1140 <Add2DFloatArrays+0x40>
mov    (%rsi,%r15,8),%r12
mov    (%rdi,%r15,8),%rbx
cmp    $0x8,%rcx
jb     117a <Add2DFloatArrays+0x7a>
lea    (%r12,%rcx,4),%rax
cmp    %rax,%rbx
jae    1207 <Add2DFloatArrays+0x107>
lea    (%rbx,%rcx,4),%rax
cmp    %rax,%r12
jae    1207 <Add2DFloatArrays+0x107>
xor    %eax,%eax
mov    %rax,%r13
not    %r13
add    %rcx,%r13
test   %r14,%r14
je     11aa <Add2DFloatArrays+0xaa>
mov    %r14,%rbp
nopl   (%rax)
movss  (%r12,%rax,4),%xmm0
addss  (%rbx,%rax,4),%xmm0
movss  %xmm0,(%rbx,%rax,4)
add    $0x1,%rax
add    $0xffffffffffffffff,%rbp
jne    1190 <Add2DFloatArrays+0x90>
cmp    $0x3,%r13
jb     1140 <Add2DFloatArrays+0x40>
movss  (%r12,%rax,4),%xmm0
addss  (%rbx,%rax,4),%xmm0
movss  %xmm0,(%rbx,%rax,4)
movss  0x4(%r12,%rax,4),%xmm0
addss  0x4(%rbx,%rax,4),%xmm0
movss  %xmm0,0x4(%rbx,%rax,4)
movss  0x8(%r12,%rax,4),%xmm0
addss  0x8(%rbx,%rax,4),%xmm0
movss  %xmm0,0x8(%rbx,%rax,4)
movss  0xc(%r12,%rax,4),%xmm0
addss  0xc(%rbx,%rax,4),%xmm0
movss  %xmm0,0xc(%rbx,%rax,4)
add    $0x4,%rax
cmp    %rax,%rcx
jne    11b0 <Add2DFloatArrays+0xb0>
jmp    1140 <Add2DFloatArrays+0x40>
cmp    $0x8,%r8
jae    1211 <Add2DFloatArrays+0x111>
xor    %eax,%eax
jmp    1273 <Add2DFloatArrays+0x173>
mov    %r10,%r13
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
movups (%r12,%rax,4),%xmm0
movups 0x10(%r12,%rax,4),%xmm1
movups (%rbx,%rax,4),%xmm2
addps  %xmm0,%xmm2
movups 0x10(%rbx,%rax,4),%xmm0
addps  %xmm1,%xmm0
movups 0x20(%rbx,%rax,4),%xmm1
movups 0x30(%rbx,%rax,4),%xmm3
movups %xmm2,(%rbx,%rax,4)
movups %xmm0,0x10(%rbx,%rax,4)
movups 0x20(%r12,%rax,4),%xmm0
addps  %xmm1,%xmm0
movups 0x30(%r12,%rax,4),%xmm1
addps  %xmm3,%xmm1
movups %xmm0,0x20(%rbx,%rax,4)
movups %xmm1,0x30(%rbx,%rax,4)
add    $0x10,%rax
add    $0xfffffffffffffffe,%r13
jne    1220 <Add2DFloatArrays+0x120>
test   $0x1,%r9b
je     129c <Add2DFloatArrays+0x19c>
movups (%r12,%rax,4),%xmm0
movups 0x10(%r12,%rax,4),%xmm1
movups (%rbx,%rax,4),%xmm2
addps  %xmm0,%xmm2
movups 0x10(%rbx,%rax,4),%xmm0
addps  %xmm1,%xmm0
movups %xmm2,(%rbx,%rax,4)
movups %xmm0,0x10(%rbx,%rax,4)
mov    %r11,%rax
cmp    %rcx,%r11
je     1140 <Add2DFloatArrays+0x40>
jmp    117c <Add2DFloatArrays+0x7c>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

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