#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 {
  scalar_t__ st_size;
};
typedef scalar_t__ off_t;

/* Variables and functions */
char *MAP_FAILED;
int /*<<< orphan*/ MAP_SHARED;
int O_CREAT;
int O_EXCL;
int /*<<< orphan*/ O_RDONLY;
int O_RDWR;
int PROT_READ;
int PROT_WRITE;
char **alloca(int);
int /*<<< orphan*/ close(int);
int /*<<< orphan*/ errno;
int /*<<< orphan*/ exit(int);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, ...);
scalar_t__ fstat(int, struct stat *);
scalar_t__ ftruncate(int, scalar_t__);
char *mmap(int /*<<< orphan*/ *, scalar_t__, int, int /*<<< orphan*/, int,
           int /*<<< orphan*/);
int open(char *, int, ...);
int /*<<< orphan*/ perror(char *);
int /*<<< orphan*/ stderr;
char *strerror(int /*<<< orphan*/);
int main(int argc, char **argv) {
  if (argc < 3) {
    fprintf(stderr, "give me at least one input and one output file!\n");
    exit(1);
  }
  char *outpath = argv[1];
  char **inpaths = argv + 2;
  int inpaths_len = argc - 2;
  char **infiles = alloca(sizeof(char *) * inpaths_len);
  off_t file_size = 0;
  for (int i = 0; i < inpaths_len; i++) {
    char *path = inpaths[i];
    struct stat st;
    int fd = open(path, O_RDONLY);
    if (fd == -1) {
      fprintf(stderr, "can't open input file \"%s\": %s\n", path,
              strerror(errno));
      exit(1);
    }
    if (fstat(fd, &st)) {
      fprintf(stderr, "can't stat input fd for file \"%s\": %s\n", path,
              strerror(errno));
      exit(1);
    }
    if (i == 0) {
      file_size = st.st_size;
    } else {
      if (file_size != st.st_size) {
        fprintf(
            stderr,
            "size mismatch between input files \"%s\" and \"%s\", aborting!\n",
            inpaths[0], path);
        exit(1);
      }
    }
    infiles[i] = mmap(NULL, file_size, PROT_READ, MAP_SHARED, fd, 0);
    if (infiles[i] == MAP_FAILED) {
      fprintf(stderr, "can't mmap \"%s\": %s\n", path, strerror(errno));
      exit(1);
    }
    close(fd);
  }
  int out_fd = open(outpath, O_RDWR | O_CREAT | O_EXCL, 0777);
  if (out_fd == -1) {
    perror("can't open outfile");
    exit(1);
  }
  if (ftruncate(out_fd, file_size)) {
    perror("can't allocate disk space for outfile");
    exit(1);
  }
  char *outfile =
      mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, out_fd, 0);
  if (outfile == MAP_FAILED) {
    perror("can't mmap outfile");
    exit(1);
  }
  close(out_fd);
  for (off_t i = 0; i < file_size; i++) {
    char *outc = outfile + i;
    for (int j = 0; j < inpaths_len; j++) {
      char inc = infiles[j][i];
      if (*outc != 0 && inc != 0 && *outc != inc) {
        fprintf(stderr, "input file integrity is bad, this won't work\n");
        exit(1);
      }
      if (inc != 0)
        *outc = inc;
    }
  }
  fprintf(stderr, "looks good ☺\n");
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0xb0,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
cmpl   $0x3,-0x8(%rbp)
jge    11e4 <main+0x44>
mov    0x2dee(%rip),%rax
mov    (%rax),%edi
lea    0xe2d(%rip),%rsi
mov    $0x0,%al
call   1060 <fprintf@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
add    $0x10,%rax
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%eax
sub    $0x2,%eax
mov    %eax,-0x24(%rbp)
movslq -0x24(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1070 <alloca@plt>
mov    %rax,-0x30(%rbp)
movq   $0x0,-0x38(%rbp)
movl   $0x0,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    1421 <main+0x281>
mov    -0x20(%rbp),%rax
movslq -0x3c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rdi
mov    0x2d7a(%rip),%rax
mov    (%rax),%esi
mov    $0x0,%al
call   1080 <open@plt>
mov    %eax,-0x54(%rbp)
cmpl   $0xffffffff,-0x54(%rbp)
jne    12ae <main+0x10e>
mov    0x2d4d(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x84(%rbp)
mov    -0x48(%rbp),%rax
mov    %rax,-0x80(%rbp)
mov    0x2d26(%rip),%rax
mov    (%rax),%edi
call   10b0 <strerror@plt>
mov    -0x84(%rbp),%edi
mov    -0x80(%rbp),%rdx
mov    %rax,%rcx
lea    0xd94(%rip),%rsi
mov    $0x0,%al
call   1060 <fprintf@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
mov    -0x54(%rbp),%edi
lea    -0x50(%rbp),%rsi
call   10c0 <fstat@plt>
cmp    $0x0,%rax
je     1314 <main+0x174>
mov    0x2ced(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x94(%rbp)
mov    -0x48(%rbp),%rax
mov    %rax,-0x90(%rbp)
mov    0x2cc3(%rip),%rax
mov    (%rax),%edi
call   10b0 <strerror@plt>
mov    -0x94(%rbp),%edi
mov    -0x90(%rbp),%rdx
mov    %rax,%rcx
lea    0xd4e(%rip),%rsi
mov    $0x0,%al
call   1060 <fprintf@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
cmpl   $0x0,-0x3c(%rbp)
jne    132b <main+0x18b>
mov    -0x50(%rbp),%rax
mov    %rax,-0x38(%rbp)
jmp    136a <main+0x1ca>
mov    -0x38(%rbp),%rax
cmp    -0x50(%rbp),%rax
je     1365 <main+0x1c5>
mov    0x2c78(%rip),%rax
mov    (%rax),%edi
mov    -0x20(%rbp),%rax
mov    (%rax),%rdx
mov    -0x48(%rbp),%rcx
lea    0xd24(%rip),%rsi
mov    $0x0,%al
call   1060 <fprintf@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
jmp    136a <main+0x1ca>
mov    -0x38(%rbp),%rsi
mov    0x2c7b(%rip),%rax
mov    (%rax),%edx
mov    0x2c62(%rip),%rax
mov    (%rax),%ecx
mov    -0x54(%rbp),%r8d
xor    %eax,%eax
mov    %eax,%edi
xor    %r9d,%r9d
call   1030 <mmap@plt>
mov    %rax,%rdx
mov    -0x30(%rbp),%rax
movslq -0x3c(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x30(%rbp),%rax
movslq -0x3c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    0x2be6(%rip),%rcx
cmp    (%rcx),%rax
jne    140b <main+0x26b>
mov    0x2bf6(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0xa4(%rbp)
mov    -0x48(%rbp),%rax
mov    %rax,-0xa0(%rbp)
mov    0x2bcc(%rip),%rax
mov    (%rax),%edi
call   10b0 <strerror@plt>
mov    -0xa4(%rbp),%edi
mov    -0xa0(%rbp),%rdx
mov    %rax,%rcx
lea    0xcba(%rip),%rsi
mov    $0x0,%al
call   1060 <fprintf@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
mov    -0x54(%rbp),%edi
call   1050 <close@plt>
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    1227 <main+0x87>
mov    -0x18(%rbp),%rdi
mov    0x2ba4(%rip),%rax
mov    (%rax),%esi
mov    0x2bc3(%rip),%rax
or     (%rax),%esi
mov    0x2b72(%rip),%rax
or     (%rax),%esi
mov    $0x1ff,%edx
mov    $0x0,%al
call   1080 <open@plt>
mov    %eax,-0x58(%rbp)
cmpl   $0xffffffff,-0x58(%rbp)
jne    146f <main+0x2cf>
lea    0xc69(%rip),%rdi
call   1090 <perror@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
mov    -0x58(%rbp),%edi
mov    -0x38(%rbp),%rsi
call   1040 <ftruncate@plt>
cmp    $0x0,%rax
je     149b <main+0x2fb>
lea    0xc50(%rip),%rdi
call   1090 <perror@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
mov    -0x38(%rbp),%rsi
mov    0x2b4a(%rip),%rax
mov    (%rax),%edx
mov    0x2af1(%rip),%rax
or     (%rax),%edx
mov    0x2b28(%rip),%rax
mov    (%rax),%ecx
mov    -0x58(%rbp),%r8d
xor    %eax,%eax
mov    %eax,%edi
xor    %r9d,%r9d
call   1030 <mmap@plt>
mov    %rax,-0x60(%rbp)
mov    -0x60(%rbp),%rax
mov    0x2abf(%rip),%rcx
cmp    (%rcx),%rax
jne    14f8 <main+0x358>
lea    0xc19(%rip),%rdi
call   1090 <perror@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
mov    -0x58(%rbp),%edi
call   1050 <close@plt>
movq   $0x0,-0x68(%rbp)
mov    -0x68(%rbp),%rax
cmp    -0x38(%rbp),%rax
jge    15db <main+0x43b>
mov    -0x60(%rbp),%rax
add    -0x68(%rbp),%rax
mov    %rax,-0x70(%rbp)
movl   $0x0,-0x74(%rbp)
mov    -0x74(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    15c5 <main+0x425>
mov    -0x30(%rbp),%rax
movslq -0x74(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x68(%rbp),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x75(%rbp)
mov    -0x70(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
je     159c <main+0x3fc>
movsbl -0x75(%rbp),%eax
cmp    $0x0,%eax
je     159c <main+0x3fc>
mov    -0x70(%rbp),%rax
movsbl (%rax),%eax
movsbl -0x75(%rbp),%ecx
cmp    %ecx,%eax
je     159c <main+0x3fc>
mov    0x2a36(%rip),%rax
mov    (%rax),%edi
lea    0xb8a(%rip),%rsi
mov    $0x0,%al
call   1060 <fprintf@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
movsbl -0x75(%rbp),%eax
cmp    $0x0,%eax
je     15b2 <main+0x412>
mov    -0x75(%rbp),%cl
mov    -0x70(%rbp),%rax
mov    %cl,(%rax)
jmp    15b7 <main+0x417>
mov    -0x74(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x74(%rbp)
jmp    1529 <main+0x389>
jmp    15ca <main+0x42a>
mov    -0x68(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x68(%rbp)
jmp    1508 <main+0x368>
mov    0x29d6(%rip),%rax
mov    (%rax),%edi
lea    0xb58(%rip),%rsi
mov    $0x0,%al
call   1060 <fprintf@plt>
mov    -0x4(%rbp),%eax
add    $0xb0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
cmp    $0x2,%edi
jle    14e7 <main+0x347>
mov    %rsi,%rbp
mov    0x8(%rsi),%rbx
mov    %rdi,0x8(%rsp)
lea    -0x10(,%rdi,8),%edi
call   1070 <alloca@plt>
mov    %rax,%r15
mov    0x10(%rbp),%r12
mov    0x2deb(%rip),%rax
mov    (%rax),%esi
mov    %r12,%rdi
xor    %eax,%eax
call   1080 <open@plt>
cmp    $0xffffffff,%eax
je     1452 <main+0x2b2>
mov    %eax,%r14d
mov    %rbp,0x10(%rsp)
mov    %rbx,0x18(%rsp)
mov    %rsp,%rsi
mov    %eax,%edi
call   10c0 <fstat@plt>
test   %rax,%rax
jne    1472 <main+0x2d2>
mov    (%rsp),%rsi
mov    0x2dd3(%rip),%rax
mov    (%rax),%edx
mov    0x2dba(%rip),%rax
mov    (%rax),%ecx
xor    %edi,%edi
mov    %rsi,%rbx
mov    %r14d,%r8d
xor    %r9d,%r9d
call   1030 <mmap@plt>
mov    %rax,(%r15)
mov    0x2d56(%rip),%rcx
cmp    (%rcx),%rax
je     1492 <main+0x2f2>
mov    0x8(%rsp),%rax
lea    -0x2(%rax),%r13d
mov    %r14d,%edi
call   1050 <close@plt>
cmp    $0x1,%r13d
je     1314 <main+0x174>
lea    -0x1(%r13),%rax
mov    %rax,0x20(%rsp)
xor    %ebp,%ebp
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    0x10(%rsp),%rax
mov    0x18(%rax,%rbp,8),%r12
mov    0x2d37(%rip),%rax
mov    (%rax),%esi
mov    %r12,%rdi
xor    %eax,%eax
call   1080 <open@plt>
cmp    $0xffffffff,%eax
je     1452 <main+0x2b2>
mov    %eax,%r14d
mov    %eax,%edi
mov    %rsp,%rsi
call   10c0 <fstat@plt>
test   %rax,%rax
jne    1472 <main+0x2d2>
cmp    (%rsp),%rbx
jne    14ba <main+0x31a>
mov    %rbx,%rsi
mov    0x2d20(%rip),%rax
mov    (%rax),%edx
mov    0x2d07(%rip),%rax
mov    (%rax),%ecx
xor    %edi,%edi
mov    %r14d,%r8d
xor    %r9d,%r9d
call   1030 <mmap@plt>
mov    %rax,0x8(%r15,%rbp,8)
mov    0x2ca4(%rip),%rcx
cmp    (%rcx),%rax
je     1492 <main+0x2f2>
mov    %r14d,%edi
call   1050 <close@plt>
add    $0x1,%rbp
cmp    %rbp,0x20(%rsp)
jne    1280 <main+0xe0>
mov    0x2cb5(%rip),%rax
mov    0x2cd6(%rip),%rcx
mov    (%rcx),%esi
or     (%rax),%esi
mov    0x2c83(%rip),%rax
or     (%rax),%esi
mov    0x18(%rsp),%rdi
mov    $0x1ff,%edx
xor    %eax,%eax
call   1080 <open@plt>
cmp    $0xffffffff,%eax
je     14fc <main+0x35c>
mov    %eax,%r12d
mov    %eax,%edi
mov    %rbx,%rsi
call   1040 <ftruncate@plt>
test   %rax,%rax
jne    1505 <main+0x365>
mov    0x2c3a(%rip),%rax
mov    (%rax),%edx
mov    0x2c81(%rip),%rax
or     (%rax),%edx
mov    0x2c68(%rip),%rax
mov    (%rax),%ecx
xor    %edi,%edi
mov    %rbx,%rsi
mov    %r12d,%r8d
xor    %r9d,%r9d
call   1030 <mmap@plt>
mov    %rax,%rbp
mov    0x2c04(%rip),%rax
cmp    (%rax),%rbp
je     150e <main+0x36e>
mov    %r12d,%edi
call   1050 <close@plt>
test   %rbx,%rbx
mov    0x8(%rsp),%rsi
jle    1409 <main+0x269>
mov    %rbx,%rdi
xor    %eax,%eax
jmp    13c9 <main+0x229>
cs nopw 0x0(%rax,%rax,1)
add    $0x1,%rax
cmp    %rdi,%rax
je     1409 <main+0x269>
cmp    $0x3,%esi
jl     13c0 <main+0x220>
mov    0x0(%rbp,%rax,1),%bl
xor    %edx,%edx
jmp    13e9 <main+0x249>
cs nopw 0x0(%rax,%rax,1)
add    $0x1,%rdx
cmp    %rdx,%r13
je     13c0 <main+0x220>
mov    (%r15,%rdx,8),%rcx
movzbl (%rcx,%rax,1),%ecx
test   %bl,%bl
je     13fd <main+0x25d>
test   %cl,%cl
je     13fd <main+0x25d>
cmp    %cl,%bl
jne    1431 <main+0x291>
test   %cl,%cl
je     13e0 <main+0x240>
mov    %cl,0x0(%rbp,%rax,1)
mov    %ecx,%ebx
jmp    13e0 <main+0x240>
mov    0x2ba8(%rip),%rax
mov    (%rax),%edi
lea    0xd2a(%rip),%rsi
xor    %eax,%eax
call   1060 <fprintf@plt>
xor    %eax,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    0x2b80(%rip),%rax
mov    (%rax),%edi
lea    0xcd4(%rip),%rsi
xor    %eax,%eax
call   1060 <fprintf@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
mov    0x2b5f(%rip),%rax
mov    (%rax),%ebx
mov    0x2b46(%rip),%rax
mov    (%rax),%edi
call   10b0 <strerror@plt>
lea    0xbc1(%rip),%rsi
jmp    14b0 <main+0x310>
mov    0x2b3f(%rip),%rax
mov    (%rax),%ebx
mov    0x2b26(%rip),%rax
mov    (%rax),%edi
call   10b0 <strerror@plt>
lea    0xbc1(%rip),%rsi
jmp    14b0 <main+0x310>
mov    0x2b1f(%rip),%rax
mov    (%rax),%ebx
mov    0x2b06(%rip),%rax
mov    (%rax),%edi
call   10b0 <strerror@plt>
lea    0xc04(%rip),%rsi
mov    %ebx,%edi
mov    %r12,%rdx
mov    %rax,%rcx
jmp    14d6 <main+0x336>
mov    0x2af7(%rip),%rax
mov    (%rax),%edi
mov    0x10(%rsp),%rax
mov    0x10(%rax),%rdx
lea    0xba5(%rip),%rsi
mov    %r12,%rcx
xor    %eax,%eax
call   1060 <fprintf@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
mov    0x2aca(%rip),%rax
mov    (%rax),%edi
lea    0xb09(%rip),%rsi
jmp    1441 <main+0x2a1>
lea    0xbc6(%rip),%rdi
jmp    1515 <main+0x375>
lea    0xbd0(%rip),%rdi
jmp    1515 <main+0x375>
lea    0xbed(%rip),%rdi
call   1090 <perror@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>

LLVM IR (-O0):
%struct.stat = type { i64 }
@stderr = global i32 0
@.str = [49 x i8] c"give me at least one input and one output file!\0A\00"
@O_RDONLY = global i32 0
@.str.1 = [32 x i8] c"can't open input file \22%s\22: %s\0A\00"
@errno = global i32 0
@.str.2 = [39 x i8] c"can't stat input fd for file \22%s\22: %s\0A\00"
@.str.3 = [60 x i8] c"size mismatch between input files \22%s\22 and \22%s\22, aborting!\0A\00"
@PROT_READ = global i32 0
@MAP_SHARED = global i32 0
@MAP_FAILED = global i8* null
@.str.4 = [21 x i8] c"can't mmap \22%s\22: %s\0A\00"
@O_RDWR = global i32 0
@O_CREAT = global i32 0
@O_EXCL = global i32 0
@.str.5 = [19 x i8] c"can't open outfile\00"
@.str.6 = [38 x i8] c"can't allocate disk space for outfile\00"
@PROT_WRITE = global i32 0
@.str.7 = [19 x i8] c"can't mmap outfile\00"
@.str.8 = [46 x i8] c"input file integrity is bad, this won't work\0A\00"
@.str.9 = [16 x i8] c"looks good \E2\98\BA\0A\00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca i8*
%7 = alloca i8**
%8 = alloca i32
%9 = alloca i8**
%10 = alloca i64
%11 = alloca i32
%12 = alloca i8*
%13 = alloca %struct.stat
%14 = alloca i32
%15 = alloca i32
%16 = alloca i8*
%17 = alloca i64
%18 = alloca i8*
%19 = alloca i32
%20 = alloca i8
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%21 = load i32, i32* %4
%22 = icmp slt i32 %21, 3
br i1 %22, label %23, label %27
23: ; preds = %2
%24 = load i32, i32* @stderr
%25 = call i32 (i32, i8*, ...) @fprintf(i32 %24, i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str, i64 0, i64 0))
%26 = call i32 @exit(i32 1)
unreachable
27: ; preds = %2
%28 = load i8**, i8*** %5
%29 = getelementptr inbounds i8*, i8** %28, i64 1
%30 = load i8*, i8** %29
store i8* %30, i8** %6
%31 = load i8**, i8*** %5
%32 = getelementptr inbounds i8*, i8** %31, i64 2
store i8** %32, i8*** %7
%33 = load i32, i32* %4
%34 = sub nsw i32 %33, 2
store i32 %34, i32* %8
%35 = load i32, i32* %8
%36 = sext i32 %35 to i64
%37 = mul i64 8, %36
%38 = trunc i64 %37 to i32
%39 = call i8** @alloca(i32 %38)
store i8** %39, i8*** %9
store i64 0, i64* %10
store i32 0, i32* %11
br label %40
40: ; preds = %120, %27
%41 = load i32, i32* %11
%42 = load i32, i32* %8
%43 = icmp slt i32 %41, %42
br i1 %43, label %44, label %123
44: ; preds = %40
%45 = load i8**, i8*** %7
%46 = load i32, i32* %11
%47 = sext i32 %46 to i64
%48 = getelementptr inbounds i8*, i8** %45, i64 %47
%49 = load i8*, i8** %48
store i8* %49, i8** %12
%50 = load i8*, i8** %12
%51 = load i32, i32* @O_RDONLY
%52 = call i32 (i8*, i32, ...) @open(i8* %50, i32 %51)
store i32 %52, i32* %14
%53 = load i32, i32* %14
%54 = icmp eq i32 %53, -1
br i1 %54, label %55, label %62
55: ; preds = %44
%56 = load i32, i32* @stderr
%57 = load i8*, i8** %12
%58 = load i32, i32* @errno
%59 = call i8* @strerror(i32 %58)
%60 = call i32 (i32, i8*, ...) @fprintf(i32 %56, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @.str.1, i64 0, i64 0), i8* %57, i8* %59)
%61 = call i32 @exit(i32 1)
unreachable
62: ; preds = %44
%63 = load i32, i32* %14
%64 = call i64 @fstat(i32 %63, %struct.stat* %13)
%65 = icmp ne i64 %64, 0
br i1 %65, label %66, label %73
66: ; preds = %62
%67 = load i32, i32* @stderr
%68 = load i8*, i8** %12
%69 = load i32, i32* @errno
%70 = call i8* @strerror(i32 %69)
%71 = call i32 (i32, i8*, ...) @fprintf(i32 %67, i8* getelementptr inbounds ([39 x i8], [39 x i8]* @.str.2, i64 0, i64 0), i8* %68, i8* %70)
%72 = call i32 @exit(i32 1)
unreachable
73: ; preds = %62
%74 = load i32, i32* %11
%75 = icmp eq i32 %74, 0
br i1 %75, label %76, label %79
76: ; preds = %73
%77 = getelementptr inbounds %struct.stat, %struct.stat* %13, i32 0, i32 0
%78 = load i64, i64* %77
store i64 %78, i64* %10
br label %93
79: ; preds = %73
%80 = load i64, i64* %10
%81 = getelementptr inbounds %struct.stat, %struct.stat* %13, i32 0, i32 0
%82 = load i64, i64* %81
%83 = icmp ne i64 %80, %82
br i1 %83, label %84, label %92
84: ; preds = %79
%85 = load i32, i32* @stderr
%86 = load i8**, i8*** %7
%87 = getelementptr inbounds i8*, i8** %86, i64 0
%88 = load i8*, i8** %87
%89 = load i8*, i8** %12
%90 = call i32 (i32, i8*, ...) @fprintf(i32 %85, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @.str.3, i64 0, i64 0), i8* %88, i8* %89)
%91 = call i32 @exit(i32 1)
unreachable
92: ; preds = %79
br label %93
93: ; preds = %92, %76
%94 = load i64, i64* %10
%95 = load i32, i32* @PROT_READ
%96 = load i32, i32* @MAP_SHARED
%97 = load i32, i32* %14
%98 = call i8* @mmap(i32* null, i64 %94, i32 %95, i32 %96, i32 %97, i32 0)
%99 = load i8**, i8*** %9
%100 = load i32, i32* %11
%101 = sext i32 %100 to i64
%102 = getelementptr inbounds i8*, i8** %99, i64 %101
store i8* %98, i8** %102
%103 = load i8**, i8*** %9
%104 = load i32, i32* %11
%105 = sext i32 %104 to i64
%106 = getelementptr inbounds i8*, i8** %103, i64 %105
%107 = load i8*, i8** %106
%108 = load i8*, i8** @MAP_FAILED
%109 = icmp eq i8* %107, %108
br i1 %109, label %110, label %117
110: ; preds = %93
%111 = load i32, i32* @stderr
%112 = load i8*, i8** %12
%113 = load i32, i32* @errno
%114 = call i8* @strerror(i32 %113)
%115 = call i32 (i32, i8*, ...) @fprintf(i32 %111, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0), i8* %112, i8* %114)
%116 = call i32 @exit(i32 1)
unreachable
117: ; preds = %93
%118 = load i32, i32* %14
%119 = call i32 @close(i32 %118)
br label %120
120: ; preds = %117
%121 = load i32, i32* %11
%122 = add nsw i32 %121, 1
store i32 %122, i32* %11
br label %40
123: ; preds = %40
%124 = load i8*, i8** %6
%125 = load i32, i32* @O_RDWR
%126 = load i32, i32* @O_CREAT
%127 = or i32 %125, %126
%128 = load i32, i32* @O_EXCL
%129 = or i32 %127, %128
%130 = call i32 (i8*, i32, ...) @open(i8* %124, i32 %129, i32 511)
store i32 %130, i32* %15
%131 = load i32, i32* %15
%132 = icmp eq i32 %131, -1
br i1 %132, label %133, label %136
133: ; preds = %123
%134 = call i32 @perror(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.5, i64 0, i64 0))
%135 = call i32 @exit(i32 1)
unreachable
136: ; preds = %123
%137 = load i32, i32* %15
%138 = load i64, i64* %10
%139 = call i64 @ftruncate(i32 %137, i64 %138)
%140 = icmp ne i64 %139, 0
br i1 %140, label %141, label %144
141: ; preds = %136
%142 = call i32 @perror(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.6, i64 0, i64 0))
%143 = call i32 @exit(i32 1)
unreachable
144: ; preds = %136
%145 = load i64, i64* %10
%146 = load i32, i32* @PROT_READ
%147 = load i32, i32* @PROT_WRITE
%148 = or i32 %146, %147
%149 = load i32, i32* @MAP_SHARED
%150 = load i32, i32* %15
%151 = call i8* @mmap(i32* null, i64 %145, i32 %148, i32 %149, i32 %150, i32 0)
store i8* %151, i8** %16
%152 = load i8*, i8** %16
%153 = load i8*, i8** @MAP_FAILED
%154 = icmp eq i8* %152, %153
br i1 %154, label %155, label %158
155: ; preds = %144
%156 = call i32 @perror(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.7, i64 0, i64 0))
%157 = call i32 @exit(i32 1)
unreachable
158: ; preds = %144
%159 = load i32, i32* %15
%160 = call i32 @close(i32 %159)
store i64 0, i64* %17
br label %161
161: ; preds = %213, %158
%162 = load i64, i64* %17
%163 = load i64, i64* %10
%164 = icmp slt i64 %162, %163
br i1 %164, label %165, label %216
165: ; preds = %161
%166 = load i8*, i8** %16
%167 = load i64, i64* %17
%168 = getelementptr inbounds i8, i8* %166, i64 %167
store i8* %168, i8** %18
store i32 0, i32* %19
br label %169
169: ; preds = %209, %165
%170 = load i32, i32* %19
%171 = load i32, i32* %8
%172 = icmp slt i32 %170, %171
br i1 %172, label %173, label %212
173: ; preds = %169
%174 = load i8**, i8*** %9
%175 = load i32, i32* %19
%176 = sext i32 %175 to i64
%177 = getelementptr inbounds i8*, i8** %174, i64 %176
%178 = load i8*, i8** %177
%179 = load i64, i64* %17
%180 = getelementptr inbounds i8, i8* %178, i64 %179
%181 = load i8, i8* %180
store i8 %181, i8* %20
%182 = load i8*, i8** %18
%183 = load i8, i8* %182
%184 = sext i8 %183 to i32
%185 = icmp ne i32 %184, 0
br i1 %185, label %186, label %201
186: ; preds = %173
%187 = load i8, i8* %20
%188 = sext i8 %187 to i32
%189 = icmp ne i32 %188, 0
br i1 %189, label %190, label %201
190: ; preds = %186
%191 = load i8*, i8** %18
%192 = load i8, i8* %191
%193 = sext i8 %192 to i32
%194 = load i8, i8* %20
%195 = sext i8 %194 to i32
%196 = icmp ne i32 %193, %195
br i1 %196, label %197, label %201
197: ; preds = %190
%198 = load i32, i32* @stderr
%199 = call i32 (i32, i8*, ...) @fprintf(i32 %198, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @.str.8, i64 0, i64 0))
%200 = call i32 @exit(i32 1)
unreachable
201: ; preds = %190, %186, %173
%202 = load i8, i8* %20
%203 = sext i8 %202 to i32
%204 = icmp ne i32 %203, 0
br i1 %204, label %205, label %208
205: ; preds = %201
%206 = load i8, i8* %20
%207 = load i8*, i8** %18
store i8 %206, i8* %207
br label %208
208: ; preds = %205, %201
br label %209
209: ; preds = %208
%210 = load i32, i32* %19
%211 = add nsw i32 %210, 1
store i32 %211, i32* %19
br label %169
212: ; preds = %169
br label %213
213: ; preds = %212
%214 = load i64, i64* %17
%215 = add nsw i64 %214, 1
store i64 %215, i64* %17
br label %161
216: ; preds = %161
%217 = load i32, i32* @stderr
%218 = call i32 (i32, i8*, ...) @fprintf(i32 %217, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.9, i64 0, i64 0))
%219 = load i32, i32* %3
ret i32 %219
}

