#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 */
struct stat {
  int dummy;
};
typedef scalar_t__ pid_t;

/* Variables and functions */
int /*<<< orphan*/ err(int /*<<< orphan*/, char *);
scalar_t__ fork();
int pipe(int *);
int /*<<< orphan*/ printf(char *, ...);
int read(int, ...);
int /*<<< orphan*/ usleep(int);
int write(int, ...);
int main(void) {
  char buffer[65535], buffer2[65535];
  int desc[2];
  int buggy, error, i, successes, total;
  struct stat status;
  pid_t new_pid;
  buggy = 0;
  total = 0;
  error = pipe(desc);
  if (error)
    err(0, "Couldn't allocate fds\n");
  buffer[0] = 'A';
  for (i = 1; i < 65535; i++) {
    buffer[i] = buffer[i - 1] + 1;
    if (buffer[i] > 'Z')
      buffer[i] = 'A';
  }
  new_pid = fork();
  if (new_pid == 0) {
    error = write(desc[0], &buffer, 4096);
    total += error;
    error = write(desc[0], &buffer[total], 4096);
    total += error;
    error = write(desc[0], &buffer[total], 4096);
    total += error;
    error = write(desc[0], &buffer[total], 4096);
    total += error;
    error = write(desc[0], &buffer[total], 4096);
    total += error;
    error = write(desc[0], &buffer[total], 4096);
    total += error;
    error = write(desc[0], &buffer[total], 4096);
    total += error;
    error = write(desc[0], &buffer[total], 4096);
    total += error;
    printf("Wrote %d bytes, sleeping\n", total);
    usleep(1000000);
    error = write(desc[0], &buffer[total], 4096);
    total += error;
    error = write(desc[0], &buffer[total], 4096);
    total += error;
    printf("Wrote another 8192 bytes, %d total, done\n", total);
  } else {
    usleep(500000);
    error = read(desc[1], &buffer2, 32768);
    total += error;
    printf("Read %d bytes, going back to sleep\n", error);
    usleep(1000000);
    error = read(desc[1], &buffer2[total], 8192);
    total += error;
    printf("Read %d bytes, done\n", error);
    for (i = 0; i < total; i++) {
      if (buffer[i] != buffer2[i]) {
        buggy = 1;
        printf("Location %d input: %hhx output: %hhx\n", i, buffer[i],
               buffer2[i]);
      }
    }
    if ((buggy == 1) || (total != 40960))
      printf("FAILURE\n");
    else
      printf("SUCCESS\n");
  }
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20040,%rsp
movl   $0x0,-0x4(%rbp)
movl   $0x0,-0x2001c(%rbp)
movl   $0x0,-0x2002c(%rbp)
lea    -0x20018(%rbp),%rdi
call   1050 <pipe@plt>
mov    %eax,-0x20020(%rbp)
cmpl   $0x0,-0x20020(%rbp)
je     11c3 <main+0x53>
xor    %edi,%edi
lea    0xe42(%rip),%rsi
call   1070 <err@plt>
movb   $0x41,-0x10010(%rbp)
movl   $0x1,-0x20024(%rbp)
cmpl   $0xffff,-0x20024(%rbp)
jge    124a <main+0xda>
mov    -0x20024(%rbp),%eax
sub    $0x1,%eax
cltq
movsbl -0x10010(%rbp,%rax,1),%eax
ff
add    $0x1,%eax
mov    %al,%cl
movslq -0x20024(%rbp),%rax
mov    %cl,-0x10010(%rbp,%rax,1)
movslq -0x20024(%rbp),%rax
movsbl -0x10010(%rbp,%rax,1),%eax
ff
cmp    $0x5a,%eax
jle    1231 <main+0xc1>
movslq -0x20024(%rbp),%rax
movb   $0x41,-0x10010(%rbp,%rax,1)
41
jmp    1236 <main+0xc6>
mov    -0x20024(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20024(%rbp)
jmp    11d4 <main+0x64>
mov    $0x0,%al
call   1080 <fork@plt>
mov    %rax,-0x20038(%rbp)
cmpq   $0x0,-0x20038(%rbp)
jne    14e1 <main+0x371>
mov    -0x20018(%rbp),%edi
lea    -0x10010(%rbp),%rsi
mov    $0x1000,%edx
mov    $0x0,%al
call   1030 <write@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x20018(%rbp),%edi
movslq -0x2002c(%rbp),%rax
lea    -0x10010(%rbp),%rsi
add    %rax,%rsi
mov    $0x1000,%edx
mov    $0x0,%al
call   1030 <write@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x20018(%rbp),%edi
movslq -0x2002c(%rbp),%rax
lea    -0x10010(%rbp),%rsi
add    %rax,%rsi
mov    $0x1000,%edx
mov    $0x0,%al
call   1030 <write@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x20018(%rbp),%edi
movslq -0x2002c(%rbp),%rax
lea    -0x10010(%rbp),%rsi
add    %rax,%rsi
mov    $0x1000,%edx
mov    $0x0,%al
call   1030 <write@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x20018(%rbp),%edi
movslq -0x2002c(%rbp),%rax
lea    -0x10010(%rbp),%rsi
add    %rax,%rsi
mov    $0x1000,%edx
mov    $0x0,%al
call   1030 <write@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x20018(%rbp),%edi
movslq -0x2002c(%rbp),%rax
lea    -0x10010(%rbp),%rsi
add    %rax,%rsi
mov    $0x1000,%edx
mov    $0x0,%al
call   1030 <write@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x20018(%rbp),%edi
movslq -0x2002c(%rbp),%rax
lea    -0x10010(%rbp),%rsi
add    %rax,%rsi
mov    $0x1000,%edx
mov    $0x0,%al
call   1030 <write@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x20018(%rbp),%edi
movslq -0x2002c(%rbp),%rax
lea    -0x10010(%rbp),%rsi
add    %rax,%rsi
mov    $0x1000,%edx
mov    $0x0,%al
call   1030 <write@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x2002c(%rbp),%esi
lea    0xbd6(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
mov    $0xf4240,%edi
call   1090 <usleep@plt>
mov    -0x20018(%rbp),%edi
movslq -0x2002c(%rbp),%rax
lea    -0x10010(%rbp),%rsi
add    %rax,%rsi
mov    $0x1000,%edx
mov    $0x0,%al
call   1030 <write@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x20018(%rbp),%edi
movslq -0x2002c(%rbp),%rax
lea    -0x10010(%rbp),%rsi
add    %rax,%rsi
mov    $0x1000,%edx
mov    $0x0,%al
call   1030 <write@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x2002c(%rbp),%esi
lea    0xb5c(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
jmp    1663 <main+0x4f3>
mov    $0x7a120,%edi
call   1090 <usleep@plt>
mov    -0x20014(%rbp),%edi
lea    -0x20010(%rbp),%rsi
mov    $0x8000,%edx
mov    $0x0,%al
call   1060 <read@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x20020(%rbp),%esi
lea    0xb32(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
mov    $0xf4240,%edi
call   1090 <usleep@plt>
mov    -0x20014(%rbp),%edi
movslq -0x2002c(%rbp),%rax
lea    -0x20010(%rbp),%rsi
add    %rax,%rsi
mov    $0x2000,%edx
mov    $0x0,%al
call   1060 <read@plt>
mov    %eax,-0x20020(%rbp)
mov    -0x20020(%rbp),%eax
add    -0x2002c(%rbp),%eax
mov    %eax,-0x2002c(%rbp)
mov    -0x20020(%rbp),%esi
lea    0xafd(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
movl   $0x0,-0x20024(%rbp)
mov    -0x20024(%rbp),%eax
cmp    -0x2002c(%rbp),%eax
jge    1620 <main+0x4b0>
movslq -0x20024(%rbp),%rax
movsbl -0x10010(%rbp,%rax,1),%eax
ff
movslq -0x20024(%rbp),%rcx
movsbl -0x20010(%rbp,%rcx,1),%ecx
ff
cmp    %ecx,%eax
je     1607 <main+0x497>
movl   $0x1,-0x2001c(%rbp)
mov    -0x20024(%rbp),%esi
movslq -0x20024(%rbp),%rax
movsbl -0x10010(%rbp,%rax,1),%edx
ff
movslq -0x20024(%rbp),%rax
movsbl -0x20010(%rbp,%rax,1),%ecx
ff
lea    0xa94(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
jmp    160c <main+0x49c>
mov    -0x20024(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20024(%rbp)
jmp    1593 <main+0x423>
cmpl   $0x1,-0x2001c(%rbp)
je     163d <main+0x4cd>
cmpl   $0xa000,-0x2002c(%rbp)
je     1650 <main+0x4e0>
lea    0xa76(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
jmp    165e <main+0x4ee>
lea    0xa6c(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
jmp    1663 <main+0x4f3>
mov    -0x4(%rbp),%eax
add    $0x20040,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x20018,%rsp
lea    0x8(%rsp),%rdi
call   1060 <pipe@plt>
test   %eax,%eax
je     11aa <main+0x2a>
lea    0xe5d(%rip),%rsi
xor    %edi,%edi
call   1080 <err@plt>
movb   $0x41,0x10(%rsp)
mov    $0x41,%dl
mov    $0x2,%eax
mov    $0x41,%ecx
nopl   0x0(%rax,%rax,1)
add    $0x1,%dl
cmp    $0x5b,%dl
movzbl %dl,%edx
cmovge %ecx,%edx
mov    %dl,0xf(%rsp,%rax,1)
add    $0x1,%dl
cmp    $0x5b,%dl
movzbl %dl,%edx
cmovge %ecx,%edx
mov    %dl,0x10(%rsp,%rax,1)
add    $0x2,%rax
cmp    $0x10000,%rax
jne    11c0 <main+0x40>
xor    %eax,%eax
call   1090 <fork@plt>
test   %rax,%rax
je     12e8 <main+0x168>
mov    $0x7a120,%edi
call   10a0 <usleep@plt>
mov    0xc(%rsp),%edi
lea    0x10010(%rsp),%rsi
mov    $0x8000,%edx
xor    %eax,%eax
call   1070 <read@plt>
mov    %eax,%ebx
lea    0xe34(%rip),%rdi
mov    %eax,%esi
xor    %eax,%eax
call   1050 <printf@plt>
mov    $0xf4240,%edi
call   10a0 <usleep@plt>
mov    0xc(%rsp),%edi
movslq %ebx,%r15
lea    (%rsp,%r15,1),%rsi
add    $0x10010,%rsi
mov    $0x2000,%edx
xor    %eax,%eax
call   1070 <read@plt>
add    %eax,%r15d
lea    0xe1d(%rip),%rdi
mov    %eax,%esi
xor    %eax,%eax
call   1050 <printf@plt>
test   %r15d,%r15d
jle    12d7 <main+0x157>
mov    %r15d,%r12d
add    $0xffffffffffffffff,%r12
mov    $0x41,%dl
lea    0xe14(%rip),%r14
xor    %ebx,%ebx
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movsbl 0x10010(%rsp,%rbx,1),%ecx
cmp    %cl,%dl
je     12b0 <main+0x130>
movsbl %dl,%edx
mov    %r14,%rdi
mov    %ebx,%esi
xor    %eax,%eax
call   1050 <printf@plt>
mov    $0x1,%eax
cmp    %rbx,%r12
je     12c0 <main+0x140>
movzbl 0x11(%rsp,%rbx,1),%edx
add    $0x1,%rbx
jmp    1290 <main+0x110>
cmp    $0x1,%eax
je     12d7 <main+0x157>
cmp    $0xa000,%r15d
jne    12d7 <main+0x157>
lea    0xde5(%rip),%rdi
jmp    12de <main+0x15e>
lea    0xde4(%rip),%rdi
call   1030 <puts@plt>
jmp    142c <main+0x2ac>
mov    0x8(%rsp),%edi
lea    0x10(%rsp),%rsi
mov    $0x1000,%edx
xor    %eax,%eax
call   1040 <write@plt>
mov    0x8(%rsp),%edi
movslq %eax,%rbx
lea    (%rsp,%rbx,1),%rsi
add    $0x10,%rsi
mov    $0x1000,%edx
xor    %eax,%eax
call   1040 <write@plt>
add    %eax,%ebx
mov    0x8(%rsp),%edi
movslq %ebx,%rbx
lea    (%rsp,%rbx,1),%rsi
add    $0x10,%rsi
mov    $0x1000,%edx
xor    %eax,%eax
call   1040 <write@plt>
add    %eax,%ebx
mov    0x8(%rsp),%edi
movslq %ebx,%rbx
lea    (%rsp,%rbx,1),%rsi
add    $0x10,%rsi
mov    $0x1000,%edx
xor    %eax,%eax
call   1040 <write@plt>
add    %eax,%ebx
mov    0x8(%rsp),%edi
movslq %ebx,%rbx
lea    (%rsp,%rbx,1),%rsi
add    $0x10,%rsi
mov    $0x1000,%edx
xor    %eax,%eax
call   1040 <write@plt>
add    %eax,%ebx
mov    0x8(%rsp),%edi
movslq %ebx,%rbx
lea    (%rsp,%rbx,1),%rsi
add    $0x10,%rsi
mov    $0x1000,%edx
xor    %eax,%eax
call   1040 <write@plt>
add    %eax,%ebx
mov    0x8(%rsp),%edi
movslq %ebx,%rbx
lea    (%rsp,%rbx,1),%rsi
add    $0x10,%rsi
mov    $0x1000,%edx
xor    %eax,%eax
call   1040 <write@plt>
add    %eax,%ebx
mov    0x8(%rsp),%edi
movslq %ebx,%rbx
lea    (%rsp,%rbx,1),%rsi
add    $0x10,%rsi
mov    $0x1000,%edx
xor    %eax,%eax
call   1040 <write@plt>
add    %eax,%ebx
lea    0xc48(%rip),%rdi
mov    %ebx,%esi
xor    %eax,%eax
call   1050 <printf@plt>
mov    $0xf4240,%edi
call   10a0 <usleep@plt>
mov    0x8(%rsp),%edi
movslq %ebx,%rbx
lea    (%rsp,%rbx,1),%rsi
add    $0x10,%rsi
mov    $0x1000,%edx
xor    %eax,%eax
call   1040 <write@plt>
add    %eax,%ebx
mov    0x8(%rsp),%edi
movslq %ebx,%rbx
lea    (%rsp,%rbx,1),%rsi
add    $0x10,%rsi
mov    $0x1000,%edx
xor    %eax,%eax
call   1040 <write@plt>
add    %eax,%ebx
lea    0xc0e(%rip),%rdi
mov    %ebx,%esi
xor    %eax,%eax
call   1050 <printf@plt>
xor    %eax,%eax
add    $0x20018,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
%struct.stat = type { i32 }
@.str = [23 x i8] c"Couldn't allocate fds\0A\00"
@.str.1 = [26 x i8] c"Wrote %d bytes, sleeping\0A\00"
@.str.2 = [42 x i8] c"Wrote another 8192 bytes, %d total, done\0A\00"
@.str.3 = [36 x i8] c"Read %d bytes, going back to sleep\0A\00"
@.str.4 = [21 x i8] c"Read %d bytes, done\0A\00"
@.str.5 = [38 x i8] c"Location %d input: %hhx output: %hhx\0A\00"
@.str.6 = [9 x i8] c"FAILURE\0A\00"
@.str.7 = [9 x i8] c"SUCCESS\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca [65535 x i8]
%3 = alloca [65535 x i8]
%4 = alloca [2 x i32]
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca %struct.stat
%11 = alloca i64
store i32 0, i32* %1
store i32 0, i32* %5
store i32 0, i32* %9
%12 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%13 = call i32 @pipe(i32* %12)
store i32 %13, i32* %6
%14 = load i32, i32* %6
%15 = icmp ne i32 %14, 0
br i1 %15, label %16, label %18
16: ; preds = %0
%17 = call i32 @err(i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i64 0, i64 0))
br label %18
18: ; preds = %16, %0
%19 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 0
store i8 65, i8* %19
store i32 1, i32* %7
br label %20
20: ; preds = %46, %18
%21 = load i32, i32* %7
%22 = icmp slt i32 %21, 65535
br i1 %22, label %23, label %49
23: ; preds = %20
%24 = load i32, i32* %7
%25 = sub nsw i32 %24, 1
%26 = sext i32 %25 to i64
%27 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %26
%28 = load i8, i8* %27
%29 = sext i8 %28 to i32
%30 = add nsw i32 %29, 1
%31 = trunc i32 %30 to i8
%32 = load i32, i32* %7
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %33
store i8 %31, i8* %34
%35 = load i32, i32* %7
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %36
%38 = load i8, i8* %37
%39 = sext i8 %38 to i32
%40 = icmp sgt i32 %39, 90
br i1 %40, label %41, label %45
41: ; preds = %23
%42 = load i32, i32* %7
%43 = sext i32 %42 to i64
%44 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %43
store i8 65, i8* %44
br label %45
45: ; preds = %41, %23
br label %46
46: ; preds = %45
%47 = load i32, i32* %7
%48 = add nsw i32 %47, 1
store i32 %48, i32* %7
br label %20
49: ; preds = %20
%50 = call i64 (...) @fork()
store i64 %50, i64* %11
%51 = load i64, i64* %11
%52 = icmp eq i64 %51, 0
br i1 %52, label %53, label %146
53: ; preds = %49
%54 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%55 = load i32, i32* %54
%56 = call i32 (i32, ...) @write(i32 %55, [65535 x i8]* %2, i32 4096)
store i32 %56, i32* %6
%57 = load i32, i32* %6
%58 = load i32, i32* %9
%59 = add nsw i32 %58, %57
store i32 %59, i32* %9
%60 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%61 = load i32, i32* %60
%62 = load i32, i32* %9
%63 = sext i32 %62 to i64
%64 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %63
%65 = call i32 (i32, ...) @write(i32 %61, i8* %64, i32 4096)
store i32 %65, i32* %6
%66 = load i32, i32* %6
%67 = load i32, i32* %9
%68 = add nsw i32 %67, %66
store i32 %68, i32* %9
%69 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%70 = load i32, i32* %69
%71 = load i32, i32* %9
%72 = sext i32 %71 to i64
%73 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %72
%74 = call i32 (i32, ...) @write(i32 %70, i8* %73, i32 4096)
store i32 %74, i32* %6
%75 = load i32, i32* %6
%76 = load i32, i32* %9
%77 = add nsw i32 %76, %75
store i32 %77, i32* %9
%78 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%79 = load i32, i32* %78
%80 = load i32, i32* %9
%81 = sext i32 %80 to i64
%82 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %81
%83 = call i32 (i32, ...) @write(i32 %79, i8* %82, i32 4096)
store i32 %83, i32* %6
%84 = load i32, i32* %6
%85 = load i32, i32* %9
%86 = add nsw i32 %85, %84
store i32 %86, i32* %9
%87 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%88 = load i32, i32* %87
%89 = load i32, i32* %9
%90 = sext i32 %89 to i64
%91 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %90
%92 = call i32 (i32, ...) @write(i32 %88, i8* %91, i32 4096)
store i32 %92, i32* %6
%93 = load i32, i32* %6
%94 = load i32, i32* %9
%95 = add nsw i32 %94, %93
store i32 %95, i32* %9
%96 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%97 = load i32, i32* %96
%98 = load i32, i32* %9
%99 = sext i32 %98 to i64
%100 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %99
%101 = call i32 (i32, ...) @write(i32 %97, i8* %100, i32 4096)
store i32 %101, i32* %6
%102 = load i32, i32* %6
%103 = load i32, i32* %9
%104 = add nsw i32 %103, %102
store i32 %104, i32* %9
%105 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%106 = load i32, i32* %105
%107 = load i32, i32* %9
%108 = sext i32 %107 to i64
%109 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %108
%110 = call i32 (i32, ...) @write(i32 %106, i8* %109, i32 4096)
store i32 %110, i32* %6
%111 = load i32, i32* %6
%112 = load i32, i32* %9
%113 = add nsw i32 %112, %111
store i32 %113, i32* %9
%114 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%115 = load i32, i32* %114
%116 = load i32, i32* %9
%117 = sext i32 %116 to i64
%118 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %117
%119 = call i32 (i32, ...) @write(i32 %115, i8* %118, i32 4096)
store i32 %119, i32* %6
%120 = load i32, i32* %6
%121 = load i32, i32* %9
%122 = add nsw i32 %121, %120
store i32 %122, i32* %9
%123 = load i32, i32* %9
%124 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0), i32 %123)
%125 = call i32 @usleep(i32 1000000)
%126 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%127 = load i32, i32* %126
%128 = load i32, i32* %9
%129 = sext i32 %128 to i64
%130 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %129
%131 = call i32 (i32, ...) @write(i32 %127, i8* %130, i32 4096)
store i32 %131, i32* %6
%132 = load i32, i32* %6
%133 = load i32, i32* %9
%134 = add nsw i32 %133, %132
store i32 %134, i32* %9
%135 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
%136 = load i32, i32* %135
%137 = load i32, i32* %9
%138 = sext i32 %137 to i64
%139 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %138
%140 = call i32 (i32, ...) @write(i32 %136, i8* %139, i32 4096)
store i32 %140, i32* %6
%141 = load i32, i32* %6
%142 = load i32, i32* %9
%143 = add nsw i32 %142, %141
store i32 %143, i32* %9
%144 = load i32, i32* %9
%145 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([42 x i8], [42 x i8]* @.str.2, i64 0, i64 0), i32 %144)
br label %212
146: ; preds = %49
%147 = call i32 @usleep(i32 500000)
%148 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 1
%149 = load i32, i32* %148
%150 = call i32 (i32, ...) @read(i32 %149, [65535 x i8]* %3, i32 32768)
store i32 %150, i32* %6
%151 = load i32, i32* %6
%152 = load i32, i32* %9
%153 = add nsw i32 %152, %151
store i32 %153, i32* %9
%154 = load i32, i32* %6
%155 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([36 x i8], [36 x i8]* @.str.3, i64 0, i64 0), i32 %154)
%156 = call i32 @usleep(i32 1000000)
%157 = getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 1
%158 = load i32, i32* %157
%159 = load i32, i32* %9
%160 = sext i32 %159 to i64
%161 = getelementptr inbounds [65535 x i8], [65535 x i8]* %3, i64 0, i64 %160
%162 = call i32 (i32, ...) @read(i32 %158, i8* %161, i32 8192)
store i32 %162, i32* %6
%163 = load i32, i32* %6
%164 = load i32, i32* %9
%165 = add nsw i32 %164, %163
store i32 %165, i32* %9
%166 = load i32, i32* %6
%167 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0), i32 %166)
store i32 0, i32* %7
br label %168
168: ; preds = %198, %146
%169 = load i32, i32* %7
%170 = load i32, i32* %9
%171 = icmp slt i32 %169, %170
br i1 %171, label %172, label %201
172: ; preds = %168
%173 = load i32, i32* %7
%174 = sext i32 %173 to i64
%175 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %174
%176 = load i8, i8* %175
%177 = sext i8 %176 to i32
%178 = load i32, i32* %7
%179 = sext i32 %178 to i64
%180 = getelementptr inbounds [65535 x i8], [65535 x i8]* %3, i64 0, i64 %179
%181 = load i8, i8* %180
%182 = sext i8 %181 to i32
%183 = icmp ne i32 %177, %182
br i1 %183, label %184, label %197
184: ; preds = %172
store i32 1, i32* %5
%185 = load i32, i32* %7
%186 = load i32, i32* %7
%187 = sext i32 %186 to i64
%188 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %187
%189 = load i8, i8* %188
%190 = sext i8 %189 to i32
%191 = load i32, i32* %7
%192 = sext i32 %191 to i64
%193 = getelementptr inbounds [65535 x i8], [65535 x i8]* %3, i64 0, i64 %192
%194 = load i8, i8* %193
%195 = sext i8 %194 to i32
%196 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.5, i64 0, i64 0), i32 %185, i32 %190, i32 %195)
br label %197
197: ; preds = %184, %172
br label %198
198: ; preds = %197
%199 = load i32, i32* %7
%200 = add nsw i32 %199, 1
store i32 %200, i32* %7
br label %168
201: ; preds = %168
%202 = load i32, i32* %5
%203 = icmp eq i32 %202, 1
br i1 %203, label %207, label %204
204: ; preds = %201
%205 = load i32, i32* %9
%206 = icmp ne i32 %205, 40960
br i1 %206, label %207, label %209
207: ; preds = %204, %201
%208 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.6, i64 0, i64 0))
br label %211
209: ; preds = %204
%210 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.7, i64 0, i64 0))
br label %211
211: ; preds = %209, %207
br label %212
212: ; preds = %211, %53
%213 = load i32, i32* %1
ret i32 %213
}

