#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 sockaddr_in {
  int /*<<< orphan*/ sin_addr;
  int /*<<< orphan*/ sin_port;
  int /*<<< orphan*/ sin_family;
};
struct sockaddr {
  int dummy;
};
typedef int /*<<< orphan*/ ssize_t;
typedef int socklen_t;
typedef int /*<<< orphan*/ servaddr;
typedef int /*<<< orphan*/ sendbuff;
typedef int /*<<< orphan*/ pathmtu;
typedef int /*<<< orphan*/ ip_mtu_disc_opt;

/* Variables and functions */
int /*<<< orphan*/ AF_INET;
int /*<<< orphan*/ EXIT_FAILURE;
int /*<<< orphan*/ IPPROTO_IP;
int /*<<< orphan*/ IPPROTO_TCP;
int /*<<< orphan*/ IP_MTU;
int /*<<< orphan*/ IP_MTU_DISCOVER;
int /*<<< orphan*/ SOCK_STREAM;
scalar_t__ connect(int, struct sockaddr *, int);
int /*<<< orphan*/ exit(int /*<<< orphan*/);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, ...);
char getchar();
scalar_t__ getsockopt(int, int /*<<< orphan*/, int /*<<< orphan*/, int *,
                      int *);
int /*<<< orphan*/ htons(int);
int inet_pton(int /*<<< orphan*/, char *, int /*<<< orphan*/ *);
int /*<<< orphan*/ perror(char *);
int /*<<< orphan*/ printf(char *, ...);
int /*<<< orphan*/ send(int, char *, int, int /*<<< orphan*/);
scalar_t__ setsockopt(int, int /*<<< orphan*/, int /*<<< orphan*/, int *, int);
int socket(int /*<<< orphan*/, int /*<<< orphan*/, int /*<<< orphan*/);
int /*<<< orphan*/ stderr;
int main(int argc, char *argv[]) {
  if (argc < 3) {
    fprintf(
        stderr,
        "Usage: %s IP { Y | N } (Y = Perform PMTUD, N = Don't perform PMTUD)\n",
        argv[0]);
    exit(EXIT_FAILURE);
  }
  if (argv[2][0] != 'Y' && argv[2][0] != 'N') {
    fprintf(stderr, "Please enter Y or N\n");
    exit(EXIT_FAILURE);
  }
  static char sendbuff[5000];
  size_t i;
  for (i = 0; i < sizeof(sendbuff); i++) {
    sendbuff[i] = 'a' + i % 26;
  }
  struct sockaddr_in servaddr;
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(12000);
  int s = inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
  if (s <= 0) {
    if (s == 0) {
      fprintf(stderr, "Invalid server IP: %s\n", argv[1]);
      exit(EXIT_FAILURE);
    } else {
      perror("inet_pton(3) error");
      exit(EXIT_FAILURE);
    }
  }
  int sockfd;
  if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
    perror("socket(2) error");
    exit(EXIT_FAILURE);
  }
  int ip_mtu_disc_opt = 1;
  if (argv[1][0] == 'N') {
    ip_mtu_disc_opt = 0;
  }
  if (setsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &ip_mtu_disc_opt,
                 sizeof(ip_mtu_disc_opt)) < 0) {
    perror("setsockopt(2) error");
    exit(EXIT_FAILURE);
  }
  if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
    perror("Connection error");
    exit(EXIT_FAILURE);
  }
  while (1) {
    int pathmtu;
    socklen_t pathmtusz = sizeof(pathmtu);
    if (getsockopt(sockfd, IPPROTO_IP, IP_MTU, &pathmtu, &pathmtusz) < 0) {
      perror("getsockopt(2) error");
    } else {
      printf("Top of main loop; Path MTU = %d\n", pathmtu);
    }
    ssize_t sent = send(sockfd, sendbuff, sizeof(sendbuff), 0);
    if (sent < 0) {
      perror("send(2) error");
      exit(EXIT_FAILURE);
    }
    printf("*** Sent %zd bytes\n", sent);
    printf("Press Q to quit; return to continue\n");
    if (getchar() == 'Q') {
      break;
    }
  }
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
cmpl   $0x3,-0x8(%rbp)
jge    120c <main+0x4c>
mov    0x2dd9(%rip),%rax
mov    (%rax),%edi
mov    -0x10(%rbp),%rax
mov    (%rax),%rdx
lea    0xe09(%rip),%rsi
mov    $0x0,%al
call   1090 <fprintf@plt>
mov    0x2da3(%rip),%rax
mov    (%rax),%edi
call   10c0 <exit@plt>
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rax
movsbl (%rax),%eax
cmp    $0x59,%eax
je     1259 <main+0x99>
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rax
movsbl (%rax),%eax
cmp    $0x4e,%eax
je     1259 <main+0x99>
mov    0x2d85(%rip),%rax
mov    (%rax),%edi
lea    0xe01(%rip),%rsi
mov    $0x0,%al
call   1090 <fprintf@plt>
mov    0x2d56(%rip),%rax
mov    (%rax),%edi
call   10c0 <exit@plt>
movq   $0x0,-0x18(%rbp)
cmpq   $0x1388,-0x18(%rbp)
jae    12a0 <main+0xe0>
mov    -0x18(%rbp),%rax
mov    $0x1a,%ecx
xor    %edx,%edx
div    %rcx
add    $0x61,%rdx
mov    -0x18(%rbp),%rcx
lea    0x2e14(%rip),%rax
mov    %dl,(%rax,%rcx,1)
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    1261 <main+0xa1>
mov    0x2d39(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x20(%rbp)
mov    $0x2ee0,%edi
call   1040 <htons@plt>
mov    %eax,-0x24(%rbp)
mov    0x2d20(%rip),%rax
mov    (%rax),%edi
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rsi
lea    -0x28(%rbp),%rdx
call   10a0 <inet_pton@plt>
mov    %eax,-0x2c(%rbp)
cmpl   $0x0,-0x2c(%rbp)
jg     1331 <main+0x171>
cmpl   $0x0,-0x2c(%rbp)
jne    1317 <main+0x157>
mov    0x2ccf(%rip),%rax
mov    (%rax),%edi
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdx
lea    0xd58(%rip),%rsi
mov    $0x0,%al
call   1090 <fprintf@plt>
mov    0x2c98(%rip),%rax
mov    (%rax),%edi
call   10c0 <exit@plt>
lea    0xd53(%rip),%rdi
call   10b0 <perror@plt>
mov    0x2c7e(%rip),%rax
mov    (%rax),%edi
call   10c0 <exit@plt>
mov    0x2ca8(%rip),%rax
mov    (%rax),%edi
mov    0x2c77(%rip),%rax
mov    (%rax),%esi
mov    0x2c86(%rip),%rax
mov    (%rax),%edx
call   10e0 <socket@plt>
mov    %eax,-0x30(%rbp)
cmp    $0x0,%eax
jge    1377 <main+0x1b7>
lea    0xd20(%rip),%rdi
call   10b0 <perror@plt>
mov    0x2c38(%rip),%rax
mov    (%rax),%edi
call   10c0 <exit@plt>
movl   $0x1,-0x34(%rbp)
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rax
movsbl (%rax),%eax
cmp    $0x4e,%eax
jne    1399 <main+0x1d9>
movl   $0x0,-0x34(%rbp)
mov    -0x30(%rbp),%edi
mov    0x2c35(%rip),%rax
mov    (%rax),%esi
mov    0x2c44(%rip),%rax
mov    (%rax),%edx
lea    -0x34(%rbp),%rcx
mov    $0x4,%r8d
call   1030 <setsockopt@plt>
cmp    $0x0,%rax
jge    13e1 <main+0x221>
lea    0xcc6(%rip),%rdi
call   10b0 <perror@plt>
mov    0x2bce(%rip),%rax
mov    (%rax),%edi
call   10c0 <exit@plt>
mov    -0x30(%rbp),%edi
lea    -0x28(%rbp),%rsi
mov    $0xc,%edx
call   10d0 <connect@plt>
cmp    $0x0,%rax
jge    1416 <main+0x256>
lea    0xca5(%rip),%rdi
call   10b0 <perror@plt>
mov    0x2b99(%rip),%rax
mov    (%rax),%edi
call   10c0 <exit@plt>
jmp    141b <main+0x25b>
movl   $0x4,-0x3c(%rbp)
mov    -0x30(%rbp),%edi
mov    0x2bac(%rip),%rax
mov    (%rax),%esi
mov    0x2b7b(%rip),%rax
mov    (%rax),%edx
lea    -0x38(%rbp),%rcx
lea    -0x3c(%rbp),%r8
call   1070 <getsockopt@plt>
cmp    $0x0,%rax
jge    145f <main+0x29f>
lea    0xc64(%rip),%rdi
call   10b0 <perror@plt>
jmp    1470 <main+0x2b0>
mov    -0x38(%rbp),%esi
lea    0xc64(%rip),%rdi
mov    $0x0,%al
call   1060 <printf@plt>
mov    -0x30(%rbp),%edi
lea    0x2c26(%rip),%rsi
mov    $0x1388,%edx
xor    %ecx,%ecx
call   1050 <send@plt>
mov    %eax,-0x40(%rbp)
cmpl   $0x0,-0x40(%rbp)
jge    14ad <main+0x2ed>
lea    0xc54(%rip),%rdi
call   10b0 <perror@plt>
mov    0x2b02(%rip),%rax
mov    (%rax),%edi
call   10c0 <exit@plt>
mov    -0x40(%rbp),%esi
lea    0xc45(%rip),%rdi
mov    $0x0,%al
call   1060 <printf@plt>
lea    0xc4b(%rip),%rdi
mov    $0x0,%al
call   1060 <printf@plt>
mov    $0x0,%al
call   1080 <getchar@plt>
movsbl %al,%eax
cmp    $0x51,%eax
jne    14e4 <main+0x324>
jmp    14e9 <main+0x329>
jmp    141b <main+0x25b>
xor    %eax,%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %rsi,%rbx
cmp    $0x2,%edi
jle    148b <main+0x2bb>
mov    0x10(%rbx),%rax
mov    (%rax),%al
cmp    $0x59,%al
je     11fc <main+0x2c>
cmp    $0x4e,%al
jne    14da <main+0x30a>
movdqa 0xdfc(%rip),%xmm5
movdqa 0xe04(%rip),%xmm4
mov    $0x10,%eax
movdqa 0xe07(%rip),%xmm2
movdqa 0xe0f(%rip),%xmm3
movdqa 0xe16(%rip),%xmm8
lea    0x2e7f(%rip),%rcx
movdqa 0xe16(%rip),%xmm9
movdqa 0xe1e(%rip),%xmm6
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movdqa %xmm4,%xmm7
pmulhuw %xmm2,%xmm7
psrlw  $0x3,%xmm7
pmullw %xmm3,%xmm7
movdqa %xmm4,%xmm1
psubw  %xmm7,%xmm1
movdqa %xmm5,%xmm7
pmulhuw %xmm2,%xmm7
psrlw  $0x3,%xmm7
pmullw %xmm3,%xmm7
movdqa %xmm5,%xmm0
psubw  %xmm7,%xmm0
packuswb %xmm0,%xmm1
paddb  %xmm8,%xmm1
movdqa %xmm1,-0x10(%rax,%rcx,1)
movdqa %xmm5,%xmm0
paddw  %xmm9,%xmm0
movdqa %xmm4,%xmm1
paddw  %xmm9,%xmm1
movdqa %xmm1,%xmm7
pmulhuw %xmm2,%xmm7
psrlw  $0x3,%xmm7
pmullw %xmm3,%xmm7
psubw  %xmm7,%xmm1
movdqa %xmm0,%xmm7
pmulhuw %xmm2,%xmm7
psrlw  $0x3,%xmm7
pmullw %xmm3,%xmm7
psubw  %xmm7,%xmm0
packuswb %xmm0,%xmm1
paddb  %xmm8,%xmm1
movdqa %xmm1,(%rax,%rcx,1)
paddw  %xmm6,%xmm4
paddw  %xmm6,%xmm5
add    $0x20,%rax
cmp    $0x1390,%rax
jne    1250 <main+0x80>
movabs $0x6867666564636261,%rax
66 67 68
mov    %rax,0x412c(%rip)
mov    0x2cd5(%rip),%rbp
mov    0x0(%rbp),%eax
mov    %eax,0x20(%rsp)
mov    $0x2ee0,%edi
call   1050 <htons@plt>
mov    %eax,0x1c(%rsp)
mov    0x0(%rbp),%edi
mov    0x8(%rbx),%rsi
lea    0x18(%rsp),%rdx
call   10b0 <inet_pton@plt>
test   %eax,%eax
jle    14a0 <main+0x2d0>
mov    0x0(%rbp),%edi
mov    0x2c75(%rip),%rax
mov    (%rax),%esi
mov    0x2c84(%rip),%rax
mov    (%rax),%edx
call   10f0 <socket@plt>
test   %eax,%eax
js     14bf <main+0x2ef>
mov    %eax,%ebp
mov    0x8(%rbx),%rax
xor    %ecx,%ecx
cmpb   $0x4e,(%rax)
setne  %cl
mov    %ecx,0x14(%rsp)
mov    0x2c64(%rip),%rax
mov    (%rax),%esi
mov    0x2c73(%rip),%rax
mov    (%rax),%edx
lea    0x14(%rsp),%rcx
mov    %ebp,%edi
mov    $0x4,%r8d
call   1040 <setsockopt@plt>
test   %rax,%rax
js     14c8 <main+0x2f8>
lea    0x18(%rsp),%rsi
mov    %ebp,%edi
mov    $0xc,%edx
call   10e0 <connect@plt>
test   %rax,%rax
js     14d1 <main+0x301>
lea    0xc(%rsp),%r12
lea    0x2cf0(%rip),%r13
lea    0xda5(%rip),%rbx
lea    0xdb2(%rip),%r15
lea    0xd68(%rip),%r14
cs nopw 0x0(%rax,%rax,1)
nop
movl   $0x4,0xc(%rsp)
mov    0x2be9(%rip),%rax
mov    (%rax),%esi
mov    0x2bb8(%rip),%rax
mov    (%rax),%edx
mov    %ebp,%edi
lea    0x10(%rsp),%rcx
mov    %r12,%r8
call   1080 <getsockopt@plt>
test   %rax,%rax
js     1452 <main+0x282>
mov    0x10(%rsp),%esi
mov    %r14,%rdi
xor    %eax,%eax
call   1070 <printf@plt>
mov    %ebp,%edi
mov    %r13,%rsi
mov    $0x1388,%edx
xor    %ecx,%ecx
call   1060 <send@plt>
test   %eax,%eax
js     1471 <main+0x2a1>
mov    %rbx,%rdi
mov    %eax,%esi
xor    %eax,%eax
call   1070 <printf@plt>
mov    %r15,%rdi
call   1030 <puts@plt>
xor    %eax,%eax
call   1090 <getchar@plt>
cmp    $0x51,%al
jne    13e0 <main+0x210>
jmp    1460 <main+0x290>
lea    0xcd0(%rip),%rdi
call   10c0 <perror@plt>
jmp    141c <main+0x24c>
xor    %eax,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
lea    0xce6(%rip),%rdi
call   10c0 <perror@plt>
mov    0x2b24(%rip),%rax
mov    (%rax),%edi
call   10d0 <exit@plt>
mov    0x2b2e(%rip),%rax
mov    (%rax),%edi
mov    (%rbx),%rdx
lea    0xbd2(%rip),%rsi
jmp    14b6 <main+0x2e6>
jne    14f3 <main+0x323>
mov    0x2b17(%rip),%rax
mov    (%rax),%edi
mov    0x8(%rbx),%rdx
lea    0xc14(%rip),%rsi
xor    %eax,%eax
call   10a0 <fprintf@plt>
jmp    147d <main+0x2ad>
lea    0xc2e(%rip),%rdi
jmp    1478 <main+0x2a8>
lea    0xc35(%rip),%rdi
jmp    1478 <main+0x2a8>
lea    0xc40(%rip),%rdi
jmp    1478 <main+0x2a8>
mov    0x2adf(%rip),%rax
mov    (%rax),%edi
lea    0xbcb(%rip),%rsi
xor    %eax,%eax
call   10a0 <fprintf@plt>
jmp    147d <main+0x2ad>
lea    0xbe7(%rip),%rdi
jmp    1478 <main+0x2a8>

LLVM IR (-O0):
%struct.sockaddr_in = type { i32, i32, i32 }
%struct.sockaddr = type { i32 }
@stderr = global i32 0
@.str = [69 x i8] c"Usage: %s IP { Y | N } (Y = Perform PMTUD, N = Don't perform PMTUD)\0A\00"
@EXIT_FAILURE = global i32 0
@.str.1 = [21 x i8] c"Please enter Y or N\0A\00"
@main.sendbuff = internal global [5000 x i8] zeroinitializer
@AF_INET = global i32 0
@.str.2 = [23 x i8] c"Invalid server IP: %s\0A\00"
@.str.3 = [19 x i8] c"inet_pton(3) error\00"
@SOCK_STREAM = global i32 0
@IPPROTO_TCP = global i32 0
@.str.4 = [16 x i8] c"socket(2) error\00"
@IPPROTO_IP = global i32 0
@IP_MTU_DISCOVER = global i32 0
@.str.5 = [20 x i8] c"setsockopt(2) error\00"
@.str.6 = [17 x i8] c"Connection error\00"
@IP_MTU = global i32 0
@.str.7 = [20 x i8] c"getsockopt(2) error\00"
@.str.8 = [33 x i8] c"Top of main loop; Path MTU = %d\0A\00"
@.str.9 = [14 x i8] c"send(2) error\00"
@.str.10 = [20 x i8] c"*** Sent %zd bytes\0A\00"
@.str.11 = [37 x i8] c"Press Q to quit; return to continue\0A\00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca i64
%7 = alloca %struct.sockaddr_in
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%14 = load i32, i32* %4
%15 = icmp slt i32 %14, 3
br i1 %15, label %16, label %24
16: ; preds = %2
%17 = load i32, i32* @stderr
%18 = load i8**, i8*** %5
%19 = getelementptr inbounds i8*, i8** %18, i64 0
%20 = load i8*, i8** %19
%21 = call i32 (i32, i8*, ...) @fprintf(i32 %17, i8* getelementptr inbounds ([69 x i8], [69 x i8]* @.str, i64 0, i64 0), i8* %20)
%22 = load i32, i32* @EXIT_FAILURE
%23 = call i32 @exit(i32 %22)
unreachable
24: ; preds = %2
%25 = load i8**, i8*** %5
%26 = getelementptr inbounds i8*, i8** %25, i64 2
%27 = load i8*, i8** %26
%28 = getelementptr inbounds i8, i8* %27, i64 0
%29 = load i8, i8* %28
%30 = sext i8 %29 to i32
%31 = icmp ne i32 %30, 89
br i1 %31, label %32, label %45
32: ; preds = %24
%33 = load i8**, i8*** %5
%34 = getelementptr inbounds i8*, i8** %33, i64 2
%35 = load i8*, i8** %34
%36 = getelementptr inbounds i8, i8* %35, i64 0
%37 = load i8, i8* %36
%38 = sext i8 %37 to i32
%39 = icmp ne i32 %38, 78
br i1 %39, label %40, label %45
40: ; preds = %32
%41 = load i32, i32* @stderr
%42 = call i32 (i32, i8*, ...) @fprintf(i32 %41, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0))
%43 = load i32, i32* @EXIT_FAILURE
%44 = call i32 @exit(i32 %43)
unreachable
45: ; preds = %32, %24
store i64 0, i64* %6
br label %46
46: ; preds = %56, %45
%47 = load i64, i64* %6
%48 = icmp ult i64 %47, 5000
br i1 %48, label %49, label %59
49: ; preds = %46
%50 = load i64, i64* %6
%51 = urem i64 %50, 26
%52 = add i64 97, %51
%53 = trunc i64 %52 to i8
%54 = load i64, i64* %6
%55 = getelementptr inbounds [5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 %54
store i8 %53, i8* %55
br label %56
56: ; preds = %49
%57 = load i64, i64* %6
%58 = add i64 %57, 1
store i64 %58, i64* %6
br label %46
59: ; preds = %46
%60 = load i32, i32* @AF_INET
%61 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %7, i32 0, i32 2
store i32 %60, i32* %61
%62 = call i32 @htons(i32 12000)
%63 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %7, i32 0, i32 1
store i32 %62, i32* %63
%64 = load i32, i32* @AF_INET
%65 = load i8**, i8*** %5
%66 = getelementptr inbounds i8*, i8** %65, i64 1
%67 = load i8*, i8** %66
%68 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %7, i32 0, i32 0
%69 = call i32 @inet_pton(i32 %64, i8* %67, i32* %68)
store i32 %69, i32* %8
%70 = load i32, i32* %8
%71 = icmp sle i32 %70, 0
br i1 %71, label %72, label %87
72: ; preds = %59
%73 = load i32, i32* %8
%74 = icmp eq i32 %73, 0
br i1 %74, label %75, label %83
75: ; preds = %72
%76 = load i32, i32* @stderr
%77 = load i8**, i8*** %5
%78 = getelementptr inbounds i8*, i8** %77, i64 1
%79 = load i8*, i8** %78
%80 = call i32 (i32, i8*, ...) @fprintf(i32 %76, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.2, i64 0, i64 0), i8* %79)
%81 = load i32, i32* @EXIT_FAILURE
%82 = call i32 @exit(i32 %81)
unreachable
83: ; preds = %72
%84 = call i32 @perror(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.3, i64 0, i64 0))
%85 = load i32, i32* @EXIT_FAILURE
%86 = call i32 @exit(i32 %85)
unreachable
87: ; preds = %59
%88 = load i32, i32* @AF_INET
%89 = load i32, i32* @SOCK_STREAM
%90 = load i32, i32* @IPPROTO_TCP
%91 = call i32 @socket(i32 %88, i32 %89, i32 %90)
store i32 %91, i32* %9
%92 = icmp slt i32 %91, 0
br i1 %92, label %93, label %97
93: ; preds = %87
%94 = call i32 @perror(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.4, i64 0, i64 0))
%95 = load i32, i32* @EXIT_FAILURE
%96 = call i32 @exit(i32 %95)
unreachable
97: ; preds = %87
store i32 1, i32* %10
%98 = load i8**, i8*** %5
%99 = getelementptr inbounds i8*, i8** %98, i64 1
%100 = load i8*, i8** %99
%101 = getelementptr inbounds i8, i8* %100, i64 0
%102 = load i8, i8* %101
%103 = sext i8 %102 to i32
%104 = icmp eq i32 %103, 78
br i1 %104, label %105, label %106
105: ; preds = %97
store i32 0, i32* %10
br label %106
106: ; preds = %105, %97
%107 = load i32, i32* %9
%108 = load i32, i32* @IPPROTO_IP
%109 = load i32, i32* @IP_MTU_DISCOVER
%110 = call i64 @setsockopt(i32 %107, i32 %108, i32 %109, i32* %10, i32 4)
%111 = icmp slt i64 %110, 0
br i1 %111, label %112, label %116
112: ; preds = %106
%113 = call i32 @perror(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.5, i64 0, i64 0))
%114 = load i32, i32* @EXIT_FAILURE
%115 = call i32 @exit(i32 %114)
unreachable
116: ; preds = %106
%117 = load i32, i32* %9
%118 = bitcast %struct.sockaddr_in* %7 to %struct.sockaddr*
%119 = call i64 @connect(i32 %117, %struct.sockaddr* %118, i32 12)
%120 = icmp slt i64 %119, 0
br i1 %120, label %121, label %125
121: ; preds = %116
%122 = call i32 @perror(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.6, i64 0, i64 0))
%123 = load i32, i32* @EXIT_FAILURE
%124 = call i32 @exit(i32 %123)
unreachable
125: ; preds = %116
br label %126
126: ; preds = %125, %154
store i32 4, i32* %12
%127 = load i32, i32* %9
%128 = load i32, i32* @IPPROTO_IP
%129 = load i32, i32* @IP_MTU
%130 = call i64 @getsockopt(i32 %127, i32 %128, i32 %129, i32* %11, i32* %12)
%131 = icmp slt i64 %130, 0
br i1 %131, label %132, label %134
132: ; preds = %126
%133 = call i32 @perror(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.7, i64 0, i64 0))
br label %137
134: ; preds = %126
%135 = load i32, i32* %11
%136 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str.8, i64 0, i64 0), i32 %135)
br label %137
137: ; preds = %134, %132
%138 = load i32, i32* %9
%139 = call i32 @send(i32 %138, i8* getelementptr inbounds ([5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 0), i32 5000, i32 0)
store i32 %139, i32* %13
%140 = load i32, i32* %13
%141 = icmp slt i32 %140, 0
br i1 %141, label %142, label %146
142: ; preds = %137
%143 = call i32 @perror(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.9, i64 0, i64 0))
%144 = load i32, i32* @EXIT_FAILURE
%145 = call i32 @exit(i32 %144)
unreachable
146: ; preds = %137
%147 = load i32, i32* %13
%148 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.10, i64 0, i64 0), i32 %147)
%149 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([37 x i8], [37 x i8]* @.str.11, i64 0, i64 0))
%150 = call signext i8 (...) @getchar()
%151 = sext i8 %150 to i32
%152 = icmp eq i32 %151, 81
br i1 %152, label %153, label %154
153: ; preds = %146
br label %155
154: ; preds = %146
br label %126
155: ; preds = %153
ret i32 0
}

