#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 char sockaddr_storage;
struct addrinfo {
  scalar_t__ ai_family;
  int ai_socktype;
  int ai_addrlen;
  char const *ai_addr;
  struct addrinfo *ai_next;
  int /*<<< orphan*/ ai_flags;
};
typedef int socklen_t;
typedef int /*<<< orphan*/ host;

/* Variables and functions */
scalar_t__ AF_INET;
scalar_t__ AF_INET6;
int /*<<< orphan*/ AI_PASSIVE;
int SOCK_STREAM;
int /*<<< orphan*/ assert(int /*<<< orphan*/);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, ...);
int /*<<< orphan*/ freeaddrinfo(struct addrinfo *);
char *gai_strerror(int);
int getaddrinfo(char *, char *, struct addrinfo *, struct addrinfo **);
int /*<<< orphan*/ memcpy(char *, char const *, int);
int /*<<< orphan*/ memset(struct addrinfo *, int /*<<< orphan*/, int);
int /*<<< orphan*/ stderr;
int /*<<< orphan*/ strlen(char const *);
char *strrchr(char *, char);
int socket_addr(const char *name, struct sockaddr_storage *ss,
                socklen_t *ss_len) {
  char host[strlen(name) + 1], *port;
  struct addrinfo *ai, *curr, hints[2];
  int e;
  const int socktype = SOCK_STREAM;
  assert(name != NULL);
  assert(ss != NULL);
  assert(ss_len != NULL);
  memcpy(host, name, sizeof(host));
  port = strrchr(host, '/');
  if (!port)
    port = strrchr(host, ':');
  if (!port) {
    fprintf(stderr, "missing port\n");
    return 1;
  }
  *port++ = 0;
  memset(hints, 0, sizeof *hints);
  hints[0].ai_family = AF_INET;
  hints[0].ai_socktype = socktype;
  hints[0].ai_next = &hints[1];
  hints[1].ai_family = AF_INET6;
  hints[1].ai_socktype = socktype;
  hints[1].ai_next = NULL;
  if ((host[0] == '*' && host[1] == 0) || host[0] == 0) {
    hints[0].ai_flags |= AI_PASSIVE;
    hints[1].ai_flags |= AI_PASSIVE;
    *host = 0;
  } else {
    hints[0].ai_flags = 0;
    hints[1].ai_flags = 0;
  }
  e = getaddrinfo(*host ? host : NULL, port, hints, &ai);
  if (e) {
    fprintf(stderr, "getaddrinfo host:%s err:%s\n", host, gai_strerror(e));
    return 0;
  }
  for (curr = ai; curr; curr = curr->ai_next) {
    if (curr->ai_family == AF_INET || curr->ai_family == AF_INET6) {
      if (*ss_len >= curr->ai_addrlen) {
        *ss_len = curr->ai_addrlen;
        memcpy(ss, curr->ai_addr, curr->ai_addrlen);
        freeaddrinfo(ai);
        return 0;
      }
    }
  }
  freeaddrinfo(ai);
  fprintf(stderr, "getaddrinfo():%s:no usable addresses found.\n", name);
  return 1;
}