LLVM IR (-O2):
@.str = [23 x i8] c"Couldn't allocate fds\0A\00"
@.str.1 = [26 x i8] c"Wrote %d bytes, sleeping\0A\00"
@.str.2 = [42 x i8] c"Wrote another 8192 bytes, %d total, done\0A\00"
@.str.3 = [36 x i8] c"Read %d bytes, going back to sleep\0A\00"
@.str.4 = [21 x i8] c"Read %d bytes, done\0A\00"
@.str.5 = [38 x i8] c"Location %d input: %hhx output: %hhx\0A\00"
@str = [8 x i8] c"SUCCESS\00"
@str.8 = [8 x i8] c"FAILURE\00"
define i32 @main() {
%1 = alloca [65535 x i8]
%2 = alloca [65535 x i8]
%3 = alloca [2 x i32]
%4 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 0
%5 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 0
%6 = bitcast [2 x i32]* %3 to i8*
%7 = getelementptr inbounds [2 x i32], [2 x i32]* %3, i64 0, i64 0
%8 = call i32 @pipe(i32* %7)
%9 = icmp eq i32 %8, 0
br i1 %9, label %12, label %10
10: ; preds = %0
%11 = call i32 @err(i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i64 0, i64 0))
br label %12
12: ; preds = %10, %0
store i8 65, i8* %4
br label %13
13: ; preds = %13, %12
%14 = phi i8 [ 65, %12 ], [ %24, %13 ]
%15 = phi i64 [ 1, %12 ], [ %25, %13 ]
%16 = add i8 %14, 1
%17 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %15
%18 = icmp sgt i8 %16, 90
%19 = select i1 %18, i8 65, i8 %16
store i8 %19, i8* %17
%20 = add nuw nsw i64 %15, 1
%21 = add i8 %19, 1
%22 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %20
%23 = icmp sgt i8 %21, 90
%24 = select i1 %23, i8 65, i8 %21
store i8 %24, i8* %22
%25 = add nuw nsw i64 %15, 2
%26 = icmp eq i64 %25, 65535
br i1 %26, label %27, label %13
27: ; preds = %13
%28 = call i64 (...) @fork()
%29 = icmp eq i64 %28, 0
br i1 %29, label %30, label %81
30: ; preds = %27
%31 = load i32, i32* %7
%32 = call i32 (i32, ...) @write(i32 %31, [65535 x i8]* %1, i32 4096)
%33 = load i32, i32* %7
%34 = sext i32 %32 to i64
%35 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %34
%36 = call i32 (i32, ...) @write(i32 %33, i8* %35, i32 4096)
%37 = add nsw i32 %36, %32
%38 = load i32, i32* %7
%39 = sext i32 %37 to i64
%40 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %39
%41 = call i32 (i32, ...) @write(i32 %38, i8* %40, i32 4096)
%42 = add nsw i32 %41, %37
%43 = load i32, i32* %7
%44 = sext i32 %42 to i64
%45 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %44
%46 = call i32 (i32, ...) @write(i32 %43, i8* %45, i32 4096)
%47 = add nsw i32 %46, %42
%48 = load i32, i32* %7
%49 = sext i32 %47 to i64
%50 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %49
%51 = call i32 (i32, ...) @write(i32 %48, i8* %50, i32 4096)
%52 = add nsw i32 %51, %47
%53 = load i32, i32* %7
%54 = sext i32 %52 to i64
%55 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %54
%56 = call i32 (i32, ...) @write(i32 %53, i8* %55, i32 4096)
%57 = add nsw i32 %56, %52
%58 = load i32, i32* %7
%59 = sext i32 %57 to i64
%60 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %59
%61 = call i32 (i32, ...) @write(i32 %58, i8* %60, i32 4096)
%62 = add nsw i32 %61, %57
%63 = load i32, i32* %7
%64 = sext i32 %62 to i64
%65 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %64
%66 = call i32 (i32, ...) @write(i32 %63, i8* %65, i32 4096)
%67 = add nsw i32 %66, %62
%68 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0), i32 %67)
%69 = call i32 @usleep(i32 1000000)
%70 = load i32, i32* %7
%71 = sext i32 %67 to i64
%72 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %71
%73 = call i32 (i32, ...) @write(i32 %70, i8* %72, i32 4096)
%74 = add nsw i32 %73, %67
%75 = load i32, i32* %7
%76 = sext i32 %74 to i64
%77 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %76
%78 = call i32 (i32, ...) @write(i32 %75, i8* %77, i32 4096)
%79 = add nsw i32 %78, %74
%80 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([42 x i8], [42 x i8]* @.str.2, i64 0, i64 0), i32 %79)
br label %124
81: ; preds = %27
%82 = call i32 @usleep(i32 500000)
%83 = getelementptr inbounds [2 x i32], [2 x i32]* %3, i64 0, i64 1
%84 = load i32, i32* %83
%85 = call i32 (i32, ...) @read(i32 %84, [65535 x i8]* %2, i32 32768)
%86 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([36 x i8], [36 x i8]* @.str.3, i64 0, i64 0), i32 %85)
%87 = call i32 @usleep(i32 1000000)
%88 = load i32, i32* %83
%89 = sext i32 %85 to i64
%90 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %89
%91 = call i32 (i32, ...) @read(i32 %88, i8* %90, i32 8192)
%92 = add i32 %91, %85
%93 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0), i32 %91)
%94 = icmp sgt i32 %92, 0
br i1 %94, label %95, label %120
95: ; preds = %81
%96 = zext i32 %92 to i64
br label %97
97: ; preds = %113, %95
%98 = phi i8 [ 65, %95 ], [ %115, %113 ]
%99 = phi i64 [ 0, %95 ], [ %111, %113 ]
%100 = phi i32 [ 0, %95 ], [ %110, %113 ]
%101 = getelementptr inbounds [65535 x i8], [65535 x i8]* %2, i64 0, i64 %99
%102 = load i8, i8* %101
%103 = icmp eq i8 %98, %102
br i1 %103, label %109, label %104
104: ; preds = %97
%105 = sext i8 %102 to i32
%106 = sext i8 %98 to i32
%107 = trunc i64 %99 to i32
%108 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([38 x i8], [38 x i8]* @.str.5, i64 0, i64 0), i32 %107, i32 %106, i32 %105)
br label %109
109: ; preds = %97, %104
%110 = phi i32 [ 1, %104 ], [ %100, %97 ]
%111 = add nuw nsw i64 %99, 1
%112 = icmp eq i64 %111, %96
br i1 %112, label %116, label %113
113: ; preds = %109
%114 = getelementptr inbounds [65535 x i8], [65535 x i8]* %1, i64 0, i64 %111
%115 = load i8, i8* %114
br label %97
116: ; preds = %109
%117 = icmp eq i32 %110, 1
%118 = icmp ne i32 %92, 40960
%119 = or i1 %117, %118
br i1 %119, label %120, label %122
120: ; preds = %81, %116
%121 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @str.8, i64 0, i64 0))
br label %124
122: ; preds = %116
%123 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @str, i64 0, i64 0))
br label %124
124: ; preds = %120, %122, %30
ret i32 0
}