#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 */
typedef int /*<<< orphan*/ FILE;

/* Variables and functions */
int /*<<< orphan*/ fgets(char *, int, int /*<<< orphan*/ *);
int /*<<< orphan*/ *fopen(char *, char *);
int /*<<< orphan*/ free(char *);
int /*<<< orphan*/ get_key(char *, char *, char **, int, char *);
int /*<<< orphan*/ get_phrase(char *, char *, char **);
scalar_t__ is_hex(char *);
int key_length(char *);
char *malloc(int);
int max_phrase_length(char *);
int /*<<< orphan*/ normalize_hex_string(char *, char *);
int normalized_hex_string_length(char *);
int printf(char *, char *);
scalar_t__ strlen(char *);
int main(int argc, char **argv) {
  if (argc != 2) {
    return printf("usage: %s [hex key] [key phrase]\n", argv[0]);
  }
  char *wordlist[65536];
  FILE *fp = fopen("words.txt", "r");
  if (!fp) {
    printf("Could not find wordlist: '%s' is missing!\n", "words.txt");
    return 1;
  }
  for (int i = 0; i < 65536; i++) {
    wordlist[i] = malloc(11 + 1);
    fgets(wordlist[i], 11 + 1, fp);
    for (int j = strlen(wordlist[i]) - 1;
         j >= 0 && (wordlist[i][j] == '\n' || wordlist[i][j] == '\r'); j--) {
      wordlist[i][j] = '\0';
    }
  }
  if (is_hex(argv[1])) {
    char hex[normalized_hex_string_length(argv[1])];
    normalize_hex_string(hex, argv[1]);
    char phrase[max_phrase_length(hex)];
    get_phrase(phrase, hex, wordlist);
    printf("%s\n", phrase);
  } else {
    char key[key_length(argv[1])];
    char err_msg[64 + strlen(argv[1])];
    get_key(key, argv[1], wordlist, 65536, err_msg);
    if (strlen(err_msg) > 0) {
      printf("ERROR: %s\n", err_msg);
      return 1;
    } else {
      printf("0x%s\n", key);
    }
  }
  for (int i = 0; i < 65536; i++) {
    free(wordlist[i]);
  }
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80080,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
cmpl   $0x2,-0x8(%rbp)
je     120e <main+0x3e>
mov    -0x10(%rbp),%rax
mov    (%rax),%rsi
lea    0xdff(%rip),%rdi
call   1060 <printf@plt>
mov    %eax,-0x4(%rbp)
jmp    15b6 <main+0x3e6>
lea    0xe0d(%rip),%rdi
lea    0xe10(%rip),%rsi
call   10f0 <fopen@plt>
mov    %rax,-0x80018(%rbp)
cmpq   $0x0,-0x80018(%rbp)
jne    1255 <main+0x85>
lea    0xdf1(%rip),%rdi
lea    0xdde(%rip),%rsi
call   1060 <printf@plt>
movl   $0x1,-0x4(%rbp)
jmp    15b6 <main+0x3e6>
movl   $0x0,-0x8001c(%rbp)
cmpl   $0x10000,-0x8001c(%rbp)
jge    1395 <main+0x1c5>
mov    $0xc,%edi
call   10c0 <malloc@plt>
mov    %rax,%rcx
movslq -0x8001c(%rbp),%rax
mov    %rcx,-0x80010(%rbp,%rax,8)
ff
movslq -0x8001c(%rbp),%rax
mov    -0x80010(%rbp,%rax,8),%rdi
ff
mov    -0x80018(%rbp),%rdx
mov    $0xc,%esi
call   1090 <fgets@plt>
movslq -0x8001c(%rbp),%rax
mov    -0x80010(%rbp,%rax,8),%rdi
ff
call   1050 <strlen@plt>
sub    $0x1,%rax
mov    %eax,-0x80020(%rbp)
xor    %eax,%eax
cmpl   $0x0,-0x80020(%rbp)
mov    %al,-0x80059(%rbp)
jl     133b <main+0x16b>
movslq -0x8001c(%rbp),%rax
mov    -0x80010(%rbp,%rax,8),%rax
ff
movslq -0x80020(%rbp),%rcx
movsbl (%rax,%rcx,1),%ecx
mov    $0x1,%al
cmp    $0xa,%ecx
mov    %al,-0x8005a(%rbp)
je     132f <main+0x15f>
movslq -0x8001c(%rbp),%rax
mov    -0x80010(%rbp,%rax,8),%rax
ff
movslq -0x80020(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0xd,%eax
sete   %al
mov    %al,-0x8005a(%rbp)
mov    -0x8005a(%rbp),%al
mov    %al,-0x80059(%rbp)
mov    -0x80059(%rbp),%al
test   $0x1,%al
jne    134e <main+0x17e>
jmp    137c <main+0x1ac>
movslq -0x8001c(%rbp),%rax
mov    -0x80010(%rbp,%rax,8),%rax
ff
movslq -0x80020(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x80020(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x80020(%rbp)
jmp    12c9 <main+0xf9>
jmp    1381 <main+0x1b1>
mov    -0x8001c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8001c(%rbp)
jmp    125f <main+0x8f>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
call   1070 <is_hex@plt>
cmp    $0x0,%rax
je     1459 <main+0x289>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
call   1040 <normalized_hex_string_length@plt>
mov    %eax,%eax
mov    %rsp,%rcx
mov    %rcx,-0x80028(%rbp)
mov    %rax,%rcx
add    $0xf,%rcx
and    $0xfffffffffffffff0,%rcx
mov    %rsp,%rdi
sub    %rcx,%rdi
mov    %rdi,-0x80070(%rbp)
mov    %rdi,%rsp
mov    %rax,-0x80030(%rbp)
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rsi
call   1080 <normalize_hex_string@plt>
mov    -0x80070(%rbp),%rdi
call   10e0 <max_phrase_length@plt>
mov    -0x80070(%rbp),%rsi
mov    %eax,%eax
mov    %rax,%rcx
add    $0xf,%rcx
and    $0xfffffffffffffff0,%rcx
mov    %rsp,%rdi
sub    %rcx,%rdi
mov    %rdi,-0x80068(%rbp)
mov    %rdi,%rsp
mov    %rax,-0x80038(%rbp)
lea    -0x80010(%rbp),%rdx
call   10b0 <get_phrase@plt>
mov    -0x80068(%rbp),%rsi
lea    0xc1b(%rip),%rdi
call   1060 <printf@plt>
mov    -0x80028(%rbp),%rax
mov    %rax,%rsp
jmp    156d <main+0x39d>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
call   10d0 <key_length@plt>
mov    %eax,%eax
mov    %rsp,%rcx
mov    %rcx,-0x80040(%rbp)
mov    %rax,%rdx
add    $0xf,%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x80080(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x80048(%rbp)
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
call   1050 <strlen@plt>
mov    -0x80080(%rbp),%rdi
mov    %rax,%rcx
mov    %rcx,%rax
add    $0x40,%rax
add    $0x4f,%rcx
and    $0xfffffffffffffff0,%rcx
mov    %rsp,%r8
sub    %rcx,%r8
mov    %r8,-0x80078(%rbp)
mov    %r8,%rsp
mov    %rax,-0x80050(%rbp)
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rsi
lea    -0x80010(%rbp),%rdx
mov    $0x10000,%ecx
call   10a0 <get_key@plt>
mov    -0x80078(%rbp),%rdi
call   1050 <strlen@plt>
cmp    $0x0,%rax
jle    1529 <main+0x359>
mov    -0x80078(%rbp),%rsi
lea    0xb4b(%rip),%rdi
call   1060 <printf@plt>
movl   $0x1,-0x4(%rbp)
movl   $0x1,-0x80054(%rbp)
jmp    1546 <main+0x376>
mov    -0x80080(%rbp),%rsi
lea    0xb2d(%rip),%rdi
call   1060 <printf@plt>
movl   $0x0,-0x80054(%rbp)
mov    -0x80040(%rbp),%rax
mov    %rax,%rsp
mov    -0x80054(%rbp),%eax
test   %eax,%eax
je     1568 <main+0x398>
jmp    1563 <main+0x393>
jmp    15b6 <main+0x3e6>
jmp    156d <main+0x39d>
movl   $0x0,-0x80058(%rbp)
cmpl   $0x10000,-0x80058(%rbp)
jge    15af <main+0x3df>
movslq -0x80058(%rbp),%rax
mov    -0x80010(%rbp,%rax,8),%rdi
ff
call   1030 <free@plt>
mov    -0x80058(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x80058(%rbp)
jmp    1577 <main+0x3a7>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x80000,%rsp
mov    %rsi,%r14
cmp    $0x2,%edi
jne    1296 <main+0xc6>
lea    0xe2d(%rip),%rdi
lea    0xe30(%rip),%rsi
call   10f0 <fopen@plt>
test   %rax,%rax
je     135f <main+0x18f>
mov    %rax,%r15
xor    %r12d,%r12d
jmp    1231 <main+0x61>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
add    $0x1,%r12
cmp    $0x10000,%r12
je     12b1 <main+0xe1>
mov    $0xc,%edi
call   10c0 <malloc@plt>
mov    %rax,%rbx
mov    %rax,-0x80020(%rbp,%r12,8)
ff
mov    %rax,%rdi
mov    $0xc,%esi
mov    %r15,%rdx
call   1090 <fgets@plt>
mov    %rbx,%rdi
call   1050 <strlen@plt>
mov    %eax,%ecx
add    $0xffffffff,%ecx
js     1220 <main+0x50>
add    $0xfffffffe,%eax
nopl   0x0(%rax,%rax,1)
lea    0x1(%rax),%ecx
movzbl (%rbx,%rcx,1),%edx
cmp    $0xa,%dl
je     1281 <main+0xb1>
cmp    $0xd,%dl
jne    1220 <main+0x50>
movb   $0x0,(%rbx,%rcx,1)
test   %eax,%eax
js     1220 <main+0x50>
mov    -0x80020(%rbp,%r12,8),%rbx
ff
add    $0xffffffff,%eax
jmp    1270 <main+0xa0>
mov    (%r14),%rsi
lea    0xd60(%rip),%rdi
lea    -0x20(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
jmp    1060 <printf@plt>
mov    0x8(%r14),%rdi
call   1070 <is_hex@plt>
mov    0x8(%r14),%rdi
test   %rax,%rax
je     137a <main+0x1aa>
call   1040 <normalized_hex_string_length@plt>
mov    %rsp,%r12
mov    %eax,%eax
mov    %rsp,%r15
add    $0xf,%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%r15
mov    %r15,%rsp
mov    0x8(%r14),%rsi
mov    %r15,%rdi
call   1080 <normalize_hex_string@plt>
mov    %r15,%rdi
call   10e0 <max_phrase_length@plt>
mov    %eax,%eax
add    $0xf,%rax
and    $0xfffffffffffffff0,%rax
mov    %rsp,%rbx
sub    %rax,%rbx
mov    %rbx,%rsp
lea    -0x80020(%rbp),%rdx
mov    %rbx,%rdi
mov    %r15,%rsi
call   10b0 <get_phrase@plt>
lea    0xd3e(%rip),%rdi
mov    %rbx,%rsi
call   1060 <printf@plt>
mov    %r12,%rsp
xor    %r14d,%r14d
xor    %ebx,%ebx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    -0x80020(%rbp,%rbx,8),%rdi
ff
call   1030 <free@plt>
add    $0x1,%rbx
cmp    $0x10000,%rbx
jne    1340 <main+0x170>
jmp    13f1 <main+0x221>
lea    0xcc8(%rip),%rdi
lea    0xcb5(%rip),%rsi
call   1060 <printf@plt>
mov    $0x1,%r14d
jmp    13f1 <main+0x221>
call   10d0 <key_length@plt>
mov    %rsp,%r12
mov    %eax,%eax
mov    %rsp,%r15
add    $0xf,%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%r15
mov    %r15,%rsp
mov    0x8(%r14),%r14
mov    %r14,%rdi
call   1050 <strlen@plt>
mov    %rsp,%rbx
add    $0x4f,%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%rbx
mov    %rbx,%rsp
lea    -0x80020(%rbp),%rdx
mov    %r15,%rdi
mov    %r14,%rsi
mov    $0x10000,%ecx
mov    %rbx,%r8
call   10a0 <get_key@plt>
mov    %rbx,%rdi
call   1050 <strlen@plt>
test   %rax,%rax
jle    1401 <main+0x231>
lea    0xc79(%rip),%rdi
mov    %rbx,%rsi
call   1060 <printf@plt>
mov    $0x1,%r14d
mov    %r12,%rsp
mov    %r14d,%eax
lea    -0x20(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret
lea    0xc5c(%rip),%rdi
mov    %r15,%rsi
jmp    1325 <main+0x155>

LLVM IR (-O0):
@.str = [34 x i8] c"usage: %s [hex key] [key phrase]\0A\00"
@.str.1 = [10 x i8] c"words.txt\00"
@.str.2 = [2 x i8] c"r\00"
@.str.3 = [43 x i8] c"Could not find wordlist: '%s' is missing!\0A\00"
@.str.4 = [4 x i8] c"%s\0A\00"
@.str.5 = [11 x i8] c"ERROR: %s\0A\00"
@.str.6 = [6 x i8] c"0x%s\0A\00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca [65536 x i8*]
%7 = alloca i32*
%8 = alloca i32
%9 = alloca i32
%10 = alloca i8*
%11 = alloca i64
%12 = alloca i64
%13 = alloca i8*
%14 = alloca i64
%15 = alloca i64
%16 = alloca i32
%17 = alloca i32
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%18 = load i32, i32* %4
%19 = icmp ne i32 %18, 2
br i1 %19, label %20, label %25
20: ; preds = %2
%21 = load i8**, i8*** %5
%22 = getelementptr inbounds i8*, i8** %21, i64 0
%23 = load i8*, i8** %22
%24 = call i32 @printf(i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str, i64 0, i64 0), i8* %23)
store i32 %24, i32* %3
br label %166
25: ; preds = %2
%26 = call i32* @fopen(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.1, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.2, i64 0, i64 0))
store i32* %26, i32** %7
%27 = load i32*, i32** %7
%28 = icmp ne i32* %27, null
br i1 %28, label %31, label %29
29: ; preds = %25
%30 = call i32 @printf(i8* getelementptr inbounds ([43 x i8], [43 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.1, i64 0, i64 0))
store i32 1, i32* %3
br label %166
31: ; preds = %25
store i32 0, i32* %8
br label %32
32: ; preds = %94, %31
%33 = load i32, i32* %8
%34 = icmp slt i32 %33, 65536
br i1 %34, label %35, label %97
35: ; preds = %32
%36 = call i8* @malloc(i32 12)
%37 = load i32, i32* %8
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %6, i64 0, i64 %38
store i8* %36, i8** %39
%40 = load i32, i32* %8
%41 = sext i32 %40 to i64
%42 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %6, i64 0, i64 %41
%43 = load i8*, i8** %42
%44 = load i32*, i32** %7
%45 = call i32 @fgets(i8* %43, i32 12, i32* %44)
%46 = load i32, i32* %8
%47 = sext i32 %46 to i64
%48 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %6, i64 0, i64 %47
%49 = load i8*, i8** %48
%50 = call i64 @strlen(i8* %49)
%51 = sub nsw i64 %50, 1
%52 = trunc i64 %51 to i32
store i32 %52, i32* %9
br label %53
53: ; preds = %90, %35
%54 = load i32, i32* %9
%55 = icmp sge i32 %54, 0
br i1 %55, label %56, label %80
56: ; preds = %53
%57 = load i32, i32* %8
%58 = sext i32 %57 to i64
%59 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %6, i64 0, i64 %58
%60 = load i8*, i8** %59
%61 = load i32, i32* %9
%62 = sext i32 %61 to i64
%63 = getelementptr inbounds i8, i8* %60, i64 %62
%64 = load i8, i8* %63
%65 = sext i8 %64 to i32
%66 = icmp eq i32 %65, 10
br i1 %66, label %78, label %67
67: ; preds = %56
%68 = load i32, i32* %8
%69 = sext i32 %68 to i64
%70 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %6, i64 0, i64 %69
%71 = load i8*, i8** %70
%72 = load i32, i32* %9
%73 = sext i32 %72 to i64
%74 = getelementptr inbounds i8, i8* %71, i64 %73
%75 = load i8, i8* %74
%76 = sext i8 %75 to i32
%77 = icmp eq i32 %76, 13
br label %78
78: ; preds = %67, %56
%79 = phi i1 [ true, %56 ], [ %77, %67 ]
br label %80
80: ; preds = %78, %53
%81 = phi i1 [ false, %53 ], [ %79, %78 ]
br i1 %81, label %82, label %93
82: ; preds = %80
%83 = load i32, i32* %8
%84 = sext i32 %83 to i64
%85 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %6, i64 0, i64 %84
%86 = load i8*, i8** %85
%87 = load i32, i32* %9
%88 = sext i32 %87 to i64
%89 = getelementptr inbounds i8, i8* %86, i64 %88
store i8 0, i8* %89
br label %90
90: ; preds = %82
%91 = load i32, i32* %9
%92 = add nsw i32 %91, -1
store i32 %92, i32* %9
br label %53
93: ; preds = %80
br label %94
94: ; preds = %93
%95 = load i32, i32* %8
%96 = add nsw i32 %95, 1
store i32 %96, i32* %8
br label %32
97: ; preds = %32
%98 = load i8**, i8*** %5
%99 = getelementptr inbounds i8*, i8** %98, i64 1
%100 = load i8*, i8** %99
%101 = call i64 @is_hex(i8* %100)
%102 = icmp ne i64 %101, 0
br i1 %102, label %103, label %122
103: ; preds = %97
%104 = load i8**, i8*** %5
%105 = getelementptr inbounds i8*, i8** %104, i64 1
%106 = load i8*, i8** %105
%107 = call i32 @normalized_hex_string_length(i8* %106)
%108 = zext i32 %107 to i64
%109 = call i8* @llvm.stacksave()
store i8* %109, i8** %10
%110 = alloca i8, i64 %108
store i64 %108, i64* %11
%111 = load i8**, i8*** %5
%112 = getelementptr inbounds i8*, i8** %111, i64 1
%113 = load i8*, i8** %112
%114 = call i32 @normalize_hex_string(i8* %110, i8* %113)
%115 = call i32 @max_phrase_length(i8* %110)
%116 = zext i32 %115 to i64
%117 = alloca i8, i64 %116
store i64 %116, i64* %12
%118 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %6, i64 0, i64 0
%119 = call i32 @get_phrase(i8* %117, i8* %110, i8** %118)
%120 = call i32 @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i64 0, i64 0), i8* %117)
%121 = load i8*, i8** %10
br label %152
122: ; preds = %97
%123 = load i8**, i8*** %5
%124 = getelementptr inbounds i8*, i8** %123, i64 1
%125 = load i8*, i8** %124
%126 = call i32 @key_length(i8* %125)
%127 = zext i32 %126 to i64
%128 = call i8* @llvm.stacksave()
store i8* %128, i8** %13
%129 = alloca i8, i64 %127
store i64 %127, i64* %14
%130 = load i8**, i8*** %5
%131 = getelementptr inbounds i8*, i8** %130, i64 1
%132 = load i8*, i8** %131
%133 = call i64 @strlen(i8* %132)
%134 = add nsw i64 64, %133
%135 = alloca i8, i64 %134
store i64 %134, i64* %15
%136 = load i8**, i8*** %5
%137 = getelementptr inbounds i8*, i8** %136, i64 1
%138 = load i8*, i8** %137
%139 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %6, i64 0, i64 0
%140 = call i32 @get_key(i8* %129, i8* %138, i8** %139, i32 65536, i8* %135)
%141 = call i64 @strlen(i8* %135)
%142 = icmp sgt i64 %141, 0
br i1 %142, label %143, label %145
143: ; preds = %122
%144 = call i32 @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i64 0, i64 0), i8* %135)
store i32 1, i32* %3
store i32 1, i32* %16
br label %148
145: ; preds = %122
%146 = call i32 @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.6, i64 0, i64 0), i8* %129)
br label %147
147: ; preds = %145
store i32 0, i32* %16
br label %148
148: ; preds = %147, %143
%149 = load i8*, i8** %13
%150 = load i32, i32* %16
switch i32 %150, label %168 [
i32 0, label %151
i32 1, label %166
]
151: ; preds = %148
br label %152
152: ; preds = %151, %103
store i32 0, i32* %17
br label %153
153: ; preds = %162, %152
%154 = load i32, i32* %17
%155 = icmp slt i32 %154, 65536
br i1 %155, label %156, label %165
156: ; preds = %153
%157 = load i32, i32* %17
%158 = sext i32 %157 to i64
%159 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %6, i64 0, i64 %158
%160 = load i8*, i8** %159
%161 = call i32 @free(i8* %160)
br label %162
162: ; preds = %156
%163 = load i32, i32* %17
%164 = add nsw i32 %163, 1
store i32 %164, i32* %17
br label %153
165: ; preds = %153
store i32 0, i32* %3
br label %166
166: ; preds = %165, %148, %29, %20
%167 = load i32, i32* %3
ret i32 %167
168: ; preds = %148
unreachable
}

