#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int /*<<< orphan*/ z;

/* Variables and functions */
int /*<<< orphan*/ asm_copy_opt(short *, short *, int);
int /*<<< orphan*/ asm_copy_optimized_k(short *, short *, int);
int /*<<< orphan*/ memset(short *, int /*<<< orphan*/, int);
void Copy() {
  int i;
  short x[64] = {0};
  for (i = 0; i < 64; i++) {
    x[i] = i;
  }
  short y[64] = {0};
  for (i = 0; i < 64; i++) {
    y[i] = x[i];
  }
  short z[64] = {0};
  asm_copy_opt(x, z, 64);
  memset(z, 0, sizeof(z));
  memset(z, 0, sizeof(z));
  asm_copy_optimized_k(x, z, 64);
}


x86 assembly (clang, -O0):
<Copy>:
push   %rbp
mov    %rsp,%rbp
sub    $0x190,%rsp
lea    -0x90(%rbp),%rdi
xor    %esi,%esi
mov    $0x80,%edx
call   1040 <memset@plt>
movl   $0x0,-0x4(%rbp)
cmpl   $0x40,-0x4(%rbp)
jge    117f <Copy+0x4f>
mov    -0x4(%rbp),%eax
mov    %ax,%cx
movslq -0x4(%rbp),%rax
mov    %cx,-0x90(%rbp,%rax,2)
ff
mov    -0x4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4(%rbp)
jmp    1155 <Copy+0x25>
lea    -0x110(%rbp),%rdi
xor    %esi,%esi
mov    $0x80,%edx
call   1040 <memset@plt>
movl   $0x0,-0x4(%rbp)
cmpl   $0x40,-0x4(%rbp)
jge    11c9 <Copy+0x99>
movslq -0x4(%rbp),%rax
mov    -0x90(%rbp,%rax,2),%cx
ff
movslq -0x4(%rbp),%rax
mov    %cx,-0x110(%rbp,%rax,2)
ff
mov    -0x4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4(%rbp)
jmp    1199 <Copy+0x69>
lea    -0x190(%rbp),%rdi
xor    %esi,%esi
mov    $0x80,%edx
call   1040 <memset@plt>
lea    -0x90(%rbp),%rdi
lea    -0x190(%rbp),%rsi
mov    $0x40,%edx
call   1050 <asm_copy_opt@plt>
lea    -0x190(%rbp),%rdi
xor    %esi,%esi
mov    $0x80,%edx
call   1040 <memset@plt>
lea    -0x190(%rbp),%rdi
xor    %esi,%esi
mov    $0x80,%edx
call   1040 <memset@plt>
lea    -0x90(%rbp),%rdi
lea    -0x190(%rbp),%rsi
mov    $0x40,%edx
call   1030 <asm_copy_optimized_k@plt>
add    $0x190,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<Copy>:
push   %r14
push   %rbx
sub    $0x108,%rsp
xorps  %xmm0,%xmm0
movaps 0xebc(%rip),%xmm1
movaps %xmm1,0x80(%rsp)
movaps 0xebd(%rip),%xmm1
movaps %xmm1,0x90(%rsp)
movaps 0xebe(%rip),%xmm1
movaps %xmm1,0xa0(%rsp)
movaps 0xebf(%rip),%xmm1
movaps %xmm1,0xb0(%rsp)
movaps 0xec0(%rip),%xmm1
movaps %xmm1,0xc0(%rsp)
movaps 0xec1(%rip),%xmm1
movaps %xmm1,0xd0(%rsp)
movaps 0xec2(%rip),%xmm1
movaps %xmm1,0xe0(%rsp)
movaps 0xec3(%rip),%xmm1
movaps %xmm1,0xf0(%rsp)
movaps %xmm0,0x70(%rsp)
movaps %xmm0,0x60(%rsp)
movaps %xmm0,0x50(%rsp)
movaps %xmm0,0x40(%rsp)
movaps %xmm0,0x30(%rsp)
movaps %xmm0,0x20(%rsp)
movaps %xmm0,0x10(%rsp)
movaps %xmm0,(%rsp)
lea    0x80(%rsp),%r14
mov    %rsp,%rbx
mov    %r14,%rdi
mov    %rbx,%rsi
mov    $0x40,%edx
call   1050 <asm_copy_opt@plt>
mov    %rbx,%rdi
xor    %esi,%esi
mov    $0x80,%edx
call   1040 <memset@plt>
mov    %rbx,%rdi
xor    %esi,%esi
mov    $0x80,%edx
call   1040 <memset@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
mov    $0x40,%edx
call   1030 <asm_copy_optimized_k@plt>
add    $0x108,%rsp
pop    %rbx
pop    %r14
ret

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

