#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 handshake_message {
  int dummy;
};

/* Variables and functions */
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, unsigned int);
int /*<<< orphan*/ printf(char *, ...);
int /*<<< orphan*/ process_handshake_client_hello(unsigned char *, int, int,
                                                  unsigned int, int, int);
int /*<<< orphan*/ process_handshake_server_hello(unsigned char *, int, int,
                                                  unsigned int, int, int);
unsigned int read_uint(unsigned char *, int, int);
int /*<<< orphan*/ stderr;
struct handshake_message *process_handshake(void *data, int offset,
                                            int record_length, int json,
                                            int raw) {
  unsigned char *buffer = data;
  unsigned handshake_type = 0;
  unsigned handshake_length = 0;
  handshake_type = read_uint(buffer, offset + 5, 1);
  handshake_length = read_uint(buffer, offset + 5 + 1, 3);
  if (!json) {
    printf("Handshake length: %d\n", handshake_length);
  }
  if (json)
    printf("\"handshake_type\": \"");
  else
    printf("Handshake type: ");
  switch (handshake_type) {
  default:
    fprintf(stderr, "ERROR: Unknown handshake type %d", handshake_type);
    break;
  case 0x00:
    printf("HELLO_REQUEST");
    if (json)
      printf("\"\n");
    break;
  case 0x01:
    printf("CLIENT_HELLO");
    if (json)
      printf("\", \"handshake_data\": {\n");
    process_handshake_client_hello(buffer, offset, record_length,
                                   handshake_length, json, raw);
    if (json)
      printf("}\n");
    break;
  case 0x02:
    printf("SERVER_HELLO");
    if (json)
      printf("\", \"handshake_data\": {\n");
    process_handshake_server_hello(buffer, offset, record_length,
                                   handshake_length, json, raw);
    if (json)
      printf("}\n");
    break;
  case 0x04:
    printf("NEW_SESSION_TICKET");
    if (json)
      printf("\"\n");
    break;
  case 0x0b:
    printf("CERTIFICATE");
    if (json)
      printf("\"\n");
    break;
  case 0x0c:
    printf("SERVER_KEY_EXCHANGE");
    if (json)
      printf("\"\n");
    break;
  case 0x0d:
    printf("CERTIFICATE_REQUEST");
    if (json)
      printf("\"\n");
    break;
  case 0x0e:
    printf("SERVER_DONE");
    if (json)
      printf("\"\n");
    break;
  case 0x0f:
    printf("CERTIFICATE_VERIFY");
    if (json)
      printf("\"\n");
    break;
  case 0x10:
    printf("CLIENT_KEY_EXCHANGE");
    if (json)
      printf("\"\n");
    break;
  case 0x14:
    printf("FINISHED");
    if (json)
      printf("\"\n");
    break;
  case 0x15:
    printf("CERTIFICATE_URL");
    if (json)
      printf("\"\n");
    break;
  case 0x16:
    printf("CERTIFICATE_STATUS");
    if (json)
      printf("\"\n");
    break;
  }
  return 0;
}


