void CopyColumn(long n1, double *src, double *dest) {
  long i;
  for (i = 0; i < n1; i++) {
    dest[2 * i] = src[2 * i];
    dest[2 * i + 1] = src[2 * i + 1];
  }
}


x86 assembly (clang, -O0):
<CopyColumn>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x8(%rbp),%rax
jge    117d <CopyColumn+0x7d>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
shl    $0x1,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x20(%rbp),%rcx
shl    $0x1,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
shl    $0x1,%rcx
movsd  0x8(%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x20(%rbp),%rcx
shl    $0x1,%rcx
movsd  %xmm0,0x8(%rax,%rcx,8)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    1118 <CopyColumn+0x18>
pop    %rbp
ret

x86 assembly (clang, -O2):
<CopyColumn>:
test   %rdi,%rdi
jle    1298 <CopyColumn+0x198>
cmp    $0x1,%rdi
je     112f <CopyColumn+0x2f>
mov    %rdi,%rax
shl    $0x4,%rax
lea    (%rsi,%rax,1),%rcx
cmp    %rdx,%rcx
jbe    11bd <CopyColumn+0xbd>
add    %rdx,%rax
cmp    %rsi,%rax
jbe    11bd <CopyColumn+0xbd>
xor    %eax,%eax
mov    %rax,%r8
not    %r8
test   $0x1,%dil
je     115e <CopyColumn+0x5e>
mov    %rax,%rcx
shl    $0x4,%rcx
movsd  (%rsi,%rcx,1),%xmm0
movsd  %xmm0,(%rdx,%rcx,1)
movsd  0x8(%rsi,%rcx,1),%xmm0
movsd  %xmm0,0x8(%rdx,%rcx,1)
or     $0x1,%rax
add    %rdi,%r8
je     1298 <CopyColumn+0x198>
sub    %rax,%rdi
shl    $0x4,%rax
add    $0x18,%rax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movsd  -0x18(%rsi,%rax,1),%xmm0
movsd  %xmm0,-0x18(%rdx,%rax,1)
movsd  -0x10(%rsi,%rax,1),%xmm0
movsd  %xmm0,-0x10(%rdx,%rax,1)
movsd  -0x8(%rsi,%rax,1),%xmm0
movsd  %xmm0,-0x8(%rdx,%rax,1)
movsd  (%rsi,%rax,1),%xmm0
movsd  %xmm0,(%rdx,%rax,1)
add    $0x20,%rax
add    $0xfffffffffffffffe,%rdi
jne    1180 <CopyColumn+0x80>
jmp    1298 <CopyColumn+0x198>
mov    %rdi,%rax
and    $0xfffffffffffffffe,%rax
lea    -0x2(%rax),%rcx
mov    %rcx,%r9
shr    %r9
add    $0x1,%r9
mov    %r9d,%r8d
and    $0x3,%r8d
cmp    $0x6,%rcx
jae    11e4 <CopyColumn+0xe4>
xor    %r10d,%r10d
jmp    124c <CopyColumn+0x14c>
and    $0xfffffffffffffffc,%r9
mov    $0x30,%ecx
xor    %r10d,%r10d
movups -0x60(%rsi,%rcx,2),%xmm0
movups -0x50(%rsi,%rcx,2),%xmm1
movups %xmm1,-0x50(%rdx,%rcx,2)
movups %xmm0,-0x60(%rdx,%rcx,2)
movups -0x40(%rsi,%rcx,2),%xmm0
movups -0x30(%rsi,%rcx,2),%xmm1
movups %xmm1,-0x30(%rdx,%rcx,2)
movups %xmm0,-0x40(%rdx,%rcx,2)
movups -0x20(%rsi,%rcx,2),%xmm0
movups -0x10(%rsi,%rcx,2),%xmm1
movups %xmm1,-0x10(%rdx,%rcx,2)
movups %xmm0,-0x20(%rdx,%rcx,2)
movups (%rsi,%rcx,2),%xmm0
movups 0x10(%rsi,%rcx,2),%xmm1
movups %xmm1,0x10(%rdx,%rcx,2)
movups %xmm0,(%rdx,%rcx,2)
add    $0x8,%r10
add    $0x40,%rcx
add    $0xfffffffffffffffc,%r9
jne    11f0 <CopyColumn+0xf0>
test   %r8,%r8
je     128f <CopyColumn+0x18f>
shl    $0x4,%r10
lea    (%rdx,%r10,1),%r9
add    %rsi,%r10
shl    $0x5,%r8
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movups (%r10,%rcx,1),%xmm0
movups 0x10(%r10,%rcx,1),%xmm1
movups %xmm1,0x10(%r9,%rcx,1)
movups %xmm0,(%r9,%rcx,1)
add    $0x20,%rcx
cmp    %rcx,%r8
jne    1270 <CopyColumn+0x170>
cmp    %rdi,%rax
jne    1131 <CopyColumn+0x31>
ret

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

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