#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 uint16_t;
struct in_addr {
  int dummy;
};
struct sockaddr_in {
  struct in_addr sin_addr;
  scalar_t__ sin_port;
  void *sin_family;
};
struct sockaddr {
  int dummy;
};
struct addrinfo {
  int ai_family;
  int ai_addrlen;
  int ai_flags;
  scalar_t__ ai_protocol;
  void *ai_socktype;
  int /*<<< orphan*/ *ai_next;
  int /*<<< orphan*/ *ai_canonname;
  struct sockaddr *ai_addr;
};
typedef int /*<<< orphan*/ hint;

/* Variables and functions */
void *AF_INET;
int AF_INET6;
int AI_ADDRCONFIG;
int AI_NUMERICHOST;
int AI_NUMERICSERV;
int AI_PASSIVE;
int GetInterfaceIndex(char *);
void *SOCK_DGRAM;
int /*<<< orphan*/ atoi(char *);
int /*<<< orphan*/ free(char *);
int getaddrinfo(char *, char *, struct addrinfo *, struct addrinfo **);
scalar_t__ inet_aton(char *, struct in_addr *);
void *malloc(int);
int /*<<< orphan*/ memset(struct addrinfo *, int /*<<< orphan*/, int);
int /*<<< orphan*/ msg_Warn(int /*<<< orphan*/ *, char *, char *);
scalar_t__ ntohs(int /*<<< orphan*/);
int /*<<< orphan*/ sprintf(char *, char *, int);
char *strchr(char *, char);
char *strdup(char *);
int strlen(char *);
char *strpbrk(char *, char *);
char *strrchr(char *, char);
struct addrinfo *ParseNodeService(char *_psz_string, char **ppsz_end,
                                  uint16_t i_default_port, int *pi_if_index) {
  int i_family = AF_INET;
  char psz_port_buffer[6];
  char *psz_string = strdup(_psz_string);
  char *psz_node, *psz_port = NULL, *psz_end;
  struct addrinfo *p_res;
  struct addrinfo hint;
  int i_ret;
  if (psz_string[0] == '[') {
    i_family = AF_INET6;
    psz_node = psz_string + 1;
    psz_end = strchr(psz_node, ']');
    if (psz_end == NULL) {
      msg_Warn(NULL, "invalid IPv6 address %s", _psz_string);
      free(psz_string);
      return NULL;
    }
    *psz_end++ = '\0';
    char *psz_intf = strrchr(psz_node, '%');
    if (psz_intf != NULL) {
      *psz_intf++ = '\0';
      if (pi_if_index != NULL)
        *pi_if_index = GetInterfaceIndex(psz_intf);
    }
  } else {
    psz_node = psz_string;
    psz_end = strpbrk(psz_string, "@:,/");
  }
  if (psz_end != NULL && psz_end[0] == ':') {
    *psz_end++ = '\0';
    psz_port = psz_end;
    psz_end = strpbrk(psz_port, "@:,/");
  }
  if (psz_end != NULL) {
    *psz_end = '\0';
    if (ppsz_end != NULL)
      *ppsz_end = _psz_string + (psz_end - psz_string);
  } else if (ppsz_end != NULL)
    *ppsz_end = _psz_string + strlen(_psz_string);
  if (i_default_port != 0 && (psz_port == NULL || !*psz_port)) {
    sprintf(psz_port_buffer, "%u", i_default_port);
    psz_port = psz_port_buffer;
  }
  if (psz_node[0] == '\0')
    psz_node = "0.0.0.0";
  if (i_family != AF_INET6) {
    struct in_addr addr;
    if (inet_aton(psz_node, &addr) != 0) {
      struct sockaddr_in *p_sin = malloc(sizeof(struct sockaddr_in));
      p_sin->sin_family = AF_INET;
      if (psz_port != NULL)
        p_sin->sin_port = ntohs(atoi(psz_port));
      else
        p_sin->sin_port = 0;
      p_sin->sin_addr = addr;
      p_res = malloc(sizeof(struct addrinfo));
      p_res->ai_family = AF_INET;
      p_res->ai_socktype = SOCK_DGRAM;
      p_res->ai_protocol = 0;
      p_res->ai_addrlen = sizeof(struct sockaddr_in);
      p_res->ai_addr = (struct sockaddr *)p_sin;
      p_res->ai_canonname = NULL;
      p_res->ai_next = NULL;
      free(psz_string);
      return p_res;
    }
  }
  memset(&hint, 0, sizeof(hint));
  hint.ai_family = i_family;
  hint.ai_socktype = SOCK_DGRAM;
  hint.ai_protocol = 0;
  hint.ai_flags = AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG;
  if ((i_ret = getaddrinfo(psz_node, psz_port, &hint, &p_res)) != 0) {
    free(psz_string);
    return NULL;
  }
  free(psz_string);
  return p_res;
}


