void func1(int row, int col, double target[][col], double source[][col]) {
  int i, j;
  for (i = row; i > 0; i--) {
    for (j = col; j > 0; j--) {
      target[i - 1][j - 1] = source[i - 1][j - 1];
    }
  }
}


x86 assembly (clang, -O0):
<func1>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %rdx,-0x10(%rbp)
mov    %rcx,-0x18(%rbp)
mov    -0x8(%rbp),%eax
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%eax
mov    %rax,-0x28(%rbp)
mov    -0x4(%rbp),%eax
mov    %eax,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jle    11b5 <func1+0xb5>
mov    -0x8(%rbp),%eax
mov    %eax,-0x20(%rbp)
cmpl   $0x0,-0x20(%rbp)
jle    11a2 <func1+0xa2>
mov    -0x30(%rbp),%rdx
mov    -0x28(%rbp),%rsi
mov    -0x18(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
imul   %rsi,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    -0x20(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    -0x20(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x20(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x20(%rbp)
jmp    1136 <func1+0x36>
jmp    11a7 <func1+0xa7>
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
jmp    1126 <func1+0x26>
pop    %rbp
ret

x86 assembly (clang, -O2):
<func1>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
test   %edi,%edi
jle    130a <func1+0x20a>
mov    %rcx,%r12
mov    %esi,%ecx
mov    %esi,%esi
mov    $0xfffffffb,%ebp
mov    %edi,%r13d
lea    -0x1(%rsi),%r10
lea    -0x1(%rcx),%eax
lea    0x8(%rdx,%rax,8),%rbx
mov    %rbx,-0x30(%rsp)
lea    (%r12,%rax,8),%rbx
add    $0x8,%rbx
mov    %rbx,-0x38(%rsp)
mov    %esi,%ebx
and    $0xfffffffc,%ebx
mov    %rbx,-0x8(%rsp)
add    $0xfffffffffffffffc,%rbx
mov    %rbx,-0x10(%rsp)
shr    $0x2,%rbx
add    $0x1,%rbx
cmp    %r10d,%eax
setb   %r8b
mov    %r10,%rax
shr    $0x20,%rax
setne  %al
or     %r8b,%al
mov    %al,-0x39(%rsp)
mov    %esi,%eax
and    $0x3,%eax
mov    %rax,-0x20(%rsp)
mov    %rbx,%rax
mov    %rbx,-0x18(%rsp)
and    $0xfffffffffffffffe,%rbx
mov    %rbx,-0x28(%rsp)
lea    (%rsi,%rbp,1),%r15
xor    %r9d,%r9d
jmp    11b5 <func1+0xb5>
cs nopw 0x0(%rax,%rax,1)
lea    -0x1(%r13),%rax
add    $0x1,%r9d
cmp    $0x1,%r13
mov    %rax,%r13
jle    130a <func1+0x20a>
test   %ecx,%ecx
jle    11a0 <func1+0xa0>
cmp    $0x4,%ecx
setb   %bl
mov    $0xfffffffb,%eax
add    %r13d,%eax
add    $0x4,%eax
imul   %rsi,%rax
lea    (%r12,%rax,8),%r14
lea    (%rdx,%rax,8),%r8
or     -0x39(%rsp),%bl
mov    %rsi,%rbp
jne    12d0 <func1+0x1d0>
mov    %r9d,%ebp
not    %ebp
add    %edi,%ebp
lea    -0x8(,%rbp,8),%rbx
ff
imul   %rsi,%rbx
mov    -0x30(%rsp),%rax
lea    (%rax,%rbx,1),%r11
imul   %rsi,%rbp
mov    -0x38(%rsp),%rax
lea    (%rax,%rbp,8),%rax
cmp    %rax,%r11
jae    122b <func1+0x12b>
add    -0x38(%rsp),%rbx
mov    -0x30(%rsp),%rax
lea    (%rax,%rbp,8),%rax
mov    %rsi,%rbp
cmp    %rax,%rbx
jb     12d0 <func1+0x1d0>
mov    %r12,%rbx
cmpq   $0x0,-0x10(%rsp)
je     12fe <func1+0x1fe>
mov    -0x28(%rsp),%r11
xor    %r12d,%r12d
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
lea    (%r10,%r12,1),%eax
movups -0x18(%r14,%rax,8),%xmm0
movups -0x8(%r14,%rax,8),%xmm1
movups %xmm1,-0x8(%r8,%rax,8)
movups %xmm0,-0x18(%r8,%rax,8)
lea    (%r15,%r12,1),%eax
movups -0x18(%r14,%rax,8),%xmm0
movups -0x8(%r14,%rax,8),%xmm1
movups %xmm1,-0x8(%r8,%rax,8)
movups %xmm0,-0x18(%r8,%rax,8)
add    $0xfffffffffffffff8,%r12
add    $0xfffffffffffffffe,%r11
jne    1250 <func1+0x150>
neg    %r12
testb  $0x1,-0x18(%rsp)
je     12bb <func1+0x1bb>
not    %r12d
lea    (%rsi,%r12,1),%eax
movups -0x18(%r14,%rax,8),%xmm0
movups -0x8(%r14,%rax,8),%xmm1
movups %xmm1,-0x8(%r8,%rax,8)
movups %xmm0,-0x18(%r8,%rax,8)
mov    -0x20(%rsp),%rbp
cmp    %rsi,-0x8(%rsp)
mov    %rbx,%r12
je     11a0 <func1+0xa0>
xchg   %ax,%ax
add    $0x1,%rbp
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
lea    -0x2(%rbp),%eax
movsd  (%r14,%rax,8),%xmm0
movsd  %xmm0,(%r8,%rax,8)
add    $0xffffffffffffffff,%rbp
cmp    $0x1,%rbp
jg     12e0 <func1+0x1e0>
jmp    11a0 <func1+0xa0>
xor    %r12d,%r12d
testb  $0x1,-0x18(%rsp)
jne    129c <func1+0x19c>
jmp    12bb <func1+0x1bb>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

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