x86 assembly (clang, -O0):
<process_handshake>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    %r8d,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
movl   $0x0,-0x28(%rbp)
mov    -0x20(%rbp),%rdi
mov    -0xc(%rbp),%esi
add    $0x5,%esi
mov    $0x1,%edx
call   1050 <read_uint@plt>
mov    %eax,-0x24(%rbp)
mov    -0x20(%rbp),%rdi
mov    -0xc(%rbp),%esi
add    $0x5,%esi
add    $0x1,%esi
mov    $0x3,%edx
call   1050 <read_uint@plt>
mov    %eax,-0x28(%rbp)
cmpl   $0x0,-0x14(%rbp)
jne    11cb <process_handshake+0x7b>
mov    -0x28(%rbp),%esi
lea    0xe98(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     11e8 <process_handshake+0x98>
lea    0xe96(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    11f6 <process_handshake+0xa6>
lea    0xe97(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x24(%rbp),%eax
mov    %rax,-0x30(%rbp)
sub    $0x16,%rax
ja     121b <process_handshake+0xcb>
mov    -0x30(%rbp),%rax
lea    0xdee(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    0x2dbe(%rip),%rax
mov    (%rax),%edi
mov    -0x24(%rbp),%edx
lea    0xe69(%rip),%rsi
call   1040 <fprintf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xe79(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     125e <process_handshake+0x10e>
lea    0xe6f(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xe5f(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     1289 <process_handshake+0x139>
lea    0xe54(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x20(%rbp),%rdi
mov    -0xc(%rbp),%esi
mov    -0x10(%rbp),%edx
mov    -0x28(%rbp),%ecx
mov    -0x14(%rbp),%r8d
mov    -0x18(%rbp),%r9d
call   1070 <process_handshake_client_hello@plt>
cmpl   $0x0,-0x14(%rbp)
je     12bb <process_handshake+0x16b>
lea    0xe3a(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xe2a(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     12e6 <process_handshake+0x196>
lea    0xdf7(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x20(%rbp),%rdi
mov    -0xc(%rbp),%esi
mov    -0x10(%rbp),%edx
mov    -0x28(%rbp),%ecx
mov    -0x14(%rbp),%r8d
mov    -0x18(%rbp),%r9d
call   1060 <process_handshake_server_hello@plt>
cmpl   $0x0,-0x14(%rbp)
je     1318 <process_handshake+0x1c8>
lea    0xddd(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xdda(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     1343 <process_handshake+0x1f3>
lea    0xd8a(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xdc2(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     136e <process_handshake+0x21e>
lea    0xd5f(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xda3(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     1399 <process_handshake+0x249>
lea    0xd34(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xd8c(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     13c4 <process_handshake+0x274>
lea    0xd09(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xd75(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     13ef <process_handshake+0x29f>
lea    0xcde(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xd56(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     141a <process_handshake+0x2ca>
lea    0xcb3(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xd3e(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     1445 <process_handshake+0x2f5>
lea    0xc88(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xd27(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     1470 <process_handshake+0x320>
lea    0xc5d(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xd05(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     149b <process_handshake+0x34b>
lea    0xc32(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
lea    0xcea(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
cmpl   $0x0,-0x14(%rbp)
je     14c6 <process_handshake+0x376>
lea    0xc07(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    14cb <process_handshake+0x37b>
xor    %eax,%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<process_handshake>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %r8d,0x4(%rsp)
mov    %ecx,%r12d
mov    %edx,%r15d
mov    %esi,%ebp
mov    %rdi,%rbx
lea    0x5(%rbp),%esi
mov    $0x1,%edx
call   1060 <read_uint@plt>
mov    %eax,%r14d
lea    0x6(%rbp),%esi
mov    %rbx,%rdi
mov    $0x3,%edx
call   1060 <read_uint@plt>
mov    %eax,%r13d
test   %r12d,%r12d
je     11ac <process_handshake+0x4c>
lea    0xec8(%rip),%rdi
jmp    11c4 <process_handshake+0x64>
lea    0xea9(%rip),%rdi
mov    %r13d,%esi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0xec2(%rip),%rdi
xor    %eax,%eax
call   1040 <printf@plt>
cmp    $0x16,%r14d
ja     1278 <process_handshake+0x118>
mov    %r14d,%eax
lea    0xe21(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
lea    0xec9(%rip),%rdi
jmp    12ea <process_handshake+0x18a>
lea    0xecb(%rip),%rdi
xor    %eax,%eax
call   1040 <printf@plt>
test   %r12d,%r12d
je     1313 <process_handshake+0x1b3>
lea    0xf76(%rip),%rdi
call   1030 <puts@plt>
mov    %rbx,%rdi
mov    %ebp,%esi
mov    %r15d,%edx
mov    %r13d,%ecx
mov    %r12d,%r8d
mov    0x4(%rsp),%r9d
call   1080 <process_handshake_client_hello@plt>
jmp    126c <process_handshake+0x10c>
lea    0xe9b(%rip),%rdi
xor    %eax,%eax
call   1040 <printf@plt>
test   %r12d,%r12d
je     132d <process_handshake+0x1cd>
lea    0xf39(%rip),%rdi
call   1030 <puts@plt>
mov    %rbx,%rdi
mov    %ebp,%esi
mov    %r15d,%edx
mov    %r13d,%ecx
mov    %r12d,%r8d
mov    0x4(%rsp),%r9d
call   1070 <process_handshake_server_hello@plt>
lea    0xf13(%rip),%rdi
jmp    12fd <process_handshake+0x19d>
mov    0x2d61(%rip),%rax
mov    (%rax),%edi
lea    0xe0f(%rip),%rsi
mov    %r14d,%edx
call   1050 <fprintf@plt>
jmp    1302 <process_handshake+0x1a2>
lea    0xe47(%rip),%rdi
jmp    12ea <process_handshake+0x18a>
lea    0xe51(%rip),%rdi
jmp    12ea <process_handshake+0x18a>
lea    0xe54(%rip),%rdi
jmp    12ea <process_handshake+0x18a>
lea    0xe5f(%rip),%rdi
jmp    12ea <process_handshake+0x18a>
lea    0xe6a(%rip),%rdi
jmp    12ea <process_handshake+0x18a>
lea    0xe6d(%rip),%rdi
jmp    12ea <process_handshake+0x18a>
lea    0xe77(%rip),%rdi
jmp    12ea <process_handshake+0x18a>
lea    0xe82(%rip),%rdi
jmp    12ea <process_handshake+0x18a>
lea    0xe82(%rip),%rdi
jmp    12ea <process_handshake+0x18a>
lea    0xe89(%rip),%rdi
xor    %eax,%eax
call   1040 <printf@plt>
test   %r12d,%r12d
je     1302 <process_handshake+0x1a2>
lea    0xd87(%rip),%rdi
call   1030 <puts@plt>
xor    %eax,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %rbx,%rdi
mov    %ebp,%esi
mov    %r15d,%edx
mov    %r13d,%ecx
xor    %r8d,%r8d
mov    0x4(%rsp),%r9d
call   1080 <process_handshake_client_hello@plt>
jmp    1302 <process_handshake+0x1a2>
mov    %rbx,%rdi
mov    %ebp,%esi
mov    %r15d,%edx
mov    %r13d,%ecx
xor    %r8d,%r8d
mov    0x4(%rsp),%r9d
call   1070 <process_handshake_server_hello@plt>
jmp    1302 <process_handshake+0x1a2>

LLVM IR (-O0):
%struct.handshake_message = type { i32 }
@.str = [22 x i8] c"Handshake length: %d\0A\00"
@.str.1 = [20 x i8] c"\22handshake_type\22: \22\00"
@.str.2 = [17 x i8] c"Handshake type: \00"
@stderr = global i32 0
@.str.3 = [33 x i8] c"ERROR: Unknown handshake type %d\00"
@.str.4 = [14 x i8] c"HELLO_REQUEST\00"
@.str.5 = [3 x i8] c"\22\0A\00"
@.str.6 = [13 x i8] c"CLIENT_HELLO\00"
@.str.7 = [24 x i8] c"\22, \22handshake_data\22: {\0A\00"
@.str.8 = [3 x i8] c"}\0A\00"
@.str.9 = [13 x i8] c"SERVER_HELLO\00"
@.str.10 = [19 x i8] c"NEW_SESSION_TICKET\00"
@.str.11 = [12 x i8] c"CERTIFICATE\00"
@.str.12 = [20 x i8] c"SERVER_KEY_EXCHANGE\00"
@.str.13 = [20 x i8] c"CERTIFICATE_REQUEST\00"
@.str.14 = [12 x i8] c"SERVER_DONE\00"
@.str.15 = [19 x i8] c"CERTIFICATE_VERIFY\00"
@.str.16 = [20 x i8] c"CLIENT_KEY_EXCHANGE\00"
@.str.17 = [9 x i8] c"FINISHED\00"
@.str.18 = [16 x i8] c"CERTIFICATE_URL\00"
@.str.19 = [19 x i8] c"CERTIFICATE_STATUS\00"
define %struct.handshake_message* @process_handshake(i8* %0, i32 %1, i32 %2, i32 %3, i32 %4) {
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i8*
%12 = alloca i32
%13 = alloca i32
store i8* %0, i8** %6
store i32 %1, i32* %7
store i32 %2, i32* %8
store i32 %3, i32* %9
store i32 %4, i32* %10
%14 = load i8*, i8** %6
store i8* %14, i8** %11
store i32 0, i32* %12
store i32 0, i32* %13
%15 = load i8*, i8** %11
%16 = load i32, i32* %7
%17 = add nsw i32 %16, 5
%18 = call i32 @read_uint(i8* %15, i32 %17, i32 1)
store i32 %18, i32* %12
%19 = load i8*, i8** %11
%20 = load i32, i32* %7
%21 = add nsw i32 %20, 5
%22 = add nsw i32 %21, 1
%23 = call i32 @read_uint(i8* %19, i32 %22, i32 3)
store i32 %23, i32* %13
%24 = load i32, i32* %9
%25 = icmp ne i32 %24, 0
br i1 %25, label %29, label %26
26: ; preds = %5
%27 = load i32, i32* %13
%28 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str, i64 0, i64 0), i32 %27)
br label %29
29: ; preds = %26, %5
%30 = load i32, i32* %9
%31 = icmp ne i32 %30, 0
br i1 %31, label %32, label %34
32: ; preds = %29
%33 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.1, i64 0, i64 0))
br label %36
34: ; preds = %29
%35 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.2, i64 0, i64 0))
br label %36
36: ; preds = %34, %32
%37 = load i32, i32* %12
switch i32 %37, label %38 [
i32 0, label %42
i32 1, label %49
i32 2, label %68
i32 4, label %87
i32 11, label %94
i32 12, label %101
i32 13, label %108
i32 14, label %115
i32 15, label %122
i32 16, label %129
i32 20, label %136
i32 21, label %143
i32 22, label %150
]
38: ; preds = %36
%39 = load i32, i32* @stderr
%40 = load i32, i32* %12
%41 = call i32 @fprintf(i32 %39, i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str.3, i64 0, i64 0), i32 %40)
br label %157
42: ; preds = %36
%43 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.4, i64 0, i64 0))
%44 = load i32, i32* %9
%45 = icmp ne i32 %44, 0
br i1 %45, label %46, label %48
46: ; preds = %42
%47 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0))
br label %48
48: ; preds = %46, %42
br label %157
49: ; preds = %36
%50 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.6, i64 0, i64 0))
%51 = load i32, i32* %9
%52 = icmp ne i32 %51, 0
br i1 %52, label %53, label %55
53: ; preds = %49
%54 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.7, i64 0, i64 0))
br label %55
55: ; preds = %53, %49
%56 = load i8*, i8** %11
%57 = load i32, i32* %7
%58 = load i32, i32* %8
%59 = load i32, i32* %13
%60 = load i32, i32* %9
%61 = load i32, i32* %10
%62 = call i32 @process_handshake_client_hello(i8* %56, i32 %57, i32 %58, i32 %59, i32 %60, i32 %61)
%63 = load i32, i32* %9
%64 = icmp ne i32 %63, 0
br i1 %64, label %65, label %67
65: ; preds = %55
%66 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.8, i64 0, i64 0))
br label %67
67: ; preds = %65, %55
br label %157
68: ; preds = %36
%69 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.9, i64 0, i64 0))
%70 = load i32, i32* %9
%71 = icmp ne i32 %70, 0
br i1 %71, label %72, label %74
72: ; preds = %68
%73 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.7, i64 0, i64 0))
br label %74
74: ; preds = %72, %68
%75 = load i8*, i8** %11
%76 = load i32, i32* %7
%77 = load i32, i32* %8
%78 = load i32, i32* %13
%79 = load i32, i32* %9
%80 = load i32, i32* %10
%81 = call i32 @process_handshake_server_hello(i8* %75, i32 %76, i32 %77, i32 %78, i32 %79, i32 %80)
%82 = load i32, i32* %9
%83 = icmp ne i32 %82, 0
br i1 %83, label %84, label %86
84: ; preds = %74
%85 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.8, i64 0, i64 0))
br label %86
86: ; preds = %84, %74
br label %157
87: ; preds = %36
%88 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.10, i64 0, i64 0))
%89 = load i32, i32* %9
%90 = icmp ne i32 %89, 0
br i1 %90, label %91, label %93
91: ; preds = %87
%92 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0))
br label %93
93: ; preds = %91, %87
br label %157
94: ; preds = %36
%95 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.11, i64 0, i64 0))
%96 = load i32, i32* %9
%97 = icmp ne i32 %96, 0
br i1 %97, label %98, label %100
98: ; preds = %94
%99 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0))
br label %100
100: ; preds = %98, %94
br label %157
101: ; preds = %36
%102 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.12, i64 0, i64 0))
%103 = load i32, i32* %9
%104 = icmp ne i32 %103, 0
br i1 %104, label %105, label %107
105: ; preds = %101
%106 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0))
br label %107
107: ; preds = %105, %101
br label %157
108: ; preds = %36
%109 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.13, i64 0, i64 0))
%110 = load i32, i32* %9
%111 = icmp ne i32 %110, 0
br i1 %111, label %112, label %114
112: ; preds = %108
%113 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0))
br label %114
114: ; preds = %112, %108
br label %157
115: ; preds = %36
%116 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.14, i64 0, i64 0))
%117 = load i32, i32* %9
%118 = icmp ne i32 %117, 0
br i1 %118, label %119, label %121
119: ; preds = %115
%120 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0))
br label %121
121: ; preds = %119, %115
br label %157
122: ; preds = %36
%123 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.15, i64 0, i64 0))
%124 = load i32, i32* %9
%125 = icmp ne i32 %124, 0
br i1 %125, label %126, label %128
126: ; preds = %122
%127 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0))
br label %128
128: ; preds = %126, %122
br label %157
129: ; preds = %36
%130 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.16, i64 0, i64 0))
%131 = load i32, i32* %9
%132 = icmp ne i32 %131, 0
br i1 %132, label %133, label %135
133: ; preds = %129
%134 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0))
br label %135
135: ; preds = %133, %129
br label %157
136: ; preds = %36
%137 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.17, i64 0, i64 0))
%138 = load i32, i32* %9
%139 = icmp ne i32 %138, 0
br i1 %139, label %140, label %142
140: ; preds = %136
%141 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0))
br label %142
142: ; preds = %140, %136
br label %157
143: ; preds = %36
%144 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.18, i64 0, i64 0))
%145 = load i32, i32* %9
%146 = icmp ne i32 %145, 0
br i1 %146, label %147, label %149
147: ; preds = %143
%148 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0))
br label %149
149: ; preds = %147, %143
br label %157
150: ; preds = %36
%151 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.19, i64 0, i64 0))
%152 = load i32, i32* %9
%153 = icmp ne i32 %152, 0
br i1 %153, label %154, label %156
154: ; preds = %150
%155 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.5, i64 0, i64 0))
br label %156
156: ; preds = %154, %150
br label %157
157: ; preds = %156, %149, %142, %135, %128, %121, %114, %107, %100, %93, %86, %67, %48, %38
ret %struct.handshake_message* null
}

