void bar(unsigned char *q, unsigned short *data16s, int len) {
  int i;
  for (i = 0; i < len; i++) {
    q[2 * i] = (((data16s[i] & 0xFF) << 8) | ((data16s[i] >> 8) & 0xFF)) & 0xFF;
    q[2 * i + 1] = ((unsigned short)(((data16s[i] & 0xFF) << 8) |
                                     ((data16s[i] >> 8) & 0xFF))) >>
                   8;
  }
}


x86 assembly (clang, -O0):
<bar>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    11b8 <bar+0xb8>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
movzwl (%rax,%rcx,2),%eax
and    $0xff,%eax
shl    $0x8,%eax
mov    -0x10(%rbp),%rcx
movslq -0x18(%rbp),%rdx
movzwl (%rcx,%rdx,2),%ecx
sar    $0x8,%ecx
and    $0xff,%ecx
or     %ecx,%eax
and    $0xff,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
shl    $0x1,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
movzwl (%rax,%rcx,2),%eax
and    $0xff,%eax
shl    $0x8,%eax
mov    -0x10(%rbp),%rcx
movslq -0x18(%rbp),%rdx
movzwl (%rcx,%rdx,2),%ecx
sar    $0x8,%ecx
and    $0xff,%ecx
or     %ecx,%eax
movzwl %ax,%eax
sar    $0x8,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
shl    $0x1,%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1116 <bar+0x16>
pop    %rbp
ret

x86 assembly (clang, -O2):
<bar>:
test   %edx,%edx
jle    1238 <bar+0x138>
mov    %edx,%r9d
cmp    $0x8,%edx
jb     1122 <bar+0x22>
lea    (%rsi,%r9,2),%rax
cmp    %rdi,%rax
jbe    1180 <bar+0x80>
lea    (%rdi,%r9,2),%rax
cmp    %rsi,%rax
jbe    1180 <bar+0x80>
xor    %ecx,%ecx
mov    %rcx,%rax
not    %rax
test   $0x1,%r9b
je     1142 <bar+0x42>
mov    0x1(%rsi,%rcx,2),%dl
mov    %dl,(%rdi,%rcx,2)
mov    (%rsi,%rcx,2),%dl
mov    %dl,0x1(%rdi,%rcx,2)
or     $0x1,%rcx
add    %r9,%rax
je     1238 <bar+0x138>
nopl   0x0(%rax,%rax,1)
movzbl 0x1(%rsi,%rcx,2),%eax
mov    %al,(%rdi,%rcx,2)
movzbl (%rsi,%rcx,2),%eax
mov    %al,0x1(%rdi,%rcx,2)
movzbl 0x3(%rsi,%rcx,2),%eax
mov    %al,0x2(%rdi,%rcx,2)
movzbl 0x2(%rsi,%rcx,2),%eax
mov    %al,0x3(%rdi,%rcx,2)
add    $0x2,%rcx
cmp    %rcx,%r9
jne    1150 <bar+0x50>
jmp    1238 <bar+0x138>
mov    %r9d,%ecx
and    $0xfffffff8,%ecx
lea    -0x8(%rcx),%rax
mov    %rax,%r8
shr    $0x3,%r8
add    $0x1,%r8
test   %rax,%rax
je     1239 <bar+0x139>
mov    %r8,%rax
and    $0xfffffffffffffffe,%rax
xor    %edx,%edx
movdqa 0xe51(%rip),%xmm0
nop
movdqu (%rsi,%rdx,2),%xmm1
movdqa %xmm1,%xmm2
psrlw  $0x8,%xmm2
packuswb %xmm2,%xmm2
pand   %xmm0,%xmm1
packuswb %xmm1,%xmm1
punpcklbw %xmm1,%xmm2
movdqu %xmm2,(%rdi,%rdx,2)
movdqu 0x10(%rsi,%rdx,2),%xmm1
movdqa %xmm1,%xmm2
psrlw  $0x8,%xmm2
packuswb %xmm2,%xmm2
pand   %xmm0,%xmm1
packuswb %xmm1,%xmm1
punpcklbw %xmm1,%xmm2
movdqu %xmm2,0x10(%rdi,%rdx,2)
add    $0x10,%rdx
add    $0xfffffffffffffffe,%rax
jne    11b0 <bar+0xb0>
test   $0x1,%r8b
je     122f <bar+0x12f>
movdqu (%rsi,%rdx,2),%xmm0
movdqa %xmm0,%xmm1
psrlw  $0x8,%xmm1
pand   0xde2(%rip),%xmm0
packuswb %xmm1,%xmm1
packuswb %xmm0,%xmm0
punpcklbw %xmm0,%xmm1
movdqu %xmm1,(%rdi,%rdx,2)
cmp    %r9,%rcx
jne    1124 <bar+0x24>
ret
xor    %edx,%edx
test   $0x1,%r8b
jne    1208 <bar+0x108>
jmp    122f <bar+0x12f>

LLVM IR (-O0):
define void @bar(i8* %0, i16* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i16*
%6 = alloca i32
%7 = alloca i32
store i8* %0, i8** %4
store i16* %1, i16** %5
store i32 %2, i32* %6
store i32 0, i32* %7
br label %8
8: ; preds = %64, %3
%9 = load i32, i32* %7
%10 = load i32, i32* %6
%11 = icmp slt i32 %9, %10
br i1 %11, label %12, label %67
12: ; preds = %8
%13 = load i16*, i16** %5
%14 = load i32, i32* %7
%15 = sext i32 %14 to i64
%16 = getelementptr inbounds i16, i16* %13, i64 %15
%17 = load i16, i16* %16
%18 = zext i16 %17 to i32
%19 = and i32 %18, 255
%20 = shl i32 %19, 8
%21 = load i16*, i16** %5
%22 = load i32, i32* %7
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds i16, i16* %21, i64 %23
%25 = load i16, i16* %24
%26 = zext i16 %25 to i32
%27 = ashr i32 %26, 8
%28 = and i32 %27, 255
%29 = or i32 %20, %28
%30 = and i32 %29, 255
%31 = trunc i32 %30 to i8
%32 = load i8*, i8** %4
%33 = load i32, i32* %7
%34 = mul nsw i32 2, %33
%35 = sext i32 %34 to i64
%36 = getelementptr inbounds i8, i8* %32, i64 %35
store i8 %31, i8* %36
%37 = load i16*, i16** %5
%38 = load i32, i32* %7
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds i16, i16* %37, i64 %39
%41 = load i16, i16* %40
%42 = zext i16 %41 to i32
%43 = and i32 %42, 255
%44 = shl i32 %43, 8
%45 = load i16*, i16** %5
%46 = load i32, i32* %7
%47 = sext i32 %46 to i64
%48 = getelementptr inbounds i16, i16* %45, i64 %47
%49 = load i16, i16* %48
%50 = zext i16 %49 to i32
%51 = ashr i32 %50, 8
%52 = and i32 %51, 255
%53 = or i32 %44, %52
%54 = trunc i32 %53 to i16
%55 = zext i16 %54 to i32
%56 = ashr i32 %55, 8
%57 = trunc i32 %56 to i8
%58 = load i8*, i8** %4
%59 = load i32, i32* %7
%60 = mul nsw i32 2, %59
%61 = add nsw i32 %60, 1
%62 = sext i32 %61 to i64
%63 = getelementptr inbounds i8, i8* %58, i64 %62
store i8 %57, i8* %63
br label %64
64: ; preds = %12
%65 = load i32, i32* %7
%66 = add nsw i32 %65, 1
store i32 %66, i32* %7
br label %8
67: ; preds = %8
ret void
}

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