void interleave_2(float *dest, float **src, int samples) {
  const float *src0 = src[0];
  const float *src1 = src[1];
  for (int i = 0; i < samples; i++) {
    dest[i * 2 + 0] = src0[i];
    dest[i * 2 + 1] = src1[i];
  }
}


x86 assembly (clang, -O0):
<interleave_2>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rax
mov    %rax,-0x28(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    118b <interleave_2+0x8b>
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x2c(%rbp),%ecx
shl    $0x1,%ecx
add    $0x0,%ecx
movslq %ecx,%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x28(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x2c(%rbp),%ecx
shl    $0x1,%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    112d <interleave_2+0x2d>
pop    %rbp
ret

x86 assembly (clang, -O2):
<interleave_2>:
test   %edx,%edx
jle    128d <interleave_2+0x18d>
mov    (%rsi),%r10
mov    0x8(%rsi),%rcx
mov    %edx,%r8d
cmp    $0x4,%edx
jae    118d <interleave_2+0x8d>
xor    %edx,%edx
mov    %rdx,%rax
not    %rax
test   $0x1,%r8b
je     113f <interleave_2+0x3f>
movss  (%r10,%rdx,4),%xmm0
movss  %xmm0,(%rdi,%rdx,8)
movss  (%rcx,%rdx,4),%xmm0
movss  %xmm0,0x4(%rdi,%rdx,8)
or     $0x1,%rdx
add    %r8,%rax
je     128d <interleave_2+0x18d>
nopl   0x0(%rax,%rax,1)
movss  (%r10,%rdx,4),%xmm0
movss  %xmm0,(%rdi,%rdx,8)
movss  (%rcx,%rdx,4),%xmm0
movss  %xmm0,0x4(%rdi,%rdx,8)
movss  0x4(%r10,%rdx,4),%xmm0
movss  %xmm0,0x8(%rdi,%rdx,8)
movss  0x4(%rcx,%rdx,4),%xmm0
movss  %xmm0,0xc(%rdi,%rdx,8)
add    $0x2,%rdx
cmp    %rdx,%r8
jne    1150 <interleave_2+0x50>
jmp    128d <interleave_2+0x18d>
lea    (%rdi,%r8,8),%rdx
lea    (%r10,%r8,4),%rax
lea    (%rcx,%r8,4),%rsi
cmp    %rdi,%rax
seta   %r9b
cmp    %rdx,%r10
setb   %r11b
cmp    %rdi,%rsi
seta   %al
cmp    %rdx,%rcx
setb   %sil
xor    %edx,%edx
test   %r11b,%r9b
jne    1119 <interleave_2+0x19>
and    %sil,%al
jne    1119 <interleave_2+0x19>
mov    %r8d,%edx
and    $0xfffffffc,%edx
lea    -0x4(%rdx),%rax
mov    %rax,%r9
shr    $0x2,%r9
add    $0x1,%r9
test   %rax,%rax
je     128e <interleave_2+0x18e>
mov    %r9,%rax
and    $0xfffffffffffffffe,%rax
xor    %esi,%esi
nop
movsd  (%r10,%rsi,4),%xmm0
movsd  0x8(%r10,%rsi,4),%xmm1
movsd  (%rcx,%rsi,4),%xmm2
unpcklps %xmm2,%xmm0
movsd  0x8(%rcx,%rsi,4),%xmm2
unpcklps %xmm2,%xmm1
movups %xmm0,(%rdi,%rsi,8)
movups %xmm1,0x10(%rdi,%rsi,8)
movsd  0x10(%r10,%rsi,4),%xmm0
movsd  0x18(%r10,%rsi,4),%xmm1
movsd  0x10(%rcx,%rsi,4),%xmm2
unpcklps %xmm2,%xmm0
movsd  0x18(%rcx,%rsi,4),%xmm2
unpcklps %xmm2,%xmm1
movups %xmm0,0x20(%rdi,%rsi,8)
movups %xmm1,0x30(%rdi,%rsi,8)
add    $0x8,%rsi
add    $0xfffffffffffffffe,%rax
jne    11f0 <interleave_2+0xf0>
test   $0x1,%r9b
je     1284 <interleave_2+0x184>
movsd  (%r10,%rsi,4),%xmm0
movsd  0x8(%r10,%rsi,4),%xmm1
movsd  (%rcx,%rsi,4),%xmm2
unpcklps %xmm2,%xmm0
movsd  0x8(%rcx,%rsi,4),%xmm2
unpcklps %xmm2,%xmm1
lea    0x0(,%rsi,8),%rax
or     $0x14,%rax
movups %xmm0,(%rdi,%rsi,8)
movups %xmm1,-0x4(%rdi,%rax,1)
cmp    %r8,%rdx
jne    1119 <interleave_2+0x19>
ret
xor    %esi,%esi
test   $0x1,%r9b
jne    1251 <interleave_2+0x151>
jmp    1284 <interleave_2+0x184>

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

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