LLVM IR (-O2):
%struct.handshake_message = type { i32 }
@.str = [22 x i8] c"Handshake length: %d\0A\00"
@.str.1 = [20 x i8] c"\22handshake_type\22: \22\00"
@.str.2 = [17 x i8] c"Handshake type: \00"
@stderr = global i32 0
@.str.3 = [33 x i8] c"ERROR: Unknown handshake type %d\00"
@.str.4 = [14 x i8] c"HELLO_REQUEST\00"
@.str.6 = [13 x i8] c"CLIENT_HELLO\00"
@.str.9 = [13 x i8] c"SERVER_HELLO\00"
@.str.10 = [19 x i8] c"NEW_SESSION_TICKET\00"
@.str.11 = [12 x i8] c"CERTIFICATE\00"
@.str.12 = [20 x i8] c"SERVER_KEY_EXCHANGE\00"
@.str.13 = [20 x i8] c"CERTIFICATE_REQUEST\00"
@.str.14 = [12 x i8] c"SERVER_DONE\00"
@.str.15 = [19 x i8] c"CERTIFICATE_VERIFY\00"
@.str.16 = [20 x i8] c"CLIENT_KEY_EXCHANGE\00"
@.str.17 = [9 x i8] c"FINISHED\00"
@.str.18 = [16 x i8] c"CERTIFICATE_URL\00"
@.str.19 = [19 x i8] c"CERTIFICATE_STATUS\00"
@str.31 = [2 x i8] c"}\00"
@str.32 = [23 x i8] c"\22, \22handshake_data\22: {\00"
@str.33 = [2 x i8] c"\22\00"
define noalias %struct.handshake_message* @process_handshake(i8* %0, i32 %1, i32 %2, i32 %3, i32 %4) {
%6 = add nsw i32 %1, 5
%7 = tail call i32 @read_uint(i8* %0, i32 %6, i32 1)
%8 = add nsw i32 %1, 6
%9 = tail call i32 @read_uint(i8* %0, i32 %8, i32 3)
%10 = icmp eq i32 %3, 0
br i1 %10, label %11, label %13
11: ; preds = %5
%12 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([22 x i8], [22 x i8]* @.str, i64 0, i64 0), i32 %9)
br label %13
13: ; preds = %5, %11
%14 = phi i8* [ getelementptr inbounds ([17 x i8], [17 x i8]* @.str.2, i64 0, i64 0), %11 ], [ getelementptr inbounds ([20 x i8], [20 x i8]* @.str.1, i64 0, i64 0), %5 ]
%15 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) %14)
switch i32 %7, label %16 [
i32 0, label %19
i32 1, label %23
i32 2, label %29
i32 4, label %35
i32 11, label %39
i32 12, label %43
i32 13, label %47
i32 14, label %51
i32 15, label %55
i32 16, label %59
i32 20, label %63
i32 21, label %67
i32 22, label %71
]
16: ; preds = %13
%17 = load i32, i32* @stderr
%18 = tail call i32 @fprintf(i32 %17, i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str.3, i64 0, i64 0), i32 %7)
br label %79
19: ; preds = %13
%20 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([14 x i8], [14 x i8]* @.str.4, i64 0, i64 0))
br i1 %10, label %79, label %21
21: ; preds = %19
%22 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.33, i64 0, i64 0))
br label %79
23: ; preds = %13
%24 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([13 x i8], [13 x i8]* @.str.6, i64 0, i64 0))
br i1 %10, label %75, label %25
25: ; preds = %23
%26 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([23 x i8], [23 x i8]* @str.32, i64 0, i64 0))
%27 = tail call i32 @process_handshake_client_hello(i8* %0, i32 %1, i32 %2, i32 %9, i32 %3, i32 %4)
%28 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.31, i64 0, i64 0))
br label %79
29: ; preds = %13
%30 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([13 x i8], [13 x i8]* @.str.9, i64 0, i64 0))
br i1 %10, label %77, label %31
31: ; preds = %29
%32 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([23 x i8], [23 x i8]* @str.32, i64 0, i64 0))
%33 = tail call i32 @process_handshake_server_hello(i8* %0, i32 %1, i32 %2, i32 %9, i32 %3, i32 %4)
%34 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.31, i64 0, i64 0))
br label %79
35: ; preds = %13
%36 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str.10, i64 0, i64 0))
br i1 %10, label %79, label %37
37: ; preds = %35
%38 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.33, i64 0, i64 0))
br label %79
39: ; preds = %13
%40 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([12 x i8], [12 x i8]* @.str.11, i64 0, i64 0))
br i1 %10, label %79, label %41
41: ; preds = %39
%42 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.33, i64 0, i64 0))
br label %79
43: ; preds = %13
%44 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @.str.12, i64 0, i64 0))
br i1 %10, label %79, label %45
45: ; preds = %43
%46 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.33, i64 0, i64 0))
br label %79
47: ; preds = %13
%48 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @.str.13, i64 0, i64 0))
br i1 %10, label %79, label %49
49: ; preds = %47
%50 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.33, i64 0, i64 0))
br label %79
51: ; preds = %13
%52 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([12 x i8], [12 x i8]* @.str.14, i64 0, i64 0))
br i1 %10, label %79, label %53
53: ; preds = %51
%54 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.33, i64 0, i64 0))
br label %79
55: ; preds = %13
%56 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str.15, i64 0, i64 0))
br i1 %10, label %79, label %57
57: ; preds = %55
%58 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.33, i64 0, i64 0))
br label %79
59: ; preds = %13
%60 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @.str.16, i64 0, i64 0))
br i1 %10, label %79, label %61
61: ; preds = %59
%62 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.33, i64 0, i64 0))
br label %79
63: ; preds = %13
%64 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([9 x i8], [9 x i8]* @.str.17, i64 0, i64 0))
br i1 %10, label %79, label %65
65: ; preds = %63
%66 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.33, i64 0, i64 0))
br label %79
67: ; preds = %13
%68 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([16 x i8], [16 x i8]* @.str.18, i64 0, i64 0))
br i1 %10, label %79, label %69
69: ; preds = %67
%70 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.33, i64 0, i64 0))
br label %79
71: ; preds = %13
%72 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str.19, i64 0, i64 0))
br i1 %10, label %79, label %73
73: ; preds = %71
%74 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str.33, i64 0, i64 0))
br label %79
75: ; preds = %23
%76 = tail call i32 @process_handshake_client_hello(i8* %0, i32 %1, i32 %2, i32 %9, i32 0, i32 %4)
br label %79
77: ; preds = %29
%78 = tail call i32 @process_handshake_server_hello(i8* %0, i32 %1, i32 %2, i32 %9, i32 0, i32 %4)
br label %79
79: ; preds = %77, %75, %71, %73, %67, %69, %63, %65, %59, %61, %55, %57, %51, %53, %47, %49, %43, %45, %39, %41, %35, %37, %31, %25, %19, %21, %16
ret %struct.handshake_message* null
}