x86 assembly (clang, -O0):
<socket_addr>:
push   %rbp
mov    %rsp,%rbp
sub    $0xd0,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    -0x10(%rbp),%rdi
call   1030 <strlen@plt>
add    $0x1,%eax
mov    %rax,-0xc0(%rbp)
mov    %rsp,%rcx
mov    %rcx,-0x28(%rbp)
mov    %rax,%rdx
add    $0xf,%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0xb8(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x30(%rbp)
mov    0x2dd9(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0xa8(%rbp)
cmpq   $0x0,-0x10(%rbp)
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1070 <assert@plt>
cmpq   $0x0,-0x18(%rbp)
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1070 <assert@plt>
cmpq   $0x0,-0x20(%rbp)
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1070 <assert@plt>
mov    -0xb8(%rbp),%rdi
mov    -0xc0(%rbp),%rax
mov    -0x10(%rbp),%rsi
mov    %eax,%edx
call   1090 <memcpy@plt>
mov    -0xb8(%rbp),%rdi
mov    $0x2f,%esi
call   1050 <strrchr@plt>
mov    %rax,-0x38(%rbp)
cmpq   $0x0,-0x38(%rbp)
jne    1273 <socket_addr+0xe3>
mov    -0xb8(%rbp),%rdi
mov    $0x3a,%esi
call   1050 <strrchr@plt>
mov    %rax,-0x38(%rbp)
cmpq   $0x0,-0x38(%rbp)
jne    12ab <socket_addr+0x11b>
mov    0x2d43(%rip),%rax
mov    (%rax),%edi
lea    0xd72(%rip),%rsi
mov    $0x0,%al
call   1080 <fprintf@plt>
movl   $0x1,-0x4(%rbp)
movl   $0x1,-0xac(%rbp)
jmp    152b <socket_addr+0x39b>
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x38(%rbp)
movb   $0x0,(%rax)
lea    -0xa0(%rbp),%rdi
xor    %esi,%esi
mov    $0x28,%edx
call   1060 <memset@plt>
mov    -0xb8(%rbp),%rax
mov    0x2d02(%rip),%rcx
mov    (%rcx),%rcx
mov    %rcx,-0xa0(%rbp)
mov    -0xa8(%rbp),%ecx
mov    %ecx,-0x98(%rbp)
lea    -0xa0(%rbp),%rcx
add    $0x28,%rcx
mov    %rcx,-0x88(%rbp)
mov    0x2ccb(%rip),%rcx
mov    (%rcx),%rcx
mov    %rcx,-0x78(%rbp)
mov    -0xa8(%rbp),%ecx
mov    %ecx,-0x70(%rbp)
movq   $0x0,-0x60(%rbp)
movsbl (%rax),%eax
cmp    $0x2a,%eax
jne    1345 <socket_addr+0x1b5>
mov    -0xb8(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x0,%eax
je     1358 <socket_addr+0x1c8>
mov    -0xb8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
jne    1385 <socket_addr+0x1f5>
mov    -0xb8(%rbp),%rax
mov    0x2c82(%rip),%rcx
mov    (%rcx),%ecx
or     -0x80(%rbp),%ecx
mov    %ecx,-0x80(%rbp)
mov    0x2c73(%rip),%rcx
mov    (%rcx),%ecx
or     -0x58(%rbp),%ecx
mov    %ecx,-0x58(%rbp)
movb   $0x0,(%rax)
jmp    1393 <socket_addr+0x203>
movl   $0x0,-0x80(%rbp)
movl   $0x0,-0x58(%rbp)
mov    -0xb8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
je     13b9 <socket_addr+0x229>
mov    -0xb8(%rbp),%rax
mov    %rax,-0xc8(%rbp)
jmp    13c7 <socket_addr+0x237>
xor    %eax,%eax
mov    %rax,-0xc8(%rbp)
jmp    13c7 <socket_addr+0x237>
mov    -0xc8(%rbp),%rdi
mov    -0x38(%rbp),%rsi
lea    -0xa0(%rbp),%rdx
lea    -0x40(%rbp),%rcx
call   10a0 <getaddrinfo@plt>
mov    %eax,-0xa4(%rbp)
cmpl   $0x0,-0xa4(%rbp)
je     1443 <socket_addr+0x2b3>
mov    0x2bcc(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0xcc(%rbp)
mov    -0xa4(%rbp),%edi
call   1040 <gai_strerror@plt>
mov    -0xcc(%rbp),%edi
mov    -0xb8(%rbp),%rdx
mov    %rax,%rcx
lea    0xbe8(%rip),%rsi
mov    $0x0,%al
call   1080 <fprintf@plt>
movl   $0x0,-0x4(%rbp)
movl   $0x1,-0xac(%rbp)
jmp    152b <socket_addr+0x39b>
mov    -0x40(%rbp),%rax
mov    %rax,-0x48(%rbp)
cmpq   $0x0,-0x48(%rbp)
je     14f6 <socket_addr+0x366>
mov    -0x48(%rbp),%rax
mov    (%rax),%rax
mov    0x2b7c(%rip),%rcx
cmp    (%rcx),%rax
je     1484 <socket_addr+0x2f4>
mov    -0x48(%rbp),%rax
mov    (%rax),%rax
mov    0x2b5d(%rip),%rcx
cmp    (%rcx),%rax
jne    14e0 <socket_addr+0x350>
mov    -0x20(%rbp),%rax
mov    (%rax),%eax
mov    -0x48(%rbp),%rcx
cmp    0xc(%rcx),%eax
jl     14db <socket_addr+0x34b>
mov    -0x48(%rbp),%rax
mov    0xc(%rax),%ecx
mov    -0x20(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x18(%rbp),%rdi
mov    -0x48(%rbp),%rax
mov    0x10(%rax),%rsi
mov    -0x48(%rbp),%rax
mov    0xc(%rax),%edx
call   1090 <memcpy@plt>
mov    -0x40(%rbp),%rdi
call   10b0 <freeaddrinfo@plt>
movl   $0x0,-0x4(%rbp)
movl   $0x1,-0xac(%rbp)
jmp    152b <socket_addr+0x39b>
jmp    14e0 <socket_addr+0x350>
jmp    14e5 <socket_addr+0x355>
mov    -0x48(%rbp),%rax
mov    0x18(%rax),%rax
mov    %rax,-0x48(%rbp)
jmp    144b <socket_addr+0x2bb>
mov    -0x40(%rbp),%rdi
call   10b0 <freeaddrinfo@plt>
mov    0x2ac2(%rip),%rax
mov    (%rax),%edi
mov    -0x10(%rbp),%rdx
lea    0xb17(%rip),%rsi
mov    $0x0,%al
call   1080 <fprintf@plt>
movl   $0x1,-0x4(%rbp)
movl   $0x1,-0xac(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,%rsp
mov    -0x4(%rbp),%eax
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<socket_addr>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x78,%rsp
mov    %rdx,%r14
mov    %rsi,%r12
mov    %rdi,%r15
call   1030 <strlen@plt>
lea    0x1(%rax),%ebx
mov    %rsp,%r13
lea    0xf(%rbx),%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%r13
mov    %r13,%rsp
mov    0x2df6(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x2c(%rbp)
xor    %edi,%edi
test   %r15,%r15
setne  %dil
call   1070 <assert@plt>
xor    %edi,%edi
mov    %r12,-0x40(%rbp)
test   %r12,%r12
setne  %dil
call   1070 <assert@plt>
xor    %edi,%edi
test   %r14,%r14
setne  %dil
call   1070 <assert@plt>
mov    %r13,%rdi
mov    %r15,-0x48(%rbp)
mov    %r15,%rsi
mov    %ebx,%edx
call   1090 <memcpy@plt>
mov    %r13,%rdi
mov    $0x2f,%esi
call   1050 <strrchr@plt>
mov    %rax,%rbx
test   %rax,%rax
jne    123c <socket_addr+0xac>
mov    %r13,%rdi
mov    $0x3a,%esi
call   1050 <strrchr@plt>
mov    %rax,%rbx
test   %rax,%rax
je     1372 <socket_addr+0x1e2>
movb   $0x0,(%rbx)
add    $0x1,%rbx
lea    -0xa0(%rbp),%rdi
xor    %esi,%esi
mov    $0x28,%edx
call   1060 <memset@plt>
mov    0x2d83(%rip),%r15
mov    (%r15),%rax
mov    %rax,-0xa0(%rbp)
mov    -0x2c(%rbp),%ecx
mov    %ecx,-0x98(%rbp)
lea    -0x78(%rbp),%rax
mov    %rax,-0x88(%rbp)
mov    0x2d56(%rip),%r12
mov    (%r12),%rax
mov    %rax,-0x78(%rbp)
mov    %ecx,-0x70(%rbp)
movq   $0x0,-0x60(%rbp)
mov    0x0(%r13),%al
test   %al,%al
je     12bb <socket_addr+0x12b>
cmp    $0x2a,%al
jne    12a8 <socket_addr+0x118>
cmpb   $0x0,0x1(%r13)
je     12bb <socket_addr+0x12b>
movl   $0x0,-0x80(%rbp)
movl   $0x0,-0x58(%rbp)
mov    %r13,%rdi
jmp    12d1 <socket_addr+0x141>
mov    0x2d26(%rip),%rax
mov    (%rax),%eax
or     %eax,-0x80(%rbp)
or     %eax,-0x58(%rbp)
movb   $0x0,0x0(%r13)
xor    %edi,%edi
lea    -0xa0(%rbp),%rdx
lea    -0x38(%rbp),%rcx
mov    %rbx,%rsi
call   10a0 <getaddrinfo@plt>
test   %eax,%eax
je     1314 <socket_addr+0x184>
mov    0x2cd9(%rip),%rcx
mov    (%rcx),%r14d
mov    %eax,%edi
call   1040 <gai_strerror@plt>
lea    0xd0e(%rip),%rsi
xor    %ebx,%ebx
mov    %r14d,%edi
mov    %r13,%rdx
mov    %rax,%rcx
xor    %eax,%eax
call   1080 <fprintf@plt>
jmp    138e <socket_addr+0x1fe>
mov    -0x38(%rbp),%rdi
test   %rdi,%rdi
je     1350 <socket_addr+0x1c0>
mov    (%r15),%rcx
mov    (%r12),%rdx
mov    %rdi,%rax
jmp    1341 <socket_addr+0x1b1>
nopl   0x0(%rax)
mov    0xc(%rax),%esi
cmp    %esi,(%r14)
jge    139f <socket_addr+0x20f>
mov    0x18(%rax),%rax
test   %rax,%rax
je     1350 <socket_addr+0x1c0>
mov    (%rax),%rsi
cmp    %rcx,%rsi
je     1330 <socket_addr+0x1a0>
cmp    %rdx,%rsi
jne    1338 <socket_addr+0x1a8>
jmp    1330 <socket_addr+0x1a0>
call   10b0 <freeaddrinfo@plt>
mov    0x2c6c(%rip),%rax
mov    (%rax),%edi
lea    0xcc5(%rip),%rsi
mov    -0x48(%rbp),%rdx
xor    %eax,%eax
call   1080 <fprintf@plt>
jmp    1389 <socket_addr+0x1f9>
mov    0x2c4f(%rip),%rax
mov    (%rax),%edi
lea    0xc7e(%rip),%rsi
xor    %eax,%eax
call   1080 <fprintf@plt>
mov    $0x1,%ebx
mov    %ebx,%eax
lea    -0x28(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %esi,(%r14)
mov    0x10(%rax),%rsi
mov    0xc(%rax),%edx
mov    -0x40(%rbp),%rdi
call   1090 <memcpy@plt>
mov    -0x38(%rbp),%rdi
call   10b0 <freeaddrinfo@plt>
xor    %ebx,%ebx
jmp    138e <socket_addr+0x1fe>

LLVM IR (-O0):
%struct.sockaddr_storage = type opaque
%struct.addrinfo = type { i64, i32, i32, i8*, %struct.addrinfo*, i32 }
@SOCK_STREAM = global i32 0
@stderr = global i32 0
@.str = [14 x i8] c"missing port\0A\00"
@AF_INET = global i64 0
@AF_INET6 = global i64 0
@AI_PASSIVE = global i32 0
@.str.1 = [28 x i8] c"getaddrinfo host:%s err:%s\0A\00"
@.str.2 = [45 x i8] c"getaddrinfo():%s:no usable addresses found.\0A\00"
define i32 @socket_addr(i8* %0, %struct.sockaddr_storage* %1, i32* %2) {
%4 = alloca i32
%5 = alloca i8*
%6 = alloca %struct.sockaddr_storage*
%7 = alloca i32*
%8 = alloca i8*
%9 = alloca i64
%10 = alloca i8*
%11 = alloca %struct.addrinfo*
%12 = alloca %struct.addrinfo*
%13 = alloca [2 x %struct.addrinfo]
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
store i8* %0, i8** %5
store %struct.sockaddr_storage* %1, %struct.sockaddr_storage** %6
store i32* %2, i32** %7
%17 = load i8*, i8** %5
%18 = call i32 @strlen(i8* %17)
%19 = add nsw i32 %18, 1
%20 = zext i32 %19 to i64
%21 = call i8* @llvm.stacksave()
store i8* %21, i8** %8
%22 = alloca i8, i64 %20
store i64 %20, i64* %9
%23 = load i32, i32* @SOCK_STREAM
store i32 %23, i32* %15
%24 = load i8*, i8** %5
%25 = icmp ne i8* %24, null
%26 = zext i1 %25 to i32
%27 = call i32 @assert(i32 %26)
%28 = load %struct.sockaddr_storage*, %struct.sockaddr_storage** %6
%29 = icmp ne %struct.sockaddr_storage* %28, null
%30 = zext i1 %29 to i32
%31 = call i32 @assert(i32 %30)
%32 = load i32*, i32** %7
%33 = icmp ne i32* %32, null
%34 = zext i1 %33 to i32
%35 = call i32 @assert(i32 %34)
%36 = load i8*, i8** %5
%37 = trunc i64 %20 to i32
%38 = call i32 @memcpy(i8* %22, i8* %36, i32 %37)
%39 = call i8* @strrchr(i8* %22, i8 signext 47)
store i8* %39, i8** %10
%40 = load i8*, i8** %10
%41 = icmp ne i8* %40, null
br i1 %41, label %44, label %42
42: ; preds = %3
%43 = call i8* @strrchr(i8* %22, i8 signext 58)
store i8* %43, i8** %10
br label %44
44: ; preds = %42, %3
%45 = load i8*, i8** %10
%46 = icmp ne i8* %45, null
br i1 %46, label %50, label %47
47: ; preds = %44
%48 = load i32, i32* @stderr
%49 = call i32 (i32, i8*, ...) @fprintf(i32 %48, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0))
store i32 1, i32* %4
store i32 1, i32* %16
br label %172
50: ; preds = %44
%51 = load i8*, i8** %10
%52 = getelementptr inbounds i8, i8* %51, i32 1
store i8* %52, i8** %10
store i8 0, i8* %51
%53 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 0
%54 = call i32 @memset(%struct.addrinfo* %53, i32 0, i32 40)
%55 = load i64, i64* @AF_INET
%56 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 0
%57 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %56, i32 0, i32 0
store i64 %55, i64* %57
%58 = load i32, i32* %15
%59 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 0
%60 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %59, i32 0, i32 1
store i32 %58, i32* %60
%61 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 1
%62 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 0
%63 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %62, i32 0, i32 4
store %struct.addrinfo* %61, %struct.addrinfo** %63
%64 = load i64, i64* @AF_INET6
%65 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 1
%66 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %65, i32 0, i32 0
store i64 %64, i64* %66
%67 = load i32, i32* %15
%68 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 1
%69 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %68, i32 0, i32 1
store i32 %67, i32* %69
%70 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 1
%71 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %70, i32 0, i32 4
store %struct.addrinfo* null, %struct.addrinfo** %71
%72 = getelementptr inbounds i8, i8* %22, i64 0
%73 = load i8, i8* %72
%74 = sext i8 %73 to i32
%75 = icmp eq i32 %74, 42
br i1 %75, label %76, label %81
76: ; preds = %50
%77 = getelementptr inbounds i8, i8* %22, i64 1
%78 = load i8, i8* %77
%79 = sext i8 %78 to i32
%80 = icmp eq i32 %79, 0
br i1 %80, label %86, label %81
81: ; preds = %76, %50
%82 = getelementptr inbounds i8, i8* %22, i64 0
%83 = load i8, i8* %82
%84 = sext i8 %83 to i32
%85 = icmp eq i32 %84, 0
br i1 %85, label %86, label %97
86: ; preds = %81, %76
%87 = load i32, i32* @AI_PASSIVE
%88 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 0
%89 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %88, i32 0, i32 5
%90 = load i32, i32* %89
%91 = or i32 %90, %87
store i32 %91, i32* %89
%92 = load i32, i32* @AI_PASSIVE
%93 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 1
%94 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %93, i32 0, i32 5
%95 = load i32, i32* %94
%96 = or i32 %95, %92
store i32 %96, i32* %94
store i8 0, i8* %22
br label %102
97: ; preds = %81
%98 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 0
%99 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %98, i32 0, i32 5
store i32 0, i32* %99
%100 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 1
%101 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %100, i32 0, i32 5
store i32 0, i32* %101
br label %102
102: ; preds = %97, %86
%103 = load i8, i8* %22
%104 = sext i8 %103 to i32
%105 = icmp ne i32 %104, 0
br i1 %105, label %106, label %107
106: ; preds = %102
br label %108
107: ; preds = %102
br label %108
108: ; preds = %107, %106
%109 = phi i8* [ %22, %106 ], [ null, %107 ]
%110 = load i8*, i8** %10
%111 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %13, i64 0, i64 0
%112 = call i32 @getaddrinfo(i8* %109, i8* %110, %struct.addrinfo* %111, %struct.addrinfo** %11)
store i32 %112, i32* %14
%113 = load i32, i32* %14
%114 = icmp ne i32 %113, 0
br i1 %114, label %115, label %120
115: ; preds = %108
%116 = load i32, i32* @stderr
%117 = load i32, i32* %14
%118 = call i8* @gai_strerror(i32 %117)
%119 = call i32 (i32, i8*, ...) @fprintf(i32 %116, i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.1, i64 0, i64 0), i8* %22, i8* %118)
store i32 0, i32* %4
store i32 1, i32* %16
br label %172
120: ; preds = %108
%121 = load %struct.addrinfo*, %struct.addrinfo** %11
store %struct.addrinfo* %121, %struct.addrinfo** %12
br label %122
122: ; preds = %162, %120
%123 = load %struct.addrinfo*, %struct.addrinfo** %12
%124 = icmp ne %struct.addrinfo* %123, null
br i1 %124, label %125, label %166
125: ; preds = %122
%126 = load %struct.addrinfo*, %struct.addrinfo** %12
%127 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %126, i32 0, i32 0
%128 = load i64, i64* %127
%129 = load i64, i64* @AF_INET
%130 = icmp eq i64 %128, %129
br i1 %130, label %137, label %131
131: ; preds = %125
%132 = load %struct.addrinfo*, %struct.addrinfo** %12
%133 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %132, i32 0, i32 0
%134 = load i64, i64* %133
%135 = load i64, i64* @AF_INET6
%136 = icmp eq i64 %134, %135
br i1 %136, label %137, label %161
137: ; preds = %131, %125
%138 = load i32*, i32** %7
%139 = load i32, i32* %138
%140 = load %struct.addrinfo*, %struct.addrinfo** %12
%141 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %140, i32 0, i32 2
%142 = load i32, i32* %141
%143 = icmp sge i32 %139, %142
br i1 %143, label %144, label %160
144: ; preds = %137
%145 = load %struct.addrinfo*, %struct.addrinfo** %12
%146 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %145, i32 0, i32 2
%147 = load i32, i32* %146
%148 = load i32*, i32** %7
store i32 %147, i32* %148
%149 = load %struct.sockaddr_storage*, %struct.sockaddr_storage** %6
%150 = bitcast %struct.sockaddr_storage* %149 to i8*
%151 = load %struct.addrinfo*, %struct.addrinfo** %12
%152 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %151, i32 0, i32 3
%153 = load i8*, i8** %152
%154 = load %struct.addrinfo*, %struct.addrinfo** %12
%155 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %154, i32 0, i32 2
%156 = load i32, i32* %155
%157 = call i32 @memcpy(i8* %150, i8* %153, i32 %156)
%158 = load %struct.addrinfo*, %struct.addrinfo** %11
%159 = call i32 @freeaddrinfo(%struct.addrinfo* %158)
store i32 0, i32* %4
store i32 1, i32* %16
br label %172
160: ; preds = %137
br label %161
161: ; preds = %160, %131
br label %162
162: ; preds = %161
%163 = load %struct.addrinfo*, %struct.addrinfo** %12
%164 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %163, i32 0, i32 4
%165 = load %struct.addrinfo*, %struct.addrinfo** %164
store %struct.addrinfo* %165, %struct.addrinfo** %12
br label %122
166: ; preds = %122
%167 = load %struct.addrinfo*, %struct.addrinfo** %11
%168 = call i32 @freeaddrinfo(%struct.addrinfo* %167)
%169 = load i32, i32* @stderr
%170 = load i8*, i8** %5
%171 = call i32 (i32, i8*, ...) @fprintf(i32 %169, i8* getelementptr inbounds ([45 x i8], [45 x i8]* @.str.2, i64 0, i64 0), i8* %170)
store i32 1, i32* %4
store i32 1, i32* %16
br label %172
172: ; preds = %166, %144, %115, %47
%173 = load i8*, i8** %8
%174 = load i32, i32* %4
ret i32 %174
}

LLVM IR (-O2):
%struct.sockaddr_storage = type opaque
%struct.addrinfo = type { i64, i32, i32, i8*, %struct.addrinfo*, i32 }
@SOCK_STREAM = global i32 0
@stderr = global i32 0
@.str = [14 x i8] c"missing port\0A\00"
@AF_INET = global i64 0
@AF_INET6 = global i64 0
@AI_PASSIVE = global i32 0
@.str.1 = [28 x i8] c"getaddrinfo host:%s err:%s\0A\00"
@.str.2 = [45 x i8] c"getaddrinfo():%s:no usable addresses found.\0A\00"
define i32 @socket_addr(i8* %0, %struct.sockaddr_storage* %1, i32* %2) {
%4 = alloca %struct.addrinfo*
%5 = alloca [2 x %struct.addrinfo]
%6 = tail call i32 @strlen(i8* %0)
%7 = add nsw i32 %6, 1
%8 = zext i32 %7 to i64
%9 = alloca i8, i64 %8
%10 = bitcast %struct.addrinfo** %4 to i8*
%11 = bitcast [2 x %struct.addrinfo]* %5 to i8*
%12 = load i32, i32* @SOCK_STREAM
%13 = icmp ne i8* %0, null
%14 = zext i1 %13 to i32
%15 = tail call i32 @assert(i32 %14)
%16 = icmp ne %struct.sockaddr_storage* %1, null
%17 = zext i1 %16 to i32
%18 = tail call i32 @assert(i32 %17)
%19 = icmp ne i32* %2, null
%20 = zext i1 %19 to i32
%21 = tail call i32 @assert(i32 %20)
%22 = call i32 @memcpy(i8* %9, i8* %0, i32 %7)
%23 = call i8* @strrchr(i8* %9, i8 signext 47)
%24 = icmp eq i8* %23, null
br i1 %24, label %25, label %31
25: ; preds = %3
%26 = call i8* @strrchr(i8* %9, i8 signext 58)
%27 = icmp eq i8* %26, null
br i1 %27, label %28, label %31
28: ; preds = %25
%29 = load i32, i32* @stderr
%30 = call i32 (i32, i8*, ...) @fprintf(i32 %29, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0))
br label %104
31: ; preds = %3, %25
%32 = phi i8* [ %26, %25 ], [ %23, %3 ]
%33 = getelementptr inbounds i8, i8* %32, i64 1
store i8 0, i8* %32
%34 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %5, i64 0, i64 0
%35 = call i32 @memset(%struct.addrinfo* %34, i32 0, i32 40)
%36 = load i64, i64* @AF_INET
%37 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %5, i64 0, i64 0, i32 0
store i64 %36, i64* %37
%38 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %5, i64 0, i64 0, i32 1
store i32 %12, i32* %38
%39 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %5, i64 0, i64 1
%40 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %5, i64 0, i64 0, i32 4
store %struct.addrinfo* %39, %struct.addrinfo** %40
%41 = load i64, i64* @AF_INET6
%42 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %39, i64 0, i32 0
store i64 %41, i64* %42
%43 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %5, i64 0, i64 1, i32 1
store i32 %12, i32* %43
%44 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %5, i64 0, i64 1, i32 4
store %struct.addrinfo* null, %struct.addrinfo** %44
%45 = load i8, i8* %9
switch i8 %45, label %58 [
i8 42, label %46
i8 0, label %50
]
46: ; preds = %31
%47 = getelementptr inbounds i8, i8* %9, i64 1
%48 = load i8, i8* %47
%49 = icmp eq i8 %48, 0
br i1 %49, label %50, label %58
50: ; preds = %31, %46
%51 = load i32, i32* @AI_PASSIVE
%52 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %5, i64 0, i64 0, i32 5
%53 = load i32, i32* %52
%54 = or i32 %53, %51
store i32 %54, i32* %52
%55 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %5, i64 0, i64 1, i32 5
%56 = load i32, i32* %55
%57 = or i32 %56, %51
store i32 %57, i32* %55
store i8 0, i8* %9
br label %61
58: ; preds = %31, %46
%59 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %5, i64 0, i64 0, i32 5
store i32 0, i32* %59
%60 = getelementptr inbounds [2 x %struct.addrinfo], [2 x %struct.addrinfo]* %5, i64 0, i64 1, i32 5
store i32 0, i32* %60
br label %61
61: ; preds = %58, %50
%62 = phi i8* [ %9, %58 ], [ null, %50 ]
%63 = call i32 @getaddrinfo(i8* %62, i8* %33, %struct.addrinfo* %34, %struct.addrinfo** %4)
%64 = icmp eq i32 %63, 0
br i1 %64, label %65, label %71
65: ; preds = %61
%66 = load %struct.addrinfo*, %struct.addrinfo** %4
%67 = icmp eq %struct.addrinfo* %66, null
br i1 %67, label %100, label %68
68: ; preds = %65
%69 = load i64, i64* @AF_INET
%70 = load i64, i64* @AF_INET6
br label %75
71: ; preds = %61
%72 = load i32, i32* @stderr
%73 = call i8* @gai_strerror(i32 %63)
%74 = call i32 (i32, i8*, ...) @fprintf(i32 %72, i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.1, i64 0, i64 0), i8* %9, i8* %73)
br label %104
75: ; preds = %68, %96
%76 = phi %struct.addrinfo* [ %66, %68 ], [ %98, %96 ]
%77 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %76, i64 0, i32 0
%78 = load i64, i64* %77
%79 = icmp eq i64 %78, %69
%80 = icmp eq i64 %78, %70
%81 = select i1 %79, i1 true, i1 %80
br i1 %81, label %82, label %96
82: ; preds = %75
%83 = load i32, i32* %2
%84 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %76, i64 0, i32 2
%85 = load i32, i32* %84
%86 = icmp slt i32 %83, %85
br i1 %86, label %96, label %87
87: ; preds = %82
%88 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %76, i64 0, i32 2
store i32 %85, i32* %2
%89 = bitcast %struct.sockaddr_storage* %1 to i8*
%90 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %76, i64 0, i32 3
%91 = load i8*, i8** %90
%92 = load i32, i32* %88
%93 = call i32 @memcpy(i8* %89, i8* %91, i32 %92)
%94 = load %struct.addrinfo*, %struct.addrinfo** %4
%95 = call i32 @freeaddrinfo(%struct.addrinfo* %94)
br label %104
96: ; preds = %75, %82
%97 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %76, i64 0, i32 4
%98 = load %struct.addrinfo*, %struct.addrinfo** %97
%99 = icmp eq %struct.addrinfo* %98, null
br i1 %99, label %100, label %75
100: ; preds = %96, %65
%101 = call i32 @freeaddrinfo(%struct.addrinfo* %66)
%102 = load i32, i32* @stderr
%103 = call i32 (i32, i8*, ...) @fprintf(i32 %102, i8* getelementptr inbounds ([45 x i8], [45 x i8]* @.str.2, i64 0, i64 0), i8* %0)
br label %104
104: ; preds = %100, %87, %71, %28
%105 = phi i32 [ 0, %71 ], [ 0, %87 ], [ 1, %100 ], [ 1, %28 ]
ret i32 %105
}