void unpack_values(int *msg, int n_items, int *weights, int *values) {
  for (int i = 0; i < n_items; i++) {
    weights[i] = msg[i];
    values[i] = msg[n_items + i];
  }
}


x86 assembly (clang, -O0):
<unpack_values>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    1165 <unpack_values+0x65>
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x8(%rbp),%rax
mov    -0xc(%rbp),%ecx
add    -0x24(%rbp),%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x20(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    111a <unpack_values+0x1a>
pop    %rbp
ret

x86 assembly (clang, -O2):
<unpack_values>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
test   %esi,%esi
jle    12d1 <unpack_values+0x1d1>
mov    %esi,%r9d
cmp    $0x8,%esi
jae    117a <unpack_values+0x7a>
xor    %esi,%esi
mov    %rsi,%rax
not    %rax
test   $0x1,%r9b
je     113c <unpack_values+0x3c>
mov    (%rdi,%rsi,4),%ebp
mov    %ebp,(%rdx,%rsi,4)
lea    (%rsi,%r9,1),%rbp
mov    (%rdi,%rbp,4),%ebp
mov    %ebp,(%rcx,%rsi,4)
or     $0x1,%rsi
add    %r9,%rax
je     12d1 <unpack_values+0x1d1>
lea    (%rdi,%r9,4),%rax
add    $0x4,%rax
nopl   (%rax)
mov    (%rdi,%rsi,4),%ebp
mov    %ebp,(%rdx,%rsi,4)
mov    -0x4(%rax,%rsi,4),%ebp
mov    %ebp,(%rcx,%rsi,4)
mov    0x4(%rdi,%rsi,4),%ebp
mov    %ebp,0x4(%rdx,%rsi,4)
mov    (%rax,%rsi,4),%ebp
mov    %ebp,0x4(%rcx,%rsi,4)
add    $0x2,%rsi
cmp    %rsi,%r9
jne    1150 <unpack_values+0x50>
jmp    12d1 <unpack_values+0x1d1>
lea    (%rdx,%r9,4),%rsi
lea    (%rcx,%r9,4),%rbp
lea    (%rdi,%r9,4),%rbx
cmp    %rdx,%rbp
seta   -0x1(%rsp)
lea    (%rdi,%r9,8),%rax
cmp    %rcx,%rsi
seta   %r12b
cmp    %rdx,%rax
seta   %r14b
cmp    %rdx,%rdi
setb   %r11b
cmp    %rdx,%rbx
seta   %r13b
cmp    %rdi,%rsi
seta   %r15b
cmp    %rcx,%rax
seta   %r8b
cmp    %rcx,%rdi
setb   %al
cmp    %rcx,%rbx
seta   %r10b
cmp    %rdi,%rbp
seta   %bl
xor    %esi,%esi
test   %r12b,-0x1(%rsp)
jne    111c <unpack_values+0x1c>
and    %r11b,%r14b
jne    111c <unpack_values+0x1c>
and    %r15b,%r13b
jne    111c <unpack_values+0x1c>
and    %al,%r8b
jne    111c <unpack_values+0x1c>
and    %bl,%r10b
jne    111c <unpack_values+0x1c>
mov    %r9d,%esi
and    $0xfffffff8,%esi
lea    -0x8(%rsi),%rax
mov    %rax,%r8
shr    $0x3,%r8
add    $0x1,%r8
test   %rax,%rax
je     12dc <unpack_values+0x1dc>
mov    %r8,%r10
and    $0xfffffffffffffffe,%r10
lea    0x30(%rdi),%r11
lea    (%rdi,%r9,4),%rbx
add    $0x30,%rbx
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movups -0x30(%r11,%rax,4),%xmm0
movups -0x20(%r11,%rax,4),%xmm1
movups %xmm0,(%rdx,%rax,4)
movups %xmm1,0x10(%rdx,%rax,4)
movups -0x30(%rbx,%rax,4),%xmm0
movups -0x20(%rbx,%rax,4),%xmm1
movups %xmm0,(%rcx,%rax,4)
movups %xmm1,0x10(%rcx,%rax,4)
movups -0x10(%r11,%rax,4),%xmm0
movups (%r11,%rax,4),%xmm1
movups %xmm0,0x20(%rdx,%rax,4)
movups %xmm1,0x30(%rdx,%rax,4)
movups -0x10(%rbx,%rax,4),%xmm0
movups (%rbx,%rax,4),%xmm1
movups %xmm0,0x20(%rcx,%rax,4)
movups %xmm1,0x30(%rcx,%rax,4)
add    $0x10,%rax
add    $0xfffffffffffffffe,%r10
jne    1240 <unpack_values+0x140>
test   $0x1,%r8b
je     12c8 <unpack_values+0x1c8>
movups (%rdi,%rax,4),%xmm0
movups 0x10(%rdi,%rax,4),%xmm1
movups %xmm0,(%rdx,%rax,4)
movups %xmm1,0x10(%rdx,%rax,4)
lea    (%rax,%r9,1),%rbp
movups (%rdi,%rbp,4),%xmm0
movups 0x10(%rdi,%rbp,4),%xmm1
movups %xmm0,(%rcx,%rax,4)
movups %xmm1,0x10(%rcx,%rax,4)
cmp    %r9,%rsi
jne    111c <unpack_values+0x1c>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
xor    %eax,%eax
test   $0x1,%r8b
jne    12a0 <unpack_values+0x1a0>
jmp    12c8 <unpack_values+0x1c8>

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

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