LLVM IR (-O2):
define void @Copy() {
%1 = alloca [64 x i16]
%2 = alloca [64 x i16]
%3 = bitcast [64 x i16]* %1 to i8*
%4 = bitcast [64 x i16]* %1 to <8 x i16>*
store <8 x i16> <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>, <8 x i16>* %4
%5 = getelementptr inbounds [64 x i16], [64 x i16]* %1, i64 0, i64 8
%6 = bitcast i16* %5 to <8 x i16>*
store <8 x i16> <i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>, <8 x i16>* %6
%7 = getelementptr inbounds [64 x i16], [64 x i16]* %1, i64 0, i64 16
%8 = bitcast i16* %7 to <8 x i16>*
store <8 x i16> <i16 16, i16 17, i16 18, i16 19, i16 20, i16 21, i16 22, i16 23>, <8 x i16>* %8
%9 = getelementptr inbounds [64 x i16], [64 x i16]* %1, i64 0, i64 24
%10 = bitcast i16* %9 to <8 x i16>*
store <8 x i16> <i16 24, i16 25, i16 26, i16 27, i16 28, i16 29, i16 30, i16 31>, <8 x i16>* %10
%11 = getelementptr inbounds [64 x i16], [64 x i16]* %1, i64 0, i64 32
%12 = bitcast i16* %11 to <8 x i16>*
store <8 x i16> <i16 32, i16 33, i16 34, i16 35, i16 36, i16 37, i16 38, i16 39>, <8 x i16>* %12
%13 = getelementptr inbounds [64 x i16], [64 x i16]* %1, i64 0, i64 40
%14 = bitcast i16* %13 to <8 x i16>*
store <8 x i16> <i16 40, i16 41, i16 42, i16 43, i16 44, i16 45, i16 46, i16 47>, <8 x i16>* %14
%15 = getelementptr inbounds [64 x i16], [64 x i16]* %1, i64 0, i64 48
%16 = bitcast i16* %15 to <8 x i16>*
store <8 x i16> <i16 48, i16 49, i16 50, i16 51, i16 52, i16 53, i16 54, i16 55>, <8 x i16>* %16
%17 = getelementptr inbounds [64 x i16], [64 x i16]* %1, i64 0, i64 56
%18 = bitcast i16* %17 to <8 x i16>*
store <8 x i16> <i16 56, i16 57, i16 58, i16 59, i16 60, i16 61, i16 62, i16 63>, <8 x i16>* %18
%19 = bitcast [64 x i16]* %2 to i8*
%20 = getelementptr inbounds [64 x i16], [64 x i16]* %1, i64 0, i64 0
%21 = getelementptr inbounds [64 x i16], [64 x i16]* %2, i64 0, i64 0
%22 = call i32 @asm_copy_opt(i16* %20, i16* %21, i32 64)
%23 = call i32 @memset(i16* %21, i32 0, i32 128)
%24 = call i32 @memset(i16* %21, i32 0, i32 128)
%25 = call i32 @asm_copy_optimized_k(i16* %20, i16* %21, i32 64)
ret void
}