void copy_utf16(void *dst, const char *src, int len) {
  char *p = (char *)dst;
  while (len > 0) {
    *p++ = '\0';
    *p++ = *src++;
    len--;
  }
}


x86 assembly (clang, -O0):
<copy_utf16>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
cmpl   $0x0,-0x14(%rbp)
jle    1163 <copy_utf16+0x63>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x20(%rbp)
movb   $0x0,(%rax)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
mov    (%rax),%cl
mov    -0x20(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x20(%rbp)
mov    %cl,(%rax)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    1117 <copy_utf16+0x17>
pop    %rbp
ret

x86 assembly (clang, -O2):
<copy_utf16>:
test   %edx,%edx
jle    1218 <copy_utf16+0x118>
lea    -0x1(%rdx),%r10d
cmp    $0xf,%r10d
jb     11fa <copy_utf16+0xfa>
lea    (%r10,%rsi,1),%rax
add    $0x1,%rax
cmp    %rdi,%rax
jbe    1134 <copy_utf16+0x34>
lea    (%rdi,%r10,2),%rax
add    $0x2,%rax
cmp    %rsi,%rax
ja     11fa <copy_utf16+0xfa>
add    $0x1,%r10
mov    %r10,%r8
and    $0xfffffffffffffff0,%r8
lea    -0x10(%r8),%rax
mov    %rax,%r9
shr    $0x4,%r9
add    $0x1,%r9
test   %rax,%rax
je     1219 <copy_utf16+0x119>
mov    %r9,%rax
and    $0xfffffffffffffffe,%rax
xor    %ecx,%ecx
movq   (%rsi,%rcx,1),%xmm0
movq   0x8(%rsi,%rcx,1),%xmm1
pxor   %xmm2,%xmm2
punpcklbw %xmm0,%xmm2
movdqu %xmm2,(%rdi,%rcx,2)
pxor   %xmm0,%xmm0
punpcklbw %xmm1,%xmm0
movdqu %xmm0,0x10(%rdi,%rcx,2)
movq   0x10(%rsi,%rcx,1),%xmm0
movq   0x18(%rsi,%rcx,1),%xmm1
pxor   %xmm2,%xmm2
punpcklbw %xmm0,%xmm2
movdqu %xmm2,0x20(%rdi,%rcx,2)
pxor   %xmm0,%xmm0
punpcklbw %xmm1,%xmm0
movdqu %xmm0,0x30(%rdi,%rcx,2)
add    $0x20,%rcx
add    $0xfffffffffffffffe,%rax
jne    1160 <copy_utf16+0x60>
test   $0x1,%r9b
je     11eb <copy_utf16+0xeb>
lea    (%rcx,%rcx,1),%rax
or     $0x10,%rax
movq   (%rsi,%rcx,1),%xmm0
movq   0x8(%rsi,%rcx,1),%xmm1
pxor   %xmm2,%xmm2
pxor   %xmm3,%xmm3
punpcklbw %xmm0,%xmm3
movdqu %xmm3,(%rdi,%rcx,2)
punpcklbw %xmm1,%xmm2
movdqu %xmm2,(%rdi,%rax,1)
cmp    %r8,%r10
je     1218 <copy_utf16+0x118>
lea    (%rdi,%r8,2),%rdi
sub    %r8d,%edx
add    %r8,%rsi
add    $0x1,%edx
xor    %eax,%eax
nop
movb   $0x0,(%rdi,%rax,2)
movzbl (%rsi,%rax,1),%ecx
mov    %cl,0x1(%rdi,%rax,2)
add    $0x1,%rax
add    $0xffffffff,%edx
cmp    $0x1,%edx
ja     1200 <copy_utf16+0x100>
ret
xor    %ecx,%ecx
test   $0x1,%r9b
jne    11be <copy_utf16+0xbe>
jmp    11eb <copy_utf16+0xeb>

LLVM IR (-O0):
define void @copy_utf16(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i8*
store i8* %0, i8** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
%8 = load i8*, i8** %4
store i8* %8, i8** %7
br label %9
9: ; preds = %12, %3
%10 = load i32, i32* %6
%11 = icmp sgt i32 %10, 0
br i1 %11, label %12, label %22
12: ; preds = %9
%13 = load i8*, i8** %7
%14 = getelementptr inbounds i8, i8* %13, i32 1
store i8* %14, i8** %7
store i8 0, i8* %13
%15 = load i8*, i8** %5
%16 = getelementptr inbounds i8, i8* %15, i32 1
store i8* %16, i8** %5
%17 = load i8, i8* %15
%18 = load i8*, i8** %7
%19 = getelementptr inbounds i8, i8* %18, i32 1
store i8* %19, i8** %7
store i8 %17, i8* %18
%20 = load i32, i32* %6
%21 = add nsw i32 %20, -1
store i32 %21, i32* %6
br label %9
22: ; preds = %9
ret void
}

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