#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*/ flash_read(char *, int, int);
int /*<<< orphan*/ flash_write(char *, int, int);
int /*<<< orphan*/ free(char *);
scalar_t__ malloc(int);
int memcmp(char *, char *, int);
int /*<<< orphan*/ memset(char *, int /*<<< orphan*/, int);
int /*<<< orphan*/ sprintf(char *, char *, char *);
int /*<<< orphan*/ system(char *);
int main(int argc, char *argv[]) {
  int i = 0;
  int test_mem = 65535;
  int result;
  char *content = NULL;
  char *buf = NULL;
  char *shell = NULL;
  content = (char *)malloc(test_mem);
  buf = (char *)malloc(test_mem);
  shell = (char *)malloc(100);
  for (i = 0; i < test_mem; i++) {
    content[i] = 'a' + i % 26;
  }
  flash_write(content, 0x0, test_mem);
  memset(buf, 0, test_mem);
  flash_read(buf, 0x0, test_mem);
  result = memcmp(content, buf, test_mem);
  if (result == 0) {
    sprintf(shell, "echo Test result: PASS > %s", argv[1]);
  } else {
    sprintf(shell, "echo Test result: FAIL > %s", argv[1]);
  }
  system(shell);
  free(content);
  content = NULL;
  free(buf);
  buf = NULL;
  free(shell);
  shell = NULL;
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
movl   $0xffff,-0x18(%rbp)
movq   $0x0,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
movq   $0x0,-0x38(%rbp)
mov    -0x18(%rbp),%edi
call   1080 <malloc@plt>
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%edi
call   1080 <malloc@plt>
mov    %rax,-0x30(%rbp)
mov    $0x64,%edi
call   1080 <malloc@plt>
mov    %rax,-0x38(%rbp)
movl   $0x0,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x18(%rbp),%eax
jge    121c <main+0x9c>
mov    -0x14(%rbp),%eax
mov    $0x1a,%ecx
cltd
idiv   %ecx
add    $0x61,%edx
mov    -0x28(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    11e9 <main+0x69>
mov    -0x28(%rbp),%rdi
mov    -0x18(%rbp),%edx
xor    %esi,%esi
call   1090 <flash_write@plt>
mov    -0x30(%rbp),%rdi
mov    -0x18(%rbp),%edx
xor    %esi,%esi
call   1050 <memset@plt>
mov    -0x30(%rbp),%rdi
mov    -0x18(%rbp),%edx
xor    %esi,%esi
call   1070 <flash_read@plt>
mov    -0x28(%rbp),%rdi
mov    -0x30(%rbp),%rsi
mov    -0x18(%rbp),%edx
call   1060 <memcmp@plt>
mov    %eax,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jne    1280 <main+0x100>
mov    -0x38(%rbp),%rdi
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdx
lea    0xd8a(%rip),%rsi
call   10a0 <sprintf@plt>
jmp    1298 <main+0x118>
mov    -0x38(%rbp),%rdi
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdx
lea    0xd89(%rip),%rsi
call   10a0 <sprintf@plt>
mov    -0x38(%rbp),%rdi
call   1040 <system@plt>
mov    -0x28(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x28(%rbp)
mov    -0x30(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x30(%rbp)
mov    -0x38(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x38(%rbp)
xor    %eax,%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %r15
push   %r14
push   %r12
push   %rbx
push   %rax
mov    %rsi,%r12
mov    $0xffff,%edi
call   1080 <malloc@plt>
mov    %rax,%rbx
mov    $0xffff,%edi
call   1080 <malloc@plt>
mov    %rax,%r14
mov    $0x64,%edi
call   1080 <malloc@plt>
mov    %rax,%r15
movdqa 0xe46(%rip),%xmm4
movdqa 0xe4e(%rip),%xmm5
mov    $0x10,%eax
movdqa 0xe51(%rip),%xmm2
movdqa 0xe59(%rip),%xmm3
movdqa 0xe60(%rip),%xmm9
movdqa 0xe67(%rip),%xmm8
movdqa 0xe6f(%rip),%xmm6
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movdqa %xmm5,%xmm7
pmulhuw %xmm2,%xmm7
psrlw  $0x3,%xmm7
pmullw %xmm3,%xmm7
movdqa %xmm5,%xmm1
psubw  %xmm7,%xmm1
movdqa %xmm4,%xmm7
pmulhuw %xmm2,%xmm7
psrlw  $0x3,%xmm7
pmullw %xmm3,%xmm7
movdqa %xmm4,%xmm0
psubw  %xmm7,%xmm0
packuswb %xmm0,%xmm1
paddb  %xmm9,%xmm1
movdqu %xmm1,-0x10(%rbx,%rax,1)
cmp    $0xfff0,%rax
je     12a4 <main+0x124>
movdqa %xmm4,%xmm0
paddw  %xmm8,%xmm0
movdqa %xmm5,%xmm1
paddw  %xmm8,%xmm1
movdqa %xmm1,%xmm7
pmulhuw %xmm2,%xmm7
psrlw  $0x3,%xmm7
pmullw %xmm3,%xmm7
psubw  %xmm7,%xmm1
movdqa %xmm0,%xmm7
pmulhuw %xmm2,%xmm7
psrlw  $0x3,%xmm7
pmullw %xmm3,%xmm7
psubw  %xmm7,%xmm0
packuswb %xmm0,%xmm1
paddb  %xmm9,%xmm1
movdqu %xmm1,(%rbx,%rax,1)
paddw  %xmm6,%xmm5
paddw  %xmm6,%xmm4
add    $0x20,%rax
jmp    1200 <main+0x80>
movabs $0x6867666564636261,%rax
66 67 68
mov    %rax,0xfff0(%rbx)
movl   $0x6c6b6a69,0xfff8(%rbx)
6a 6b 6c
movw   $0x6e6d,0xfffc(%rbx)
6d 6e
movb   $0x6f,0xfffe(%rbx)
mov    %rbx,%rdi
xor    %esi,%esi
mov    $0xffff,%edx
call   1090 <flash_write@plt>
mov    %r14,%rdi
xor    %esi,%esi
mov    $0xffff,%edx
call   1050 <memset@plt>
mov    %r14,%rdi
xor    %esi,%esi
mov    $0xffff,%edx
call   1070 <flash_read@plt>
mov    %rbx,%rdi
mov    %r14,%rsi
mov    $0xffff,%edx
call   1060 <memcmp@plt>
test   %eax,%eax
mov    0x8(%r12),%rdx
lea    0xd56(%rip),%rax
lea    0xd6b(%rip),%rsi
cmove  %rax,%rsi
mov    %r15,%rdi
call   10a0 <sprintf@plt>
mov    %r15,%rdi
call   1040 <system@plt>
mov    %rbx,%rdi
call   1030 <free@plt>
mov    %r14,%rdi
call   1030 <free@plt>
mov    %r15,%rdi
call   1030 <free@plt>
xor    %eax,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@.str = [28 x i8] c"echo Test result: PASS > %s\00"
@.str.1 = [28 x i8] c"echo Test result: FAIL > %s\00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i8*
%10 = alloca i8*
%11 = alloca i8*
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
store i32 0, i32* %6
store i32 65535, i32* %7
store i8* null, i8** %9
store i8* null, i8** %10
store i8* null, i8** %11
%12 = load i32, i32* %7
%13 = call i64 @malloc(i32 %12)
%14 = inttoptr i64 %13 to i8*
store i8* %14, i8** %9
%15 = load i32, i32* %7
%16 = call i64 @malloc(i32 %15)
%17 = inttoptr i64 %16 to i8*
store i8* %17, i8** %10
%18 = call i64 @malloc(i32 100)
%19 = inttoptr i64 %18 to i8*
store i8* %19, i8** %11
store i32 0, i32* %6
br label %20
20: ; preds = %33, %2
%21 = load i32, i32* %6
%22 = load i32, i32* %7
%23 = icmp slt i32 %21, %22
br i1 %23, label %24, label %36
24: ; preds = %20
%25 = load i32, i32* %6
%26 = srem i32 %25, 26
%27 = add nsw i32 97, %26
%28 = trunc i32 %27 to i8
%29 = load i8*, i8** %9
%30 = load i32, i32* %6
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds i8, i8* %29, i64 %31
store i8 %28, i8* %32
br label %33
33: ; preds = %24
%34 = load i32, i32* %6
%35 = add nsw i32 %34, 1
store i32 %35, i32* %6
br label %20
36: ; preds = %20
%37 = load i8*, i8** %9
%38 = load i32, i32* %7
%39 = call i32 @flash_write(i8* %37, i32 0, i32 %38)
%40 = load i8*, i8** %10
%41 = load i32, i32* %7
%42 = call i32 @memset(i8* %40, i32 0, i32 %41)
%43 = load i8*, i8** %10
%44 = load i32, i32* %7
%45 = call i32 @flash_read(i8* %43, i32 0, i32 %44)
%46 = load i8*, i8** %9
%47 = load i8*, i8** %10
%48 = load i32, i32* %7
%49 = call i32 @memcmp(i8* %46, i8* %47, i32 %48)
store i32 %49, i32* %8
%50 = load i32, i32* %8
%51 = icmp eq i32 %50, 0
br i1 %51, label %52, label %58
52: ; preds = %36
%53 = load i8*, i8** %11
%54 = load i8**, i8*** %5
%55 = getelementptr inbounds i8*, i8** %54, i64 1
%56 = load i8*, i8** %55
%57 = call i32 @sprintf(i8* %53, i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str, i64 0, i64 0), i8* %56)
br label %64
58: ; preds = %36
%59 = load i8*, i8** %11
%60 = load i8**, i8*** %5
%61 = getelementptr inbounds i8*, i8** %60, i64 1
%62 = load i8*, i8** %61
%63 = call i32 @sprintf(i8* %59, i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.1, i64 0, i64 0), i8* %62)
br label %64
64: ; preds = %58, %52
%65 = load i8*, i8** %11
%66 = call i32 @system(i8* %65)
%67 = load i8*, i8** %9
%68 = call i32 @free(i8* %67)
store i8* null, i8** %9
%69 = load i8*, i8** %10
%70 = call i32 @free(i8* %69)
store i8* null, i8** %10
%71 = load i8*, i8** %11
%72 = call i32 @free(i8* %71)
store i8* null, i8** %11
ret i32 0
}

LLVM IR (-O2):
@.str = [28 x i8] c"echo Test result: PASS > %s\00"
@.str.1 = [28 x i8] c"echo Test result: FAIL > %s\00"
define i32 @main(i32 %0, i8** nocapture %1) {
%3 = tail call i64 @malloc(i32 65535)
%4 = inttoptr i64 %3 to i8*
%5 = tail call i64 @malloc(i32 65535)
%6 = tail call i64 @malloc(i32 100)
br label %7
7: ; preds = %17, %2
%8 = phi i64 [ 0, %2 ], [ %24, %17 ]
%9 = phi <16 x i16> [ <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>, %2 ], [ %25, %17 ]
%10 = urem <16 x i16> %9, <i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26>
%11 = trunc <16 x i16> %10 to <16 x i8>
%12 = add nuw nsw <16 x i8> %11, <i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97>
%13 = getelementptr inbounds i8, i8* %4, i64 %8
%14 = bitcast i8* %13 to <16 x i8>*
store <16 x i8> %12, <16 x i8>* %14
%15 = or i64 %8, 16
%16 = icmp eq i64 %15, 65520
br i1 %16, label %26, label %17
17: ; preds = %7
%18 = add <16 x i16> %9, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
%19 = urem <16 x i16> %18, <i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26>
%20 = trunc <16 x i16> %19 to <16 x i8>
%21 = add nuw nsw <16 x i8> %20, <i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97>
%22 = getelementptr inbounds i8, i8* %4, i64 %15
%23 = bitcast i8* %22 to <16 x i8>*
store <16 x i8> %21, <16 x i8>* %23
%24 = add nuw nsw i64 %8, 32
%25 = add <16 x i16> %9, <i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32>
br label %7
26: ; preds = %7
%27 = getelementptr inbounds i8, i8* %4, i64 65520
store i8 97, i8* %27
%28 = getelementptr inbounds i8, i8* %4, i64 65521
store i8 98, i8* %28
%29 = getelementptr inbounds i8, i8* %4, i64 65522
store i8 99, i8* %29
%30 = getelementptr inbounds i8, i8* %4, i64 65523
store i8 100, i8* %30
%31 = getelementptr inbounds i8, i8* %4, i64 65524
store i8 101, i8* %31
%32 = getelementptr inbounds i8, i8* %4, i64 65525
store i8 102, i8* %32
%33 = getelementptr inbounds i8, i8* %4, i64 65526
store i8 103, i8* %33
%34 = getelementptr inbounds i8, i8* %4, i64 65527
store i8 104, i8* %34
%35 = getelementptr inbounds i8, i8* %4, i64 65528
store i8 105, i8* %35
%36 = getelementptr inbounds i8, i8* %4, i64 65529
store i8 106, i8* %36
%37 = getelementptr inbounds i8, i8* %4, i64 65530
store i8 107, i8* %37
%38 = getelementptr inbounds i8, i8* %4, i64 65531
store i8 108, i8* %38
%39 = getelementptr inbounds i8, i8* %4, i64 65532
store i8 109, i8* %39
%40 = getelementptr inbounds i8, i8* %4, i64 65533
store i8 110, i8* %40
%41 = getelementptr inbounds i8, i8* %4, i64 65534
store i8 111, i8* %41
%42 = inttoptr i64 %5 to i8*
%43 = inttoptr i64 %6 to i8*
%44 = tail call i32 @flash_write(i8* %4, i32 0, i32 65535)
%45 = tail call i32 @memset(i8* %42, i32 0, i32 65535)
%46 = tail call i32 @flash_read(i8* %42, i32 0, i32 65535)
%47 = tail call i32 @memcmp(i8* %4, i8* %42, i32 65535)
%48 = icmp eq i32 %47, 0
%49 = getelementptr inbounds i8*, i8** %1, i64 1
%50 = load i8*, i8** %49
%51 = select i1 %48, i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.1, i64 0, i64 0)
%52 = tail call i32 @sprintf(i8* dereferenceable(1) %43, i8* dereferenceable(1) %51, i8* %50)
%53 = tail call i32 @system(i8* %43)
%54 = tail call i32 @free(i8* %4)
%55 = tail call i32 @free(i8* %42)
%56 = tail call i32 @free(i8* %43)
ret i32 0
}