x86 assembly (clang, -O0):
<ParseNodeService>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
mov    %rcx,-0x28(%rbp)
mov    0x2dc7(%rip),%rax
mov    (%rax),%rax
mov    %eax,-0x2c(%rbp)
mov    -0x10(%rbp),%rdi
call   1110 <strdup@plt>
mov    %rax,-0x40(%rbp)
movq   $0x0,-0x50(%rbp)
mov    -0x40(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x5b,%eax
jne    1311 <ParseNodeService+0x121>
mov    0x2d7d(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rdi
mov    $0x5d,%esi
call   1050 <strchr@plt>
mov    %rax,-0x58(%rbp)
cmpq   $0x0,-0x58(%rbp)
jne    129b <ParseNodeService+0xab>
mov    -0x10(%rbp),%rdx
xor    %eax,%eax
mov    %eax,%edi
lea    0xd80(%rip),%rsi
call   10d0 <msg_Warn@plt>
mov    -0x40(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x8(%rbp)
jmp    1616 <ParseNodeService+0x426>
mov    -0x58(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x58(%rbp)
movb   $0x0,(%rax)
mov    -0x48(%rbp),%rdi
mov    $0x25,%esi
call   1060 <strrchr@plt>
mov    %rax,-0xa8(%rbp)
cmpq   $0x0,-0xa8(%rbp)
je     130c <ParseNodeService+0x11c>
mov    -0xa8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0xa8(%rbp)
movb   $0x0,(%rax)
cmpq   $0x0,-0x28(%rbp)
je     1307 <ParseNodeService+0x117>
mov    -0xa8(%rbp),%rdi
call   1080 <GetInterfaceIndex@plt>
mov    %eax,%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
jmp    130c <ParseNodeService+0x11c>
jmp    132d <ParseNodeService+0x13d>
mov    -0x40(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x40(%rbp),%rdi
lea    0xcf4(%rip),%rsi
call   10b0 <strpbrk@plt>
mov    %rax,-0x58(%rbp)
cmpq   $0x0,-0x58(%rbp)
je     1376 <ParseNodeService+0x186>
mov    -0x58(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x3a,%eax
jne    1376 <ParseNodeService+0x186>
mov    -0x58(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x58(%rbp)
movb   $0x0,(%rax)
mov    -0x58(%rbp),%rax
mov    %rax,-0x50(%rbp)
mov    -0x50(%rbp),%rdi
lea    0xcab(%rip),%rsi
call   10b0 <strpbrk@plt>
mov    %rax,-0x58(%rbp)
cmpq   $0x0,-0x58(%rbp)
je     13b1 <ParseNodeService+0x1c1>
mov    -0x58(%rbp),%rax
movb   $0x0,(%rax)
cmpq   $0x0,-0x18(%rbp)
je     13ac <ParseNodeService+0x1bc>
mov    -0x10(%rbp),%rcx
mov    -0x58(%rbp),%rax
mov    -0x40(%rbp),%rdx
sub    %rdx,%rax
add    %rax,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
jmp    13e8 <ParseNodeService+0x1f8>
cmpq   $0x0,-0x18(%rbp)
je     13e3 <ParseNodeService+0x1f3>
mov    -0x10(%rbp),%rax
mov    %rax,-0xc0(%rbp)
mov    -0x10(%rbp),%rdi
call   1040 <strlen@plt>
mov    -0xc0(%rbp),%rcx
cltq
add    %rax,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
jmp    13e8 <ParseNodeService+0x1f8>
cmpl   $0x0,-0x1c(%rbp)
je     1425 <ParseNodeService+0x235>
cmpq   $0x0,-0x50(%rbp)
je     140a <ParseNodeService+0x21a>
mov    -0x50(%rbp),%rax
cmpb   $0x0,(%rax)
jne    1425 <ParseNodeService+0x235>
lea    -0x32(%rbp),%rdi
mov    -0x1c(%rbp),%edx
lea    0xc05(%rip),%rsi
call   10f0 <sprintf@plt>
lea    -0x32(%rbp),%rax
mov    %rax,-0x50(%rbp)
mov    -0x48(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
jne    1440 <ParseNodeService+0x250>
lea    0xbe4(%rip),%rax
mov    %rax,-0x48(%rbp)
mov    -0x2c(%rbp),%eax
mov    0x2b76(%rip),%rcx
cmp    (%rcx),%eax
je     1569 <ParseNodeService+0x379>
mov    -0x48(%rbp),%rdi
lea    -0xb0(%rbp),%rsi
call   1090 <inet_aton@plt>
cmp    $0x0,%rax
je     1564 <ParseNodeService+0x374>
mov    $0x18,%edi
call   10a0 <malloc@plt>
mov    %rax,-0xb8(%rbp)
mov    0x2b54(%rip),%rax
mov    (%rax),%rcx
mov    -0xb8(%rbp),%rax
mov    %rcx,0x10(%rax)
cmpq   $0x0,-0x50(%rbp)
je     14c0 <ParseNodeService+0x2d0>
mov    -0x50(%rbp),%rdi
call   10e0 <atoi@plt>
mov    %eax,%edi
call   10c0 <ntohs@plt>
mov    %rax,%rcx
mov    -0xb8(%rbp),%rax
mov    %rcx,0x8(%rax)
jmp    14cf <ParseNodeService+0x2df>
mov    -0xb8(%rbp),%rax
movq   $0x0,0x8(%rax)
mov    -0xb8(%rbp),%rax
mov    -0xb0(%rbp),%ecx
mov    %ecx,(%rax)
mov    $0x38,%edi
call   10a0 <malloc@plt>
mov    %rax,-0x60(%rbp)
mov    0x2ae5(%rip),%rax
mov    (%rax),%rax
mov    %eax,%ecx
mov    -0x60(%rbp),%rax
mov    %ecx,(%rax)
mov    0x2ac3(%rip),%rax
mov    (%rax),%rcx
mov    -0x60(%rbp),%rax
mov    %rcx,0x18(%rax)
mov    -0x60(%rbp),%rax
movq   $0x0,0x10(%rax)
mov    -0x60(%rbp),%rax
movl   $0x18,0x4(%rax)
mov    -0xb8(%rbp),%rcx
mov    -0x60(%rbp),%rax
mov    %rcx,0x30(%rax)
mov    -0x60(%rbp),%rax
movq   $0x0,0x28(%rax)
mov    -0x60(%rbp),%rax
movq   $0x0,0x20(%rax)
mov    -0x40(%rbp),%rdi
call   1030 <free@plt>
mov    -0x60(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1616 <ParseNodeService+0x426>
jmp    1569 <ParseNodeService+0x379>
lea    -0x98(%rbp),%rdi
xor    %esi,%esi
mov    $0x38,%edx
call   1070 <memset@plt>
mov    -0x2c(%rbp),%eax
mov    %eax,-0x98(%rbp)
mov    0x2a3c(%rip),%rax
mov    (%rax),%rax
mov    %rax,-0x80(%rbp)
movq   $0x0,-0x88(%rbp)
mov    0x2a3b(%rip),%rax
mov    (%rax),%eax
mov    0x2a22(%rip),%rcx
or     (%rcx),%eax
mov    0x2a41(%rip),%rcx
or     (%rcx),%eax
mov    0x29e8(%rip),%rcx
or     (%rcx),%eax
mov    %eax,-0x90(%rbp)
mov    -0x48(%rbp),%rdi
mov    -0x50(%rbp),%rsi
lea    -0x98(%rbp),%rdx
lea    -0x60(%rbp),%rcx
call   1100 <getaddrinfo@plt>
mov    %eax,-0x9c(%rbp)
cmp    $0x0,%eax
je     1605 <ParseNodeService+0x415>
mov    -0x40(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x8(%rbp)
jmp    1616 <ParseNodeService+0x426>
mov    -0x40(%rbp),%rdi
call   1030 <free@plt>
mov    -0x60(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0xc0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ParseNodeService>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x68,%rsp
mov    %rcx,%r14
mov    %edx,0x4(%rsp)
mov    %rsi,0x8(%rsp)
mov    %rdi,%r15
mov    0x2dc4(%rip),%rax
mov    (%rax),%rbx
call   1110 <strdup@plt>
mov    %rax,%r12
cmpb   $0x5b,(%rax)
jne    1289 <ParseNodeService+0x99>
mov    0x2d95(%rip),%rax
mov    (%rax),%eax
mov    %rax,0x18(%rsp)
mov    %r12,%rbp
add    $0x1,%r12
mov    %r12,%rdi
mov    $0x5d,%esi
call   1050 <strchr@plt>
test   %rax,%rax
je     12f3 <ParseNodeService+0x103>
mov    %rax,%r13
mov    %rbp,0x10(%rsp)
add    $0x1,%r13
movb   $0x0,(%rax)
mov    %r12,%rdi
mov    $0x25,%esi
call   1060 <strrchr@plt>
test   %rax,%rax
je     12aa <ParseNodeService+0xba>
movb   $0x0,(%rax)
test   %r14,%r14
je     12aa <ParseNodeService+0xba>
add    $0x1,%rax
mov    %rax,%rdi
call   1080 <GetInterfaceIndex@plt>
mov    %eax,(%r14)
jmp    12aa <ParseNodeService+0xba>
mov    %rbx,0x18(%rsp)
lea    0xd83(%rip),%rsi
mov    %r12,%rdi
call   10b0 <strpbrk@plt>
test   %rax,%rax
mov    %r12,0x10(%rsp)
je     130f <ParseNodeService+0x11f>
mov    %rax,%r13
mov    0x4(%rsp),%ebx
mov    0x8(%rsp),%rbp
cmpb   $0x3a,0x0(%r13)
jne    12de <ParseNodeService+0xee>
movb   $0x0,0x0(%r13)
add    $0x1,%r13
lea    0xd4e(%rip),%rsi
mov    %r13,%rdi
call   10b0 <strpbrk@plt>
test   %rax,%rax
jne    12e4 <ParseNodeService+0xf4>
test   %rbp,%rbp
jne    1320 <ParseNodeService+0x130>
jmp    1331 <ParseNodeService+0x141>
mov    %r13,%rax
xor    %r13d,%r13d
movb   $0x0,(%rax)
test   %rbp,%rbp
je     1331 <ParseNodeService+0x141>
sub    0x10(%rsp),%rax
jmp    132a <ParseNodeService+0x13a>
lea    0xd06(%rip),%rsi
xor    %r12d,%r12d
xor    %edi,%edi
mov    %r15,%rdx
call   10d0 <msg_Warn@plt>
mov    %rbp,%rdi
jmp    14a0 <ParseNodeService+0x2b0>
xor    %r13d,%r13d
mov    0x4(%rsp),%ebx
mov    0x8(%rsp),%rbp
test   %rbp,%rbp
je     1331 <ParseNodeService+0x141>
mov    %r15,%rdi
call   1040 <strlen@plt>
cltq
add    %rax,%r15
mov    %r15,0x0(%rbp)
test   %ebx,%ebx
je     1357 <ParseNodeService+0x167>
test   %r13,%r13
je     1341 <ParseNodeService+0x151>
cmpb   $0x0,0x0(%r13)
jne    1357 <ParseNodeService+0x167>
lea    0x2a(%rsp),%r13
lea    0xcd0(%rip),%rsi
mov    %r13,%rdi
mov    %ebx,%edx
call   10f0 <sprintf@plt>
cmpb   $0x0,(%r12)
lea    0xcbd(%rip),%rbx
cmovne %r12,%rbx
mov    0x2c52(%rip),%rax
mov    0x18(%rsp),%rbp
cmp    (%rax),%ebp
je     13c6 <ParseNodeService+0x1d6>
lea    0x30(%rsp),%rsi
mov    %rbx,%rdi
call   1090 <inet_aton@plt>
test   %rax,%rax
je     13c6 <ParseNodeService+0x1d6>
mov    $0x18,%edi
call   10a0 <malloc@plt>
mov    %rax,%rbx
mov    0x2c3b(%rip),%rbp
mov    0x0(%rbp),%r15
mov    %r15,0x10(%rax)
test   %r13,%r13
je     144b <ParseNodeService+0x25b>
mov    %r13,%rdi
call   10e0 <atoi@plt>
mov    %eax,%edi
call   10c0 <ntohs@plt>
mov    0x0(%rbp),%r15
jmp    144d <ParseNodeService+0x25d>
lea    0x30(%rsp),%r15
xor    %r12d,%r12d
mov    %r15,%rdi
xor    %esi,%esi
mov    $0x38,%edx
call   1070 <memset@plt>
mov    %ebp,0x30(%rsp)
mov    0x2be0(%rip),%rax
mov    (%rax),%rax
mov    %rax,0x48(%rsp)
mov    0x2be9(%rip),%rax
mov    0x2bd2(%rip),%rcx
mov    (%rcx),%ecx
or     (%rax),%ecx
movq   $0x0,0x40(%rsp)
mov    0x2be6(%rip),%rax
or     (%rax),%ecx
mov    0x2b8d(%rip),%rax
or     (%rax),%ecx
mov    %ecx,0x38(%rsp)
lea    0x20(%rsp),%rcx
mov    %rbx,%rdi
mov    %r13,%rsi
mov    %r15,%rdx
call   1100 <getaddrinfo@plt>
mov    %eax,%ebx
mov    0x10(%rsp),%rdi
call   1030 <free@plt>
test   %ebx,%ebx
jne    14a5 <ParseNodeService+0x2b5>
mov    0x20(%rsp),%r12
jmp    14a5 <ParseNodeService+0x2b5>
xor    %eax,%eax
mov    %rax,0x8(%rbx)
mov    0x30(%rsp),%eax
mov    %eax,(%rbx)
mov    $0x38,%edi
call   10a0 <malloc@plt>
mov    %rax,%r12
mov    %rax,0x20(%rsp)
mov    %r15d,(%rax)
mov    0x2b55(%rip),%rax
mov    (%rax),%rax
mov    %rax,0x18(%r12)
movq   $0x0,0x10(%r12)
movl   $0x18,0x4(%r12)
mov    %rbx,0x30(%r12)
xorps  %xmm0,%xmm0
movups %xmm0,0x20(%r12)
mov    0x10(%rsp),%rdi
call   1030 <free@plt>
mov    %r12,%rax
add    $0x68,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.addrinfo = type { i32, i32, i32, i64, i8*, i32*, i32*, %struct.sockaddr* }
%struct.sockaddr = type { i32 }
%struct.in_addr = type { i32 }
%struct.sockaddr_in = type { %struct.in_addr, i64, i8* }
@AF_INET = global i8* null
@AF_INET6 = global i32 0
@.str = [24 x i8] c"invalid IPv6 address %s\00"
@.str.1 = [5 x i8] c"@:,/\00"
@.str.2 = [3 x i8] c"%u\00"
@.str.3 = [8 x i8] c"0.0.0.0\00"
@SOCK_DGRAM = global i8* null
@AI_PASSIVE = global i32 0
@AI_NUMERICHOST = global i32 0
@AI_NUMERICSERV = global i32 0
@AI_ADDRCONFIG = global i32 0
define %struct.addrinfo* @ParseNodeService(i8* %0, i8** %1, i32 %2, i32* %3) {
%5 = alloca %struct.addrinfo*
%6 = alloca i8*
%7 = alloca i8**
%8 = alloca i32
%9 = alloca i32*
%10 = alloca i32
%11 = alloca [6 x i8]
%12 = alloca i8*
%13 = alloca i8*
%14 = alloca i8*
%15 = alloca i8*
%16 = alloca %struct.addrinfo*
%17 = alloca %struct.addrinfo
%18 = alloca i32
%19 = alloca i8*
%20 = alloca %struct.in_addr
%21 = alloca %struct.sockaddr_in*
store i8* %0, i8** %6
store i8** %1, i8*** %7
store i32 %2, i32* %8
store i32* %3, i32** %9
%22 = load i8*, i8** @AF_INET
%23 = ptrtoint i8* %22 to i32
store i32 %23, i32* %10
%24 = load i8*, i8** %6
%25 = call i8* @strdup(i8* %24)
store i8* %25, i8** %12
store i8* null, i8** %14
%26 = load i8*, i8** %12
%27 = getelementptr inbounds i8, i8* %26, i64 0
%28 = load i8, i8* %27
%29 = sext i8 %28 to i32
%30 = icmp eq i32 %29, 91
br i1 %30, label %31, label %62
31: ; preds = %4
%32 = load i32, i32* @AF_INET6
store i32 %32, i32* %10
%33 = load i8*, i8** %12
%34 = getelementptr inbounds i8, i8* %33, i64 1
store i8* %34, i8** %13
%35 = load i8*, i8** %13
%36 = call i8* @strchr(i8* %35, i8 signext 93)
store i8* %36, i8** %15
%37 = load i8*, i8** %15
%38 = icmp eq i8* %37, null
br i1 %38, label %39, label %44
39: ; preds = %31
%40 = load i8*, i8** %6
%41 = call i32 @msg_Warn(i32* null, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str, i64 0, i64 0), i8* %40)
%42 = load i8*, i8** %12
%43 = call i32 @free(i8* %42)
store %struct.addrinfo* null, %struct.addrinfo** %5
br label %212
44: ; preds = %31
%45 = load i8*, i8** %15
%46 = getelementptr inbounds i8, i8* %45, i32 1
store i8* %46, i8** %15
store i8 0, i8* %45
%47 = load i8*, i8** %13
%48 = call i8* @strrchr(i8* %47, i8 signext 37)
store i8* %48, i8** %19
%49 = load i8*, i8** %19
%50 = icmp ne i8* %49, null
br i1 %50, label %51, label %61
51: ; preds = %44
%52 = load i8*, i8** %19
%53 = getelementptr inbounds i8, i8* %52, i32 1
store i8* %53, i8** %19
store i8 0, i8* %52
%54 = load i32*, i32** %9
%55 = icmp ne i32* %54, null
br i1 %55, label %56, label %60
56: ; preds = %51
%57 = load i8*, i8** %19
%58 = call i32 @GetInterfaceIndex(i8* %57)
%59 = load i32*, i32** %9
store i32 %58, i32* %59
br label %60
60: ; preds = %56, %51
br label %61
61: ; preds = %60, %44
br label %66
62: ; preds = %4
%63 = load i8*, i8** %12
store i8* %63, i8** %13
%64 = load i8*, i8** %12
%65 = call i8* @strpbrk(i8* %64, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0))
store i8* %65, i8** %15
br label %66
66: ; preds = %62, %61
%67 = load i8*, i8** %15
%68 = icmp ne i8* %67, null
br i1 %68, label %69, label %81
69: ; preds = %66
%70 = load i8*, i8** %15
%71 = getelementptr inbounds i8, i8* %70, i64 0
%72 = load i8, i8* %71
%73 = sext i8 %72 to i32
%74 = icmp eq i32 %73, 58
br i1 %74, label %75, label %81
75: ; preds = %69
%76 = load i8*, i8** %15
%77 = getelementptr inbounds i8, i8* %76, i32 1
store i8* %77, i8** %15
store i8 0, i8* %76
%78 = load i8*, i8** %15
store i8* %78, i8** %14
%79 = load i8*, i8** %14
%80 = call i8* @strpbrk(i8* %79, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0))
store i8* %80, i8** %15
br label %81
81: ; preds = %75, %69, %66
%82 = load i8*, i8** %15
%83 = icmp ne i8* %82, null
br i1 %83, label %84, label %98
84: ; preds = %81
%85 = load i8*, i8** %15
store i8 0, i8* %85
%86 = load i8**, i8*** %7
%87 = icmp ne i8** %86, null
br i1 %87, label %88, label %97
88: ; preds = %84
%89 = load i8*, i8** %6
%90 = load i8*, i8** %15
%91 = load i8*, i8** %12
%92 = ptrtoint i8* %90 to i64
%93 = ptrtoint i8* %91 to i64
%94 = sub i64 %92, %93
%95 = getelementptr inbounds i8, i8* %89, i64 %94
%96 = load i8**, i8*** %7
store i8* %95, i8** %96
br label %97
97: ; preds = %88, %84
br label %109
98: ; preds = %81
%99 = load i8**, i8*** %7
%100 = icmp ne i8** %99, null
br i1 %100, label %101, label %108
101: ; preds = %98
%102 = load i8*, i8** %6
%103 = load i8*, i8** %6
%104 = call i32 @strlen(i8* %103)
%105 = sext i32 %104 to i64
%106 = getelementptr inbounds i8, i8* %102, i64 %105
%107 = load i8**, i8*** %7
store i8* %106, i8** %107
br label %108
108: ; preds = %101, %98
br label %109
109: ; preds = %108, %97
%110 = load i32, i32* %8
%111 = icmp ne i32 %110, 0
br i1 %111, label %112, label %124
112: ; preds = %109
%113 = load i8*, i8** %14
%114 = icmp eq i8* %113, null
br i1 %114, label %119, label %115
115: ; preds = %112
%116 = load i8*, i8** %14
%117 = load i8, i8* %116
%118 = icmp ne i8 %117, 0
br i1 %118, label %124, label %119
119: ; preds = %115, %112
%120 = getelementptr inbounds [6 x i8], [6 x i8]* %11, i64 0, i64 0
%121 = load i32, i32* %8
%122 = call i32 @sprintf(i8* %120, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 %121)
%123 = getelementptr inbounds [6 x i8], [6 x i8]* %11, i64 0, i64 0
store i8* %123, i8** %14
br label %124
124: ; preds = %119, %115, %109
%125 = load i8*, i8** %13
%126 = getelementptr inbounds i8, i8* %125, i64 0
%127 = load i8, i8* %126
%128 = sext i8 %127 to i32
%129 = icmp eq i32 %128, 0
br i1 %129, label %130, label %131
130: ; preds = %124
store i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.3, i64 0, i64 0), i8** %13
br label %131
131: ; preds = %130, %124
%132 = load i32, i32* %10
%133 = load i32, i32* @AF_INET6
%134 = icmp ne i32 %132, %133
br i1 %134, label %135, label %186
135: ; preds = %131
%136 = load i8*, i8** %13
%137 = call i64 @inet_aton(i8* %136, %struct.in_addr* %20)
%138 = icmp ne i64 %137, 0
br i1 %138, label %139, label %185
139: ; preds = %135
%140 = call i8* @malloc(i32 24)
%141 = bitcast i8* %140 to %struct.sockaddr_in*
store %struct.sockaddr_in* %141, %struct.sockaddr_in** %21
%142 = load i8*, i8** @AF_INET
%143 = load %struct.sockaddr_in*, %struct.sockaddr_in** %21
%144 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %143, i32 0, i32 2
store i8* %142, i8** %144
%145 = load i8*, i8** %14
%146 = icmp ne i8* %145, null
br i1 %146, label %147, label %153
147: ; preds = %139
%148 = load i8*, i8** %14
%149 = call i32 @atoi(i8* %148)
%150 = call i64 @ntohs(i32 %149)
%151 = load %struct.sockaddr_in*, %struct.sockaddr_in** %21
%152 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %151, i32 0, i32 1
store i64 %150, i64* %152
br label %156
153: ; preds = %139
%154 = load %struct.sockaddr_in*, %struct.sockaddr_in** %21
%155 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %154, i32 0, i32 1
store i64 0, i64* %155
br label %156
156: ; preds = %153, %147
%157 = load %struct.sockaddr_in*, %struct.sockaddr_in** %21
%158 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %157, i32 0, i32 0
%159 = bitcast %struct.in_addr* %158 to i8*
%160 = bitcast %struct.in_addr* %20 to i8*
%161 = call i8* @malloc(i32 56)
%162 = bitcast i8* %161 to %struct.addrinfo*
store %struct.addrinfo* %162, %struct.addrinfo** %16
%163 = load i8*, i8** @AF_INET
%164 = ptrtoint i8* %163 to i32
%165 = load %struct.addrinfo*, %struct.addrinfo** %16
%166 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %165, i32 0, i32 0
store i32 %164, i32* %166
%167 = load i8*, i8** @SOCK_DGRAM
%168 = load %struct.addrinfo*, %struct.addrinfo** %16
%169 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %168, i32 0, i32 4
store i8* %167, i8** %169
%170 = load %struct.addrinfo*, %struct.addrinfo** %16
%171 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %170, i32 0, i32 3
store i64 0, i64* %171
%172 = load %struct.addrinfo*, %struct.addrinfo** %16
%173 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %172, i32 0, i32 1
store i32 24, i32* %173
%174 = load %struct.sockaddr_in*, %struct.sockaddr_in** %21
%175 = bitcast %struct.sockaddr_in* %174 to %struct.sockaddr*
%176 = load %struct.addrinfo*, %struct.addrinfo** %16
%177 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %176, i32 0, i32 7
store %struct.sockaddr* %175, %struct.sockaddr** %177
%178 = load %struct.addrinfo*, %struct.addrinfo** %16
%179 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %178, i32 0, i32 6
store i32* null, i32** %179
%180 = load %struct.addrinfo*, %struct.addrinfo** %16
%181 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %180, i32 0, i32 5
store i32* null, i32** %181
%182 = load i8*, i8** %12
%183 = call i32 @free(i8* %182)
%184 = load %struct.addrinfo*, %struct.addrinfo** %16
store %struct.addrinfo* %184, %struct.addrinfo** %5
br label %212
185: ; preds = %135
br label %186
186: ; preds = %185, %131
%187 = call i32 @memset(%struct.addrinfo* %17, i32 0, i32 56)
%188 = load i32, i32* %10
%189 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %17, i32 0, i32 0
store i32 %188, i32* %189
%190 = load i8*, i8** @SOCK_DGRAM
%191 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %17, i32 0, i32 4
store i8* %190, i8** %191
%192 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %17, i32 0, i32 3
store i64 0, i64* %192
%193 = load i32, i32* @AI_PASSIVE
%194 = load i32, i32* @AI_NUMERICHOST
%195 = or i32 %193, %194
%196 = load i32, i32* @AI_NUMERICSERV
%197 = or i32 %195, %196
%198 = load i32, i32* @AI_ADDRCONFIG
%199 = or i32 %197, %198
%200 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %17, i32 0, i32 2
store i32 %199, i32* %200
%201 = load i8*, i8** %13
%202 = load i8*, i8** %14
%203 = call i32 @getaddrinfo(i8* %201, i8* %202, %struct.addrinfo* %17, %struct.addrinfo** %16)
store i32 %203, i32* %18
%204 = icmp ne i32 %203, 0
br i1 %204, label %205, label %208
205: ; preds = %186
%206 = load i8*, i8** %12
%207 = call i32 @free(i8* %206)
store %struct.addrinfo* null, %struct.addrinfo** %5
br label %212
208: ; preds = %186
%209 = load i8*, i8** %12
%210 = call i32 @free(i8* %209)
%211 = load %struct.addrinfo*, %struct.addrinfo** %16
store %struct.addrinfo* %211, %struct.addrinfo** %5
br label %212
212: ; preds = %208, %205, %156, %39
%213 = load %struct.addrinfo*, %struct.addrinfo** %5
ret %struct.addrinfo* %213
}

LLVM IR (-O2):
%struct.addrinfo = type { i32, i32, i32, i64, i8*, i32*, i32*, %struct.sockaddr* }
%struct.sockaddr = type { i32 }
%struct.in_addr = type { i32 }
%struct.sockaddr_in = type { %struct.in_addr, i64, i8* }
@AF_INET = global i8* null
@AF_INET6 = global i32 0
@.str = [24 x i8] c"invalid IPv6 address %s\00"
@.str.1 = [5 x i8] c"@:,/\00"
@.str.2 = [3 x i8] c"%u\00"
@.str.3 = [8 x i8] c"0.0.0.0\00"
@SOCK_DGRAM = global i8* null
@AI_PASSIVE = global i32 0
@AI_NUMERICHOST = global i32 0
@AI_NUMERICSERV = global i32 0
@AI_ADDRCONFIG = global i32 0
define %struct.addrinfo* @ParseNodeService(i8* %0, i8** writeonly %1, i32 %2, i32* writeonly %3) {
%5 = alloca [6 x i8]
%6 = alloca %struct.addrinfo*
%7 = alloca %struct.addrinfo
%8 = alloca %struct.in_addr
%9 = load i8*, i8** @AF_INET
%10 = getelementptr inbounds [6 x i8], [6 x i8]* %5, i64 0, i64 0
%11 = tail call i8* @strdup(i8* %0)
%12 = bitcast %struct.addrinfo** %6 to i8*
%13 = bitcast %struct.addrinfo* %7 to i8*
%14 = load i8, i8* %11
%15 = icmp eq i8 %14, 91
br i1 %15, label %16, label %33
16: ; preds = %4
%17 = load i32, i32* @AF_INET6
%18 = getelementptr inbounds i8, i8* %11, i64 1
%19 = tail call i8* @strchr(i8* %18, i8 signext 93)
%20 = icmp eq i8* %19, null
br i1 %20, label %21, label %24
21: ; preds = %16
%22 = tail call i32 @msg_Warn(i32* null, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str, i64 0, i64 0), i8* %0)
%23 = tail call i32 @free(i8* %11)
br label %145
24: ; preds = %16
%25 = getelementptr inbounds i8, i8* %19, i64 1
store i8 0, i8* %19
%26 = tail call i8* @strrchr(i8* %18, i8 signext 37)
%27 = icmp eq i8* %26, null
br i1 %27, label %38, label %28
28: ; preds = %24
store i8 0, i8* %26
%29 = icmp eq i32* %3, null
br i1 %29, label %38, label %30
30: ; preds = %28
%31 = getelementptr inbounds i8, i8* %26, i64 1
%32 = tail call i32 @GetInterfaceIndex(i8* %31)
store i32 %32, i32* %3
br label %38
33: ; preds = %4
%34 = ptrtoint i8* %9 to i64
%35 = trunc i64 %34 to i32
%36 = tail call i8* @strpbrk(i8* %11, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0))
%37 = icmp eq i8* %36, null
br i1 %37, label %56, label %38
38: ; preds = %24, %30, %28, %33
%39 = phi i32 [ %35, %33 ], [ %17, %28 ], [ %17, %30 ], [ %17, %24 ]
%40 = phi i8* [ %36, %33 ], [ %25, %28 ], [ %25, %30 ], [ %25, %24 ]
%41 = phi i8* [ %11, %33 ], [ %18, %28 ], [ %18, %30 ], [ %18, %24 ]
%42 = load i8, i8* %40
%43 = icmp eq i8 %42, 58
br i1 %43, label %44, label %48
44: ; preds = %38
%45 = getelementptr inbounds i8, i8* %40, i64 1
store i8 0, i8* %40
%46 = tail call i8* @strpbrk(i8* %45, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0))
%47 = icmp eq i8* %46, null
br i1 %47, label %56, label %48
48: ; preds = %38, %44
%49 = phi i8* [ %46, %44 ], [ %40, %38 ]
%50 = phi i8* [ %45, %44 ], [ null, %38 ]
store i8 0, i8* %49
%51 = icmp eq i8** %1, null
br i1 %51, label %70, label %52
52: ; preds = %48
%53 = ptrtoint i8* %49 to i64
%54 = ptrtoint i8* %11 to i64
%55 = sub i64 %53, %54
br label %64
56: ; preds = %33, %44
%57 = phi i8* [ %45, %44 ], [ null, %33 ]
%58 = phi i8* [ %41, %44 ], [ %11, %33 ]
%59 = phi i32 [ %39, %44 ], [ %35, %33 ]
%60 = icmp eq i8** %1, null
br i1 %60, label %70, label %61
61: ; preds = %56
%62 = tail call i32 @strlen(i8* %0)
%63 = sext i32 %62 to i64
br label %64
64: ; preds = %52, %61
%65 = phi i64 [ %63, %61 ], [ %55, %52 ]
%66 = phi i8* [ %57, %61 ], [ %50, %52 ]
%67 = phi i8* [ %58, %61 ], [ %41, %52 ]
%68 = phi i32 [ %59, %61 ], [ %39, %52 ]
%69 = getelementptr inbounds i8, i8* %0, i64 %65
store i8* %69, i8** %1
br label %70
70: ; preds = %64, %56, %48
%71 = phi i8* [ %57, %56 ], [ %50, %48 ], [ %66, %64 ]
%72 = phi i8* [ %58, %56 ], [ %41, %48 ], [ %67, %64 ]
%73 = phi i32 [ %59, %56 ], [ %39, %48 ], [ %68, %64 ]
%74 = icmp eq i32 %2, 0
br i1 %74, label %82, label %75
75: ; preds = %70
%76 = icmp eq i8* %71, null
br i1 %76, label %80, label %77
77: ; preds = %75
%78 = load i8, i8* %71
%79 = icmp eq i8 %78, 0
br i1 %79, label %80, label %82
80: ; preds = %77, %75
%81 = call i32 @sprintf(i8* %10, i8* dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 %2)
br label %82
82: ; preds = %80, %77, %70
%83 = phi i8* [ %10, %80 ], [ %71, %77 ], [ %71, %70 ]
%84 = load i8, i8* %72
%85 = icmp eq i8 %84, 0
%86 = select i1 %85, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.3, i64 0, i64 0), i8* %72
%87 = load i32, i32* @AF_INET6
%88 = icmp eq i32 %73, %87
br i1 %88, label %126, label %89
89: ; preds = %82
%90 = bitcast %struct.in_addr* %8 to i8*
%91 = call i64 @inet_aton(i8* %86, %struct.in_addr* %8)
%92 = icmp eq i64 %91, 0
br i1 %92, label %93, label %94
93: ; preds = %89
br label %126
94: ; preds = %89
%95 = call dereferenceable_or_null(24) i8* @malloc(i32 24)
%96 = bitcast i8* %95 to %struct.sockaddr_in*
%97 = load i8*, i8** @AF_INET
%98 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %96, i64 0, i32 2
store i8* %97, i8** %98
%99 = icmp eq i8* %83, null
br i1 %99, label %104, label %100
100: ; preds = %94
%101 = call i32 @atoi(i8* %83)
%102 = call i64 @ntohs(i32 %101)
%103 = load i8*, i8** @AF_INET
br label %104
104: ; preds = %94, %100
%105 = phi i8* [ %103, %100 ], [ %97, %94 ]
%106 = phi i64 [ %102, %100 ], [ 0, %94 ]
%107 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %96, i64 0, i32 1
store i64 %106, i64* %107
%108 = getelementptr inbounds %struct.in_addr, %struct.in_addr* %8, i64 0, i32 0
%109 = bitcast i8* %95 to i32*
%110 = load i32, i32* %108
store i32 %110, i32* %109
%111 = call dereferenceable_or_null(56) i8* @malloc(i32 56)
%112 = bitcast i8* %111 to %struct.addrinfo*
%113 = bitcast %struct.addrinfo** %6 to i8**
store i8* %111, i8** %113
%114 = ptrtoint i8* %105 to i64
%115 = trunc i64 %114 to i32
%116 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %112, i64 0, i32 0
store i32 %115, i32* %116
%117 = load i8*, i8** @SOCK_DGRAM
%118 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %112, i64 0, i32 4
store i8* %117, i8** %118
%119 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %112, i64 0, i32 3
store i64 0, i64* %119
%120 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %112, i64 0, i32 1
store i32 24, i32* %120
%121 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %112, i64 0, i32 7
%122 = bitcast %struct.sockaddr** %121 to i8**
store i8* %95, i8** %122
%123 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %112, i64 0, i32 5
%124 = bitcast i32** %123 to i8*
%125 = call i32 @free(i8* %11)
br label %145
126: ; preds = %93, %82
%127 = call i32 @memset(%struct.addrinfo* %7, i32 0, i32 56)
%128 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %7, i64 0, i32 0
store i32 %73, i32* %128
%129 = load i8*, i8** @SOCK_DGRAM
%130 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %7, i64 0, i32 4
store i8* %129, i8** %130
%131 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %7, i64 0, i32 3
store i64 0, i64* %131
%132 = load i32, i32* @AI_PASSIVE
%133 = load i32, i32* @AI_NUMERICHOST
%134 = or i32 %133, %132
%135 = load i32, i32* @AI_NUMERICSERV
%136 = or i32 %134, %135
%137 = load i32, i32* @AI_ADDRCONFIG
%138 = or i32 %136, %137
%139 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %7, i64 0, i32 2
store i32 %138, i32* %139
%140 = call i32 @getaddrinfo(i8* %86, i8* %83, %struct.addrinfo* %7, %struct.addrinfo** %6)
%141 = icmp eq i32 %140, 0
%142 = call i32 @free(i8* %11)
%143 = load %struct.addrinfo*, %struct.addrinfo** %6
%144 = select i1 %141, %struct.addrinfo* %143, %struct.addrinfo* null
br label %145
145: ; preds = %126, %104, %21
%146 = phi %struct.addrinfo* [ null, %21 ], [ %112, %104 ], [ %144, %126 ]
ret %struct.addrinfo* %146
}