#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 */

/* Variables and functions */
int /*<<< orphan*/ CopyRepMovsb(char *const, char const *const, size_t);
void exegesis_copyblock(char *const, char const *const, int);
int /*<<< orphan*/ exegesis_overlap(char *const, char const *const, size_t,
                                    int);
void Copy_V1(char *const dst, const char *const src, size_t count) {
  if (count == 0)
    return;
  if (count == 1)
    return exegesis_copyblock(dst, src, 1);
  if (count == 2)
    return exegesis_copyblock(dst, src, 2);
  if (count == 3)
    return exegesis_copyblock(dst, src, 3);
  if (count == 4)
    return exegesis_copyblock(dst, src, 4);
  if (count <= 8) {
    exegesis_overlap(dst, src, count, 4);
    return;
  };
  if (count <= 16) {
    exegesis_overlap(dst, src, count, 8);
    return;
  };
  if (count <= 32) {
    exegesis_overlap(dst, src, count, 16);
    return;
  };
  if (count <= 64) {
    exegesis_overlap(dst, src, count, 32);
    return;
  };
  if (count <= 128) {
    exegesis_overlap(dst, src, count, 64);
    return;
  };
  CopyRepMovsb(dst, src, count);
}


x86 assembly (clang, -O0):
<Copy_V1>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    1154 <Copy_V1+0x24>
jmp    12ae <Copy_V1+0x17e>
cmpq   $0x1,-0x18(%rbp)
jne    1176 <Copy_V1+0x46>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    $0x1,%edx
call   1030 <exegesis_copyblock@plt>
jmp    12ae <Copy_V1+0x17e>
cmpq   $0x2,-0x18(%rbp)
jne    1198 <Copy_V1+0x68>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    $0x2,%edx
call   1030 <exegesis_copyblock@plt>
jmp    12ae <Copy_V1+0x17e>
cmpq   $0x3,-0x18(%rbp)
jne    11ba <Copy_V1+0x8a>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    $0x3,%edx
call   1030 <exegesis_copyblock@plt>
jmp    12ae <Copy_V1+0x17e>
cmpq   $0x4,-0x18(%rbp)
jne    11dc <Copy_V1+0xac>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    $0x4,%edx
call   1030 <exegesis_copyblock@plt>
jmp    12ae <Copy_V1+0x17e>
cmpq   $0x8,-0x18(%rbp)
ja     1202 <Copy_V1+0xd2>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
mov    $0x4,%ecx
call   1040 <exegesis_overlap@plt>
jmp    12ae <Copy_V1+0x17e>
cmpq   $0x10,-0x18(%rbp)
ja     1228 <Copy_V1+0xf8>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
mov    $0x8,%ecx
call   1040 <exegesis_overlap@plt>
jmp    12ae <Copy_V1+0x17e>
cmpq   $0x20,-0x18(%rbp)
ja     124e <Copy_V1+0x11e>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
mov    $0x10,%ecx
call   1040 <exegesis_overlap@plt>
jmp    12ae <Copy_V1+0x17e>
cmpq   $0x40,-0x18(%rbp)
ja     1274 <Copy_V1+0x144>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
mov    $0x20,%ecx
call   1040 <exegesis_overlap@plt>
jmp    12ae <Copy_V1+0x17e>
cmpq   $0x80,-0x18(%rbp)
ja     129d <Copy_V1+0x16d>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
mov    $0x40,%ecx
call   1040 <exegesis_overlap@plt>
jmp    12ae <Copy_V1+0x17e>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
call   1050 <CopyRepMovsb@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<Copy_V1>:
cmp    $0x4,%rdx
ja     116f <Copy_V1+0x3f>
lea    0xec3(%rip),%rax
movslq (%rax,%rdx,4),%rcx
add    %rax,%rcx
jmp    *%rcx
ret
mov    $0x1,%edx
jmp    1030 <exegesis_copyblock@plt>
mov    $0x2,%edx
jmp    1030 <exegesis_copyblock@plt>
mov    $0x3,%edx
jmp    1030 <exegesis_copyblock@plt>
mov    $0x4,%edx
jmp    1030 <exegesis_copyblock@plt>
cmp    $0x8,%rdx
ja     117f <Copy_V1+0x4f>
mov    $0x4,%ecx
jmp    1040 <exegesis_overlap@plt>
cmp    $0x10,%rdx
ja     118f <Copy_V1+0x5f>
mov    $0x8,%ecx
jmp    1040 <exegesis_overlap@plt>
cmp    $0x20,%rdx
ja     119f <Copy_V1+0x6f>
mov    $0x10,%ecx
jmp    1040 <exegesis_overlap@plt>
cmp    $0x40,%rdx
ja     11af <Copy_V1+0x7f>
mov    $0x20,%ecx
jmp    1040 <exegesis_overlap@plt>
cmp    $0x80,%rdx
ja     11c2 <Copy_V1+0x92>
mov    $0x40,%ecx
jmp    1040 <exegesis_overlap@plt>
jmp    1050 <CopyRepMovsb@plt>