LLVM IR (-O2):
%struct.sockaddr_in = type { i32, i32, i32 }
%struct.sockaddr = type { i32 }
@stderr = global i32 0
@.str = [69 x i8] c"Usage: %s IP { Y | N } (Y = Perform PMTUD, N = Don't perform PMTUD)\0A\00"
@EXIT_FAILURE = global i32 0
@.str.1 = [21 x i8] c"Please enter Y or N\0A\00"
@main.sendbuff = internal global [5000 x i8] zeroinitializer
@AF_INET = global i32 0
@.str.2 = [23 x i8] c"Invalid server IP: %s\0A\00"
@.str.3 = [19 x i8] c"inet_pton(3) error\00"
@SOCK_STREAM = global i32 0
@IPPROTO_TCP = global i32 0
@.str.4 = [16 x i8] c"socket(2) error\00"
@IPPROTO_IP = global i32 0
@IP_MTU_DISCOVER = global i32 0
@.str.5 = [20 x i8] c"setsockopt(2) error\00"
@.str.6 = [17 x i8] c"Connection error\00"
@IP_MTU = global i32 0
@.str.7 = [20 x i8] c"getsockopt(2) error\00"
@.str.8 = [33 x i8] c"Top of main loop; Path MTU = %d\0A\00"
@.str.9 = [14 x i8] c"send(2) error\00"
@.str.10 = [20 x i8] c"*** Sent %zd bytes\0A\00"
@str = [36 x i8] c"Press Q to quit; return to continue\00"
define i32 @main(i32 %0, i8** nocapture %1) {
%3 = alloca %struct.sockaddr_in
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = icmp slt i32 %0, 3
br i1 %7, label %8, label %14
8: ; preds = %2
%9 = load i32, i32* @stderr
%10 = load i8*, i8** %1
%11 = tail call i32 (i32, i8*, ...) @fprintf(i32 %9, i8* getelementptr inbounds ([69 x i8], [69 x i8]* @.str, i64 0, i64 0), i8* %10)
%12 = load i32, i32* @EXIT_FAILURE
%13 = tail call i32 @exit(i32 %12)
unreachable
14: ; preds = %2
%15 = getelementptr inbounds i8*, i8** %1, i64 2
%16 = load i8*, i8** %15
%17 = load i8, i8* %16
switch i8 %17, label %19 [
i8 89, label %18
i8 78, label %18
]
18: ; preds = %14, %14
br label %24
19: ; preds = %14
%20 = load i32, i32* @stderr
%21 = tail call i32 (i32, i8*, ...) @fprintf(i32 %20, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0))
%22 = load i32, i32* @EXIT_FAILURE
%23 = tail call i32 @exit(i32 %22)
unreachable
24: ; preds = %24, %18
%25 = phi i64 [ 0, %18 ], [ %39, %24 ]
%26 = phi <16 x i16> [ <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>, %18 ], [ %40, %24 ]
%27 = urem <16 x i16> %26, <i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26>
%28 = trunc <16 x i16> %27 to <16 x i8>
%29 = add nuw nsw <16 x i8> %28, <i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97>
%30 = getelementptr inbounds [5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 %25
%31 = bitcast i8* %30 to <16 x i8>*
store <16 x i8> %29, <16 x i8>* %31
%32 = or i64 %25, 16
%33 = add <16 x i16> %26, <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>
%34 = urem <16 x i16> %33, <i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26>
%35 = trunc <16 x i16> %34 to <16 x i8>
%36 = add nuw nsw <16 x i8> %35, <i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97, i8 97>
%37 = getelementptr inbounds [5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 %32
%38 = bitcast i8* %37 to <16 x i8>*
store <16 x i8> %36, <16 x i8>* %38
%39 = add nuw nsw i64 %25, 32
%40 = add <16 x i16> %26, <i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32, i16 32>
%41 = icmp eq i64 %39, 4992
br i1 %41, label %42, label %24
42: ; preds = %24
store i8 97, i8* getelementptr inbounds ([5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 4992)
store i8 98, i8* getelementptr inbounds ([5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 4993)
store i8 99, i8* getelementptr inbounds ([5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 4994)
store i8 100, i8* getelementptr inbounds ([5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 4995)
store i8 101, i8* getelementptr inbounds ([5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 4996)
store i8 102, i8* getelementptr inbounds ([5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 4997)
store i8 103, i8* getelementptr inbounds ([5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 4998)
store i8 104, i8* getelementptr inbounds ([5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 4999)
%43 = bitcast %struct.sockaddr_in* %3 to i8*
%44 = load i32, i32* @AF_INET
%45 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %3, i64 0, i32 2
store i32 %44, i32* %45
%46 = tail call i32 @htons(i32 12000)
%47 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %3, i64 0, i32 1
store i32 %46, i32* %47
%48 = load i32, i32* @AF_INET
%49 = getelementptr inbounds i8*, i8** %1, i64 1
%50 = load i8*, i8** %49
%51 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %3, i64 0, i32 0
%52 = call i32 @inet_pton(i32 %48, i8* %50, i32* %51)
%53 = icmp slt i32 %52, 1
br i1 %53, label %54, label %66
54: ; preds = %42
%55 = icmp eq i32 %52, 0
br i1 %55, label %56, label %62
56: ; preds = %54
%57 = load i32, i32* @stderr
%58 = load i8*, i8** %49
%59 = call i32 (i32, i8*, ...) @fprintf(i32 %57, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.2, i64 0, i64 0), i8* %58)
%60 = load i32, i32* @EXIT_FAILURE
%61 = call i32 @exit(i32 %60)
unreachable
62: ; preds = %54
%63 = call i32 @perror(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.3, i64 0, i64 0))
%64 = load i32, i32* @EXIT_FAILURE
%65 = call i32 @exit(i32 %64)
unreachable
66: ; preds = %42
%67 = load i32, i32* @AF_INET
%68 = load i32, i32* @SOCK_STREAM
%69 = load i32, i32* @IPPROTO_TCP
%70 = call i32 @socket(i32 %67, i32 %68, i32 %69)
%71 = icmp slt i32 %70, 0
br i1 %71, label %72, label %76
72: ; preds = %66
%73 = call i32 @perror(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.4, i64 0, i64 0))
%74 = load i32, i32* @EXIT_FAILURE
%75 = call i32 @exit(i32 %74)
unreachable
76: ; preds = %66
%77 = bitcast i32* %4 to i8*
%78 = load i8*, i8** %49
%79 = load i8, i8* %78
%80 = icmp ne i8 %79, 78
%81 = zext i1 %80 to i32
store i32 %81, i32* %4
%82 = load i32, i32* @IPPROTO_IP
%83 = load i32, i32* @IP_MTU_DISCOVER
%84 = call i64 @setsockopt(i32 %70, i32 %82, i32 %83, i32* %4, i32 4)
%85 = icmp slt i64 %84, 0
br i1 %85, label %86, label %90
86: ; preds = %76
%87 = call i32 @perror(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.5, i64 0, i64 0))
%88 = load i32, i32* @EXIT_FAILURE
%89 = call i32 @exit(i32 %88)
unreachable
90: ; preds = %76
%91 = bitcast %struct.sockaddr_in* %3 to %struct.sockaddr*
%92 = call i64 @connect(i32 %70, %struct.sockaddr* %91, i32 12)
%93 = icmp slt i64 %92, 0
br i1 %93, label %97, label %94
94: ; preds = %90
%95 = bitcast i32* %5 to i8*
%96 = bitcast i32* %6 to i8*
br label %101
97: ; preds = %90
%98 = call i32 @perror(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.6, i64 0, i64 0))
%99 = load i32, i32* @EXIT_FAILURE
%100 = call i32 @exit(i32 %99)
unreachable
101: ; preds = %94, %118
store i32 4, i32* %6
%102 = load i32, i32* @IPPROTO_IP
%103 = load i32, i32* @IP_MTU
%104 = call i64 @getsockopt(i32 %70, i32 %102, i32 %103, i32* %5, i32* %6)
%105 = icmp slt i64 %104, 0
br i1 %105, label %106, label %108
106: ; preds = %101
%107 = call i32 @perror(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.7, i64 0, i64 0))
br label %111
108: ; preds = %101
%109 = load i32, i32* %5
%110 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([33 x i8], [33 x i8]* @.str.8, i64 0, i64 0), i32 %109)
br label %111
111: ; preds = %108, %106
%112 = call i32 @send(i32 %70, i8* getelementptr inbounds ([5000 x i8], [5000 x i8]* @main.sendbuff, i64 0, i64 0), i32 5000, i32 0)
%113 = icmp slt i32 %112, 0
br i1 %113, label %114, label %118
114: ; preds = %111
%115 = call i32 @perror(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.9, i64 0, i64 0))
%116 = load i32, i32* @EXIT_FAILURE
%117 = call i32 @exit(i32 %116)
unreachable
118: ; preds = %111
%119 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([20 x i8], [20 x i8]* @.str.10, i64 0, i64 0), i32 %112)
%120 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([36 x i8], [36 x i8]* @str, i64 0, i64 0))
%121 = call signext i8 (...) @getchar()
%122 = icmp eq i8 %121, 81
br i1 %122, label %123, label %101
123: ; preds = %118
ret i32 0
}