LLVM IR (-O2):
@.str = [34 x i8] c"usage: %s [hex key] [key phrase]\0A\00"
@.str.1 = [10 x i8] c"words.txt\00"
@.str.2 = [2 x i8] c"r\00"
@.str.3 = [43 x i8] c"Could not find wordlist: '%s' is missing!\0A\00"
@.str.4 = [4 x i8] c"%s\0A\00"
@.str.5 = [11 x i8] c"ERROR: %s\0A\00"
@.str.6 = [6 x i8] c"0x%s\0A\00"
define i32 @main(i32 %0, i8** nocapture %1) {
%3 = alloca [65536 x i8*]
%4 = icmp eq i32 %0, 2
br i1 %4, label %8, label %5
5: ; preds = %2
%6 = load i8*, i8** %1
%7 = tail call i32 @printf(i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str, i64 0, i64 0), i8* %6)
br label %84
8: ; preds = %2
%9 = bitcast [65536 x i8*]* %3 to i8*
%10 = tail call i32* @fopen(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.1, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.2, i64 0, i64 0))
%11 = icmp eq i32* %10, null
br i1 %11, label %12, label %20
12: ; preds = %8
%13 = tail call i32 @printf(i8* getelementptr inbounds ([43 x i8], [43 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.1, i64 0, i64 0))
br label %82
14: ; preds = %35
%15 = getelementptr inbounds i8*, i8** %1, i64 1
%16 = load i8*, i8** %15
%17 = tail call i64 @is_hex(i8* %16)
%18 = icmp eq i64 %17, 0
%19 = load i8*, i8** %15
br i1 %18, label %56, label %43
20: ; preds = %8, %35
%21 = phi i64 [ %36, %35 ], [ 0, %8 ]
%22 = tail call dereferenceable_or_null(12) i8* @malloc(i32 12)
%23 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %3, i64 0, i64 %21
store i8* %22, i8** %23
%24 = tail call i32 @fgets(i8* %22, i32 12, i32* %10)
%25 = tail call i64 @strlen(i8* dereferenceable(1) %22)
%26 = trunc i64 %25 to i32
%27 = add i32 %26, -1
%28 = icmp sgt i32 %27, -1
br i1 %28, label %29, label %35
29: ; preds = %20, %41
%30 = phi i8* [ %42, %41 ], [ %22, %20 ]
%31 = phi i32 [ %39, %41 ], [ %27, %20 ]
%32 = zext i32 %31 to i64
%33 = getelementptr inbounds i8, i8* %30, i64 %32
%34 = load i8, i8* %33
switch i8 %34, label %35 [
i8 10, label %38
i8 13, label %38
]
35: ; preds = %38, %29, %20
%36 = add nuw nsw i64 %21, 1
%37 = icmp eq i64 %36, 65536
br i1 %37, label %14, label %20
38: ; preds = %29, %29
store i8 0, i8* %33
%39 = add i32 %31, -1
%40 = icmp sgt i32 %39, -1
br i1 %40, label %41, label %35
41: ; preds = %38
%42 = load i8*, i8** %23
br label %29
43: ; preds = %14
%44 = tail call i32 @normalized_hex_string_length(i8* %19)
%45 = zext i32 %44 to i64
%46 = tail call i8* @llvm.stacksave()
%47 = alloca i8, i64 %45
%48 = load i8*, i8** %15
%49 = call i32 @normalize_hex_string(i8* %47, i8* %48)
%50 = call i32 @max_phrase_length(i8* %47)
%51 = zext i32 %50 to i64
%52 = alloca i8, i64 %51
%53 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %3, i64 0, i64 0
%54 = call i32 @get_phrase(i8* %52, i8* %47, i8** %53)
%55 = call i32 @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i64 0, i64 0), i8* %52)
br label %73
56: ; preds = %14
%57 = tail call i32 @key_length(i8* %19)
%58 = zext i32 %57 to i64
%59 = tail call i8* @llvm.stacksave()
%60 = alloca i8, i64 %58
%61 = load i8*, i8** %15
%62 = tail call i64 @strlen(i8* dereferenceable(1) %61)
%63 = add nsw i64 %62, 64
%64 = alloca i8, i64 %63
%65 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %3, i64 0, i64 0
%66 = call i32 @get_key(i8* %60, i8* %61, i8** %65, i32 65536, i8* %64)
%67 = call i64 @strlen(i8* %64)
%68 = icmp sgt i64 %67, 0
br i1 %68, label %69, label %71
69: ; preds = %56
%70 = call i32 @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i64 0, i64 0), i8* %64)
br label %82
71: ; preds = %56
%72 = call i32 @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.6, i64 0, i64 0), i8* %60)
br label %73
73: ; preds = %71, %43
%74 = phi i8* [ %59, %71 ], [ %46, %43 ]
br label %75
75: ; preds = %73, %75
%76 = phi i64 [ 0, %73 ], [ %80, %75 ]
%77 = getelementptr inbounds [65536 x i8*], [65536 x i8*]* %3, i64 0, i64 %76
%78 = load i8*, i8** %77
%79 = call i32 @free(i8* %78)
%80 = add nuw nsw i64 %76, 1
%81 = icmp eq i64 %80, 65536
br i1 %81, label %82, label %75
82: ; preds = %75, %69, %12
%83 = phi i32 [ 1, %12 ], [ 1, %69 ], [ 0, %75 ]
br label %84
84: ; preds = %82, %5
%85 = phi i32 [ %7, %5 ], [ %83, %82 ]
ret i32 %85
}