#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*/ abort();
int memcmp(char *, char *, int);
int /*<<< orphan*/ memcpy(char *, char const *, int);
void test_memcmp_16_1(const char *str1, const char *str2, int expect) {
  char three[8192] __attribute__((aligned(4096)));
  char four[8192] __attribute__((aligned(4096)));
  char *a, *b;
  int i, j, r;
  for (j = 0; j < 2; j++) {
    for (i = 0; i < 2; i++) {
      a = three + i * 1 + j * (4096 - 2 * i * 1);
      b = four + i * 1 + j * (4096 - 2 * i * 1);
      memcpy(a, str1, 16);
      memcpy(b, str2, 16);
      r = memcmp(a, b, 16);
      if (r < 0 && !(expect < 0))
        abort();
      if (r > 0 && !(expect > 0))
        abort();
      if (r == 0 && !(expect == 0))
        abort();
    }
  }
}


x86 assembly (clang, -O0):
<test_memcmp_16_1>:
push   %rbp
mov    %rsp,%rbp
and    $0xfffffffffffff000,%rsp
sub    $0x6000,%rsp
mov    %rdi,0x5fe8(%rsp)
mov    %rsi,0x5fe0(%rsp)
mov    %edx,0x5fdc(%rsp)
movl   $0x0,0xfe8(%rsp)
cmpl   $0x2,0xfe8(%rsp)
02
jge    1307 <test_memcmp_16_1+0x1d7>
movl   $0x0,0xfec(%rsp)
cmpl   $0x2,0xfec(%rsp)
02
jge    12ec <test_memcmp_16_1+0x1bc>
lea    0x3000(%rsp),%rax
mov    0xfec(%rsp),%ecx
shl    $0x0,%ecx
movslq %ecx,%rcx
add    %rcx,%rax
mov    0xfe8(%rsp),%ecx
mov    0xfec(%rsp),%esi
shl    $0x1,%esi
shl    $0x0,%esi
mov    $0x1000,%edx
sub    %esi,%edx
imul   %edx,%ecx
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,0xff8(%rsp)
lea    0x1000(%rsp),%rax
mov    0xfec(%rsp),%ecx
shl    $0x0,%ecx
movslq %ecx,%rcx
add    %rcx,%rax
mov    0xfe8(%rsp),%ecx
mov    0xfec(%rsp),%esi
shl    $0x1,%esi
shl    $0x0,%esi
mov    $0x1000,%edx
sub    %esi,%edx
imul   %edx,%ecx
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,0xff0(%rsp)
mov    0xff8(%rsp),%rdi
mov    0x5fe8(%rsp),%rsi
mov    $0x10,%edx
call   1050 <memcpy@plt>
mov    0xff0(%rsp),%rdi
mov    0x5fe0(%rsp),%rsi
mov    $0x10,%edx
call   1050 <memcpy@plt>
mov    0xff8(%rsp),%rdi
mov    0xff0(%rsp),%rsi
mov    $0x10,%edx
call   1040 <memcmp@plt>
mov    %eax,0xfe4(%rsp)
cmpl   $0x0,0xfe4(%rsp)
jge    128b <test_memcmp_16_1+0x15b>
cmpl   $0x0,0x5fdc(%rsp)
jl     128b <test_memcmp_16_1+0x15b>
mov    $0x0,%al
call   1030 <abort@plt>
cmpl   $0x0,0xfe4(%rsp)
jle    12ae <test_memcmp_16_1+0x17e>
cmpl   $0x0,0x5fdc(%rsp)
jg     12ae <test_memcmp_16_1+0x17e>
mov    $0x0,%al
call   1030 <abort@plt>
cmpl   $0x0,0xfe4(%rsp)
jne    12d1 <test_memcmp_16_1+0x1a1>
cmpl   $0x0,0x5fdc(%rsp)
je     12d1 <test_memcmp_16_1+0x1a1>
mov    $0x0,%al
call   1030 <abort@plt>
jmp    12d6 <test_memcmp_16_1+0x1a6>
mov    0xfec(%rsp),%eax
add    $0x1,%eax
mov    %eax,0xfec(%rsp)
jmp    117d <test_memcmp_16_1+0x4d>
jmp    12f1 <test_memcmp_16_1+0x1c1>
mov    0xfe8(%rsp),%eax
add    $0x1,%eax
mov    %eax,0xfe8(%rsp)
jmp    1164 <test_memcmp_16_1+0x34>
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<test_memcmp_16_1>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
and    $0xfffffffffffff000,%rsp
sub    $0x5000,%rsp
mov    %edx,%ebx
mov    %rsi,%r14
mov    %rdi,%r15
lea    0x2000(%rsp),%r12
mov    %r12,%rdi
mov    %r15,%rsi
mov    $0x10,%edx
call   1050 <memcpy@plt>
mov    %rsp,%r13
mov    %r13,%rdi
mov    %r14,%rsi
mov    $0x10,%edx
call   1050 <memcpy@plt>
mov    %r12,%rdi
mov    %r13,%rsi
mov    $0x10,%edx
call   1040 <memcmp@plt>
test   %ebx,%ebx
js     119a <test_memcmp_16_1+0x6a>
test   %eax,%eax
js     12d2 <test_memcmp_16_1+0x1a2>
test   %ebx,%ebx
jg     11a6 <test_memcmp_16_1+0x76>
test   %eax,%eax
jg     12d2 <test_memcmp_16_1+0x1a2>
test   %ebx,%ebx
je     11b2 <test_memcmp_16_1+0x82>
test   %eax,%eax
je     12d2 <test_memcmp_16_1+0x1a2>
lea    0x2001(%rsp),%r12
lea    0x1(%rsp),%r13
mov    %r12,%rdi
mov    %r15,%rsi
mov    $0x10,%edx
call   1050 <memcpy@plt>
mov    %r13,%rdi
mov    %r14,%rsi
mov    $0x10,%edx
call   1050 <memcpy@plt>
mov    %r12,%rdi
mov    %r13,%rsi
mov    $0x10,%edx
call   1040 <memcmp@plt>
test   %ebx,%ebx
js     11fb <test_memcmp_16_1+0xcb>
test   %eax,%eax
js     12d2 <test_memcmp_16_1+0x1a2>
test   %ebx,%ebx
jg     1207 <test_memcmp_16_1+0xd7>
test   %eax,%eax
jg     12d2 <test_memcmp_16_1+0x1a2>
test   %ebx,%ebx
je     1213 <test_memcmp_16_1+0xe3>
test   %eax,%eax
je     12d2 <test_memcmp_16_1+0x1a2>
lea    0x3000(%rsp),%r12
lea    0x1000(%rsp),%r13
mov    %r12,%rdi
mov    %r15,%rsi
mov    $0x10,%edx
call   1050 <memcpy@plt>
mov    %r13,%rdi
mov    %r14,%rsi
mov    $0x10,%edx
call   1050 <memcpy@plt>
mov    %r12,%rdi
mov    %r13,%rsi
mov    $0x10,%edx
call   1040 <memcmp@plt>
test   %ebx,%ebx
js     125b <test_memcmp_16_1+0x12b>
test   %eax,%eax
js     12d2 <test_memcmp_16_1+0x1a2>
test   %ebx,%ebx
jg     1263 <test_memcmp_16_1+0x133>
test   %eax,%eax
jg     12d2 <test_memcmp_16_1+0x1a2>
test   %ebx,%ebx
je     126b <test_memcmp_16_1+0x13b>
test   %eax,%eax
je     12d2 <test_memcmp_16_1+0x1a2>
lea    0x2fff(%rsp),%r12
lea    0xfff(%rsp),%r13
mov    %r12,%rdi
mov    %r15,%rsi
mov    $0x10,%edx
call   1050 <memcpy@plt>
mov    %r13,%rdi
mov    %r14,%rsi
mov    $0x10,%edx
call   1050 <memcpy@plt>
mov    %r12,%rdi
mov    %r13,%rsi
mov    $0x10,%edx
call   1040 <memcmp@plt>
test   %ebx,%ebx
js     12b3 <test_memcmp_16_1+0x183>
test   %eax,%eax
js     12d2 <test_memcmp_16_1+0x1a2>
test   %ebx,%ebx
jg     12bb <test_memcmp_16_1+0x18b>
test   %eax,%eax
jg     12d2 <test_memcmp_16_1+0x1a2>
test   %ebx,%ebx
je     12c3 <test_memcmp_16_1+0x193>
test   %eax,%eax
je     12d2 <test_memcmp_16_1+0x1a2>
lea    -0x28(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
xor    %eax,%eax
call   1030 <abort@plt>

LLVM IR (-O0):
define void @test_memcmp_16_1(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i32
%7 = alloca [8192 x i8]
%8 = alloca [8192 x i8]
%9 = alloca i8*
%10 = alloca i8*
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
store i8* %0, i8** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
store i32 0, i32* %12
br label %14
14: ; preds = %85, %3
%15 = load i32, i32* %12
%16 = icmp slt i32 %15, 2
br i1 %16, label %17, label %88
17: ; preds = %14
store i32 0, i32* %11
br label %18
18: ; preds = %81, %17
%19 = load i32, i32* %11
%20 = icmp slt i32 %19, 2
br i1 %20, label %21, label %84
21: ; preds = %18
%22 = getelementptr inbounds [8192 x i8], [8192 x i8]* %7, i64 0, i64 0
%23 = load i32, i32* %11
%24 = mul nsw i32 %23, 1
%25 = sext i32 %24 to i64
%26 = getelementptr inbounds i8, i8* %22, i64 %25
%27 = load i32, i32* %12
%28 = load i32, i32* %11
%29 = mul nsw i32 2, %28
%30 = mul nsw i32 %29, 1
%31 = sub nsw i32 4096, %30
%32 = mul nsw i32 %27, %31
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds i8, i8* %26, i64 %33
store i8* %34, i8** %9
%35 = getelementptr inbounds [8192 x i8], [8192 x i8]* %8, i64 0, i64 0
%36 = load i32, i32* %11
%37 = mul nsw i32 %36, 1
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds i8, i8* %35, i64 %38
%40 = load i32, i32* %12
%41 = load i32, i32* %11
%42 = mul nsw i32 2, %41
%43 = mul nsw i32 %42, 1
%44 = sub nsw i32 4096, %43
%45 = mul nsw i32 %40, %44
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds i8, i8* %39, i64 %46
store i8* %47, i8** %10
%48 = load i8*, i8** %9
%49 = load i8*, i8** %4
%50 = call i32 @memcpy(i8* %48, i8* %49, i32 16)
%51 = load i8*, i8** %10
%52 = load i8*, i8** %5
%53 = call i32 @memcpy(i8* %51, i8* %52, i32 16)
%54 = load i8*, i8** %9
%55 = load i8*, i8** %10
%56 = call i32 @memcmp(i8* %54, i8* %55, i32 16)
store i32 %56, i32* %13
%57 = load i32, i32* %13
%58 = icmp slt i32 %57, 0
br i1 %58, label %59, label %64
59: ; preds = %21
%60 = load i32, i32* %6
%61 = icmp slt i32 %60, 0
br i1 %61, label %64, label %62
62: ; preds = %59
%63 = call i32 (...) @abort()
unreachable
64: ; preds = %59, %21
%65 = load i32, i32* %13
%66 = icmp sgt i32 %65, 0
br i1 %66, label %67, label %72
67: ; preds = %64
%68 = load i32, i32* %6
%69 = icmp sgt i32 %68, 0
br i1 %69, label %72, label %70
70: ; preds = %67
%71 = call i32 (...) @abort()
unreachable
72: ; preds = %67, %64
%73 = load i32, i32* %13
%74 = icmp eq i32 %73, 0
br i1 %74, label %75, label %80
75: ; preds = %72
%76 = load i32, i32* %6
%77 = icmp eq i32 %76, 0
br i1 %77, label %80, label %78
78: ; preds = %75
%79 = call i32 (...) @abort()
unreachable
80: ; preds = %75, %72
br label %81
81: ; preds = %80
%82 = load i32, i32* %11
%83 = add nsw i32 %82, 1
store i32 %83, i32* %11
br label %18
84: ; preds = %18
br label %85
85: ; preds = %84
%86 = load i32, i32* %12
%87 = add nsw i32 %86, 1
store i32 %87, i32* %12
br label %14
88: ; preds = %14
ret void
}

LLVM IR (-O2):
define void @test_memcmp_16_1(i8* %0, i8* %1, i32 %2) {
%4 = alloca [8192 x i8]
%5 = alloca [8192 x i8]
%6 = getelementptr inbounds [8192 x i8], [8192 x i8]* %4, i64 0, i64 0
%7 = getelementptr inbounds [8192 x i8], [8192 x i8]* %5, i64 0, i64 0
%8 = icmp slt i32 %2, 0
%9 = icmp sgt i32 %2, 0
%10 = icmp eq i32 %2, 0
%11 = call i32 @memcpy(i8* %6, i8* %0, i32 16)
%12 = call i32 @memcpy(i8* %7, i8* %1, i32 16)
%13 = call i32 @memcmp(i8* %6, i8* %7, i32 16)
%14 = icmp sgt i32 %13, -1
%15 = or i1 %8, %14
br i1 %15, label %61, label %59
16: ; preds = %66
%17 = getelementptr inbounds [8192 x i8], [8192 x i8]* %4, i64 0, i64 1
%18 = getelementptr inbounds [8192 x i8], [8192 x i8]* %5, i64 0, i64 1
%19 = call i32 @memcpy(i8* %17, i8* %0, i32 16)
%20 = call i32 @memcpy(i8* %18, i8* %1, i32 16)
%21 = call i32 @memcmp(i8* %17, i8* %18, i32 16)
%22 = icmp sgt i32 %21, -1
%23 = or i1 %8, %22
br i1 %23, label %24, label %59
24: ; preds = %16
%25 = icmp slt i32 %21, 1
%26 = or i1 %9, %25
br i1 %26, label %27, label %64
27: ; preds = %24
%28 = icmp ne i32 %21, 0
%29 = or i1 %10, %28
br i1 %29, label %30, label %69
30: ; preds = %27
%31 = getelementptr inbounds [8192 x i8], [8192 x i8]* %4, i64 0, i64 4096
%32 = getelementptr inbounds [8192 x i8], [8192 x i8]* %5, i64 0, i64 4096
%33 = call i32 @memcpy(i8* %31, i8* %0, i32 16)
%34 = call i32 @memcpy(i8* %32, i8* %1, i32 16)
%35 = call i32 @memcmp(i8* %31, i8* %32, i32 16)
%36 = icmp sgt i32 %35, -1
%37 = or i1 %8, %36
br i1 %37, label %38, label %59
38: ; preds = %30
%39 = icmp slt i32 %35, 1
%40 = or i1 %9, %39
br i1 %40, label %41, label %64
41: ; preds = %38
%42 = icmp ne i32 %35, 0
%43 = or i1 %10, %42
br i1 %43, label %44, label %69
44: ; preds = %41
%45 = getelementptr inbounds [8192 x i8], [8192 x i8]* %4, i64 0, i64 4095
%46 = getelementptr inbounds [8192 x i8], [8192 x i8]* %5, i64 0, i64 4095
%47 = call i32 @memcpy(i8* %45, i8* %0, i32 16)
%48 = call i32 @memcpy(i8* %46, i8* %1, i32 16)
%49 = call i32 @memcmp(i8* %45, i8* %46, i32 16)
%50 = icmp sgt i32 %49, -1
%51 = or i1 %8, %50
br i1 %51, label %52, label %59
52: ; preds = %44
%53 = icmp slt i32 %49, 1
%54 = or i1 %9, %53
br i1 %54, label %55, label %64
55: ; preds = %52
%56 = icmp ne i32 %49, 0
%57 = or i1 %10, %56
br i1 %57, label %58, label %69
58: ; preds = %55
ret void
59: ; preds = %44, %30, %16, %3
%60 = call i32 (...) @abort()
unreachable
61: ; preds = %3
%62 = icmp slt i32 %13, 1
%63 = or i1 %9, %62
br i1 %63, label %66, label %64
64: ; preds = %52, %38, %24, %61
%65 = call i32 (...) @abort()
unreachable
66: ; preds = %61
%67 = icmp ne i32 %13, 0
%68 = or i1 %10, %67
br i1 %68, label %16, label %69
69: ; preds = %55, %41, %27, %66
%70 = call i32 (...) @abort()
unreachable
}