LLVM IR (-O0):
define void @Copy_V1(i8* %0, i8* %1, i64 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i64
store i8* %0, i8** %4
store i8* %1, i8** %5
store i64 %2, i64* %6
%7 = load i64, i64* %6
%8 = icmp eq i64 %7, 0
br i1 %8, label %9, label %10
9: ; preds = %3
br label %79
10: ; preds = %3
%11 = load i64, i64* %6
%12 = icmp eq i64 %11, 1
br i1 %12, label %13, label %16
13: ; preds = %10
%14 = load i8*, i8** %4
%15 = load i8*, i8** %5
br label %79
16: ; preds = %10
%17 = load i64, i64* %6
%18 = icmp eq i64 %17, 2
br i1 %18, label %19, label %22
19: ; preds = %16
%20 = load i8*, i8** %4
%21 = load i8*, i8** %5
br label %79
22: ; preds = %16
%23 = load i64, i64* %6
%24 = icmp eq i64 %23, 3
br i1 %24, label %25, label %28
25: ; preds = %22
%26 = load i8*, i8** %4
%27 = load i8*, i8** %5
br label %79
28: ; preds = %22
%29 = load i64, i64* %6
%30 = icmp eq i64 %29, 4
br i1 %30, label %31, label %34
31: ; preds = %28
%32 = load i8*, i8** %4
%33 = load i8*, i8** %5
br label %79
34: ; preds = %28
%35 = load i64, i64* %6
%36 = icmp ule i64 %35, 8
br i1 %36, label %37, label %42
37: ; preds = %34
%38 = load i8*, i8** %4
%39 = load i8*, i8** %5
%40 = load i64, i64* %6
%41 = call i32 @exegesis_overlap(i8* %38, i8* %39, i64 %40, i32 4)
br label %79
42: ; preds = %34
%43 = load i64, i64* %6
%44 = icmp ule i64 %43, 16
br i1 %44, label %45, label %50
45: ; preds = %42
%46 = load i8*, i8** %4
%47 = load i8*, i8** %5
%48 = load i64, i64* %6
%49 = call i32 @exegesis_overlap(i8* %46, i8* %47, i64 %48, i32 8)
br label %79
50: ; preds = %42
%51 = load i64, i64* %6
%52 = icmp ule i64 %51, 32
br i1 %52, label %53, label %58
53: ; preds = %50
%54 = load i8*, i8** %4
%55 = load i8*, i8** %5
%56 = load i64, i64* %6
%57 = call i32 @exegesis_overlap(i8* %54, i8* %55, i64 %56, i32 16)
br label %79
58: ; preds = %50
%59 = load i64, i64* %6
%60 = icmp ule i64 %59, 64
br i1 %60, label %61, label %66
61: ; preds = %58
%62 = load i8*, i8** %4
%63 = load i8*, i8** %5
%64 = load i64, i64* %6
%65 = call i32 @exegesis_overlap(i8* %62, i8* %63, i64 %64, i32 32)
br label %79
66: ; preds = %58
%67 = load i64, i64* %6
%68 = icmp ule i64 %67, 128
br i1 %68, label %69, label %74
69: ; preds = %66
%70 = load i8*, i8** %4
%71 = load i8*, i8** %5
%72 = load i64, i64* %6
%73 = call i32 @exegesis_overlap(i8* %70, i8* %71, i64 %72, i32 64)
br label %79
74: ; preds = %66
%75 = load i8*, i8** %4
%76 = load i8*, i8** %5
%77 = load i64, i64* %6
%78 = call i32 @CopyRepMovsb(i8* %75, i8* %76, i64 %77)
br label %79
79: ; preds = %74, %69, %61, %53, %45, %37, %31, %25, %19, %13, %9
ret void
}

LLVM IR (-O2):
define void @Copy_V1(i8* %0, i8* %1, i64 %2) {
switch i64 %2, label %8 [
i64 0, label %30
i64 1, label %4
i64 2, label %5
i64 3, label %6
i64 4, label %7
]
4: ; preds = %3
tail call void @exegesis_copyblock(i8* %0, i8* %1, i32 1)
br label %30
5: ; preds = %3
tail call void @exegesis_copyblock(i8* %0, i8* %1, i32 2)
br label %30
6: ; preds = %3
tail call void @exegesis_copyblock(i8* %0, i8* %1, i32 3)
br label %30
7: ; preds = %3
tail call void @exegesis_copyblock(i8* %0, i8* %1, i32 4)
br label %30
8: ; preds = %3
%9 = icmp ult i64 %2, 9
br i1 %9, label %10, label %12
10: ; preds = %8
%11 = tail call i32 @exegesis_overlap(i8* %0, i8* %1, i64 %2, i32 4)
br label %30
12: ; preds = %8
%13 = icmp ult i64 %2, 17
br i1 %13, label %14, label %16
14: ; preds = %12
%15 = tail call i32 @exegesis_overlap(i8* %0, i8* %1, i64 %2, i32 8)
br label %30
16: ; preds = %12
%17 = icmp ult i64 %2, 33
br i1 %17, label %18, label %20
18: ; preds = %16
%19 = tail call i32 @exegesis_overlap(i8* %0, i8* %1, i64 %2, i32 16)
br label %30
20: ; preds = %16
%21 = icmp ult i64 %2, 65
br i1 %21, label %22, label %24
22: ; preds = %20
%23 = tail call i32 @exegesis_overlap(i8* %0, i8* %1, i64 %2, i32 32)
br label %30
24: ; preds = %20
%25 = icmp ult i64 %2, 129
br i1 %25, label %26, label %28
26: ; preds = %24
%27 = tail call i32 @exegesis_overlap(i8* %0, i8* %1, i64 %2, i32 64)
br label %30
28: ; preds = %24
%29 = tail call i32 @CopyRepMovsb(i8* %0, i8* %1, i64 %2)
br label %30
30: ; preds = %3, %28, %26, %22, %18, %14, %10, %7, %6, %5, %4
ret void
}