LLVM IR (-O2):
%struct.stat = type { i64 }
@stderr = global i32 0
@.str = [49 x i8] c"give me at least one input and one output file!\0A\00"
@O_RDONLY = global i32 0
@.str.1 = [32 x i8] c"can't open input file \22%s\22: %s\0A\00"
@errno = global i32 0
@.str.2 = [39 x i8] c"can't stat input fd for file \22%s\22: %s\0A\00"
@.str.3 = [60 x i8] c"size mismatch between input files \22%s\22 and \22%s\22, aborting!\0A\00"
@PROT_READ = global i32 0
@MAP_SHARED = global i32 0
@MAP_FAILED = global i8* null
@.str.4 = [21 x i8] c"can't mmap \22%s\22: %s\0A\00"
@O_RDWR = global i32 0
@O_CREAT = global i32 0
@O_EXCL = global i32 0
@.str.5 = [19 x i8] c"can't open outfile\00"
@.str.6 = [38 x i8] c"can't allocate disk space for outfile\00"
@PROT_WRITE = global i32 0
@.str.7 = [19 x i8] c"can't mmap outfile\00"
@.str.8 = [46 x i8] c"input file integrity is bad, this won't work\0A\00"
@.str.9 = [16 x i8] c"looks good \E2\98\BA\0A\00"
define i32 @main(i32 %0, i8** nocapture %1) {
%3 = alloca %struct.stat
%4 = icmp slt i32 %0, 3
br i1 %4, label %5, label %9
5: ; preds = %2
%6 = load i32, i32* @stderr
%7 = tail call i32 (i32, i8*, ...) @fprintf(i32 %6, i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str, i64 0, i64 0))
%8 = tail call i32 @exit(i32 1)
unreachable
9: ; preds = %2
%10 = getelementptr inbounds i8*, i8** %1, i64 1
%11 = load i8*, i8** %10
%12 = getelementptr inbounds i8*, i8** %1, i64 2
%13 = add nsw i32 %0, -2
%14 = shl i32 %13, 3
%15 = tail call i8** @alloca(i32 %14)
%16 = bitcast %struct.stat* %3 to i8*
%17 = getelementptr inbounds %struct.stat, %struct.stat* %3, i64 0, i32 0
%18 = zext i32 %13 to i64
%19 = load i8*, i8** %12
%20 = load i32, i32* @O_RDONLY
%21 = tail call i32 (i8*, i32, ...) @open(i8* %19, i32 %20)
%22 = icmp eq i32 %21, -1
br i1 %22, label %51, label %23
23: ; preds = %9
%24 = call i64 @fstat(i32 %21, %struct.stat* %3)
%25 = icmp eq i64 %24, 0
br i1 %25, label %26, label %61
26: ; preds = %23
%27 = load i64, i64* %17
%28 = load i32, i32* @PROT_READ
%29 = load i32, i32* @MAP_SHARED
%30 = tail call i8* @mmap(i32* null, i64 %27, i32 %28, i32 %29, i32 %21, i32 0)
store i8* %30, i8** %15
%31 = load i8*, i8** @MAP_FAILED
%32 = icmp eq i8* %30, %31
br i1 %32, label %83, label %33
33: ; preds = %26
%34 = tail call i32 @close(i32 %21)
%35 = icmp eq i32 %13, 1
br i1 %35, label %36, label %44
36: ; preds = %90, %33
%37 = load i32, i32* @O_RDWR
%38 = load i32, i32* @O_CREAT
%39 = or i32 %38, %37
%40 = load i32, i32* @O_EXCL
%41 = or i32 %39, %40
%42 = tail call i32 (i8*, i32, ...) @open(i8* %11, i32 %41, i32 511)
%43 = icmp eq i32 %42, -1
br i1 %43, label %94, label %97
44: ; preds = %33, %90
%45 = phi i64 [ %92, %90 ], [ 1, %33 ]
%46 = getelementptr inbounds i8*, i8** %12, i64 %45
%47 = load i8*, i8** %46
%48 = load i32, i32* @O_RDONLY
%49 = tail call i32 (i8*, i32, ...) @open(i8* %47, i32 %48)
%50 = icmp eq i32 %49, -1
br i1 %50, label %51, label %58
51: ; preds = %44, %9
%52 = phi i8* [ %19, %9 ], [ %47, %44 ]
%53 = load i32, i32* @stderr
%54 = load i32, i32* @errno
%55 = tail call i8* @strerror(i32 %54)
%56 = tail call i32 (i32, i8*, ...) @fprintf(i32 %53, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @.str.1, i64 0, i64 0), i8* %52, i8* %55)
%57 = tail call i32 @exit(i32 1)
unreachable
58: ; preds = %44
%59 = call i64 @fstat(i32 %49, %struct.stat* %3)
%60 = icmp eq i64 %59, 0
br i1 %60, label %68, label %61
61: ; preds = %58, %23
%62 = phi i8* [ %19, %23 ], [ %47, %58 ]
%63 = load i32, i32* @stderr
%64 = load i32, i32* @errno
%65 = tail call i8* @strerror(i32 %64)
%66 = tail call i32 (i32, i8*, ...) @fprintf(i32 %63, i8* getelementptr inbounds ([39 x i8], [39 x i8]* @.str.2, i64 0, i64 0), i8* %62, i8* %65)
%67 = tail call i32 @exit(i32 1)
unreachable
68: ; preds = %58
%69 = load i64, i64* %17
%70 = icmp eq i64 %27, %69
br i1 %70, label %76, label %71
71: ; preds = %68
%72 = load i32, i32* @stderr
%73 = load i8*, i8** %12
%74 = tail call i32 (i32, i8*, ...) @fprintf(i32 %72, i8* getelementptr inbounds ([60 x i8], [60 x i8]* @.str.3, i64 0, i64 0), i8* %73, i8* %47)
%75 = tail call i32 @exit(i32 1)
unreachable
76: ; preds = %68
%77 = load i32, i32* @PROT_READ
%78 = load i32, i32* @MAP_SHARED
%79 = tail call i8* @mmap(i32* null, i64 %27, i32 %77, i32 %78, i32 %49, i32 0)
%80 = getelementptr inbounds i8*, i8** %15, i64 %45
store i8* %79, i8** %80
%81 = load i8*, i8** @MAP_FAILED
%82 = icmp eq i8* %79, %81
br i1 %82, label %83, label %90
83: ; preds = %76, %26
%84 = phi i8* [ %19, %26 ], [ %47, %76 ]
%85 = load i32, i32* @stderr
%86 = load i32, i32* @errno
%87 = tail call i8* @strerror(i32 %86)
%88 = tail call i32 (i32, i8*, ...) @fprintf(i32 %85, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0), i8* %84, i8* %87)
%89 = tail call i32 @exit(i32 1)
unreachable
90: ; preds = %76
%91 = tail call i32 @close(i32 %49)
%92 = add nuw nsw i64 %45, 1
%93 = icmp eq i64 %92, %18
br i1 %93, label %36, label %44
94: ; preds = %36
%95 = tail call i32 @perror(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.5, i64 0, i64 0))
%96 = tail call i32 @exit(i32 1)
unreachable
97: ; preds = %36
%98 = tail call i64 @ftruncate(i32 %42, i64 %27)
%99 = icmp eq i64 %98, 0
br i1 %99, label %103, label %100
100: ; preds = %97
%101 = tail call i32 @perror(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.6, i64 0, i64 0))
%102 = tail call i32 @exit(i32 1)
unreachable
103: ; preds = %97
%104 = load i32, i32* @PROT_READ
%105 = load i32, i32* @PROT_WRITE
%106 = or i32 %105, %104
%107 = load i32, i32* @MAP_SHARED
%108 = tail call i8* @mmap(i32* null, i64 %27, i32 %106, i32 %107, i32 %42, i32 0)
%109 = load i8*, i8** @MAP_FAILED
%110 = icmp eq i8* %108, %109
br i1 %110, label %111, label %114
111: ; preds = %103
%112 = tail call i32 @perror(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.7, i64 0, i64 0))
%113 = tail call i32 @exit(i32 1)
unreachable
114: ; preds = %103
%115 = tail call i32 @close(i32 %42)
%116 = icmp sgt i64 %27, 0
br i1 %116, label %117, label %120
117: ; preds = %114
%118 = icmp sgt i32 %0, 2
%119 = zext i32 %13 to i64
br label %123
120: ; preds = %128, %114
%121 = load i32, i32* @stderr
%122 = tail call i32 (i32, i8*, ...) @fprintf(i32 %121, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.9, i64 0, i64 0))
ret i32 0
123: ; preds = %117, %128
%124 = phi i64 [ 0, %117 ], [ %129, %128 ]
%125 = getelementptr inbounds i8, i8* %108, i64 %124
br i1 %118, label %126, label %128
126: ; preds = %123
%127 = load i8, i8* %125
br label %131
128: ; preds = %150, %123
%129 = add nuw nsw i64 %124, 1
%130 = icmp eq i64 %129, %27
br i1 %130, label %120, label %123
131: ; preds = %126, %150
%132 = phi i8 [ %127, %126 ], [ %151, %150 ]
%133 = phi i64 [ 0, %126 ], [ %152, %150 ]
%134 = getelementptr inbounds i8*, i8** %15, i64 %133
%135 = load i8*, i8** %134
%136 = getelementptr inbounds i8, i8* %135, i64 %124
%137 = load i8, i8* %136
%138 = icmp ne i8 %132, 0
%139 = icmp ne i8 %137, 0
%140 = select i1 %138, i1 %139, i1 false
%141 = xor i1 %140, true
%142 = icmp eq i8 %132, %137
%143 = select i1 %141, i1 true, i1 %142
br i1 %143, label %148, label %144
144: ; preds = %131
%145 = load i32, i32* @stderr
%146 = tail call i32 (i32, i8*, ...) @fprintf(i32 %145, i8* getelementptr inbounds ([46 x i8], [46 x i8]* @.str.8, i64 0, i64 0))
%147 = tail call i32 @exit(i32 1)
unreachable
148: ; preds = %131
br i1 %139, label %149, label %150
149: ; preds = %148
store i8 %137, i8* %125
br label %150
150: ; preds = %149, %148
%151 = phi i8 [ %137, %149 ], [ %132, %148 ]
%152 = add nuw nsw i64 %133, 1
%153 = icmp eq i64 %152, %119
br i1 %153, label %128, label %131
}