#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_in6 {
  int /*<<< orphan*/ sin6_addr;
};
struct sockaddr_in {
  int /*<<< orphan*/ sin_addr;
};
struct addrinfo {
  int ai_family;
  struct addrinfo *ai_next;
  scalar_t__ ai_addr;
};

/* Variables and functions */
#define AF_INET 129
#define AF_INET6 128
int /*<<< orphan*/ inet_ntop(int, void *, char *, int);
int /*<<< orphan*/ printf(char *, int, char *);
void printip(struct addrinfo *res) {
  char buf[256];
  void *ptr;
  while (res != NULL) {
    switch (res->ai_family) {
    case AF_INET:
      ptr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
      break;
    case AF_INET6:
      ptr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
      break;
    }
    inet_ntop(res->ai_family, ptr, buf, 255);
    printf("\tIPv%d address: %s\n", (res->ai_family == AF_INET6) ? 6 : 4, buf);
    res = res->ai_next;
  }
}


x86 assembly (clang, -O0):
<printip>:
push   %rbp
mov    %rsp,%rbp
sub    $0x120,%rsp
mov    %rdi,-0x8(%rbp)
cmpq   $0x0,-0x8(%rbp)
je     11ea <printip+0xca>
mov    -0x8(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x11c(%rbp)
sub    $0x80,%eax
je     1180 <printip+0x60>
jmp    1156 <printip+0x36>
mov    -0x11c(%rbp),%eax
sub    $0x81,%eax
jne    118f <printip+0x6f>
jmp    116c <printip+0x4c>
mov    -0x8(%rbp),%rax
mov    0x10(%rax),%rax
mov    %rax,-0x118(%rbp)
jmp    118f <printip+0x6f>
mov    -0x8(%rbp),%rax
mov    0x10(%rax),%rax
mov    %rax,-0x118(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%edi
mov    -0x118(%rbp),%rsi
lea    -0x110(%rbp),%rdx
mov    $0xff,%ecx
call   1030 <inet_ntop@plt>
mov    -0x8(%rbp),%rax
mov    (%rax),%ecx
mov    $0x4,%esi
mov    $0x6,%eax
cmp    $0x80,%ecx
cmove  %eax,%esi
lea    -0x110(%rbp),%rdx
lea    0xe2c(%rip),%rdi
call   1040 <printf@plt>
mov    -0x8(%rbp),%rax
mov    0x8(%rax),%rax
mov    %rax,-0x8(%rbp)
jmp    112f <printip+0xf>
add    $0x120,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<printip>:
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x108,%rsp
test   %rdi,%rdi
je     1199 <printip+0x79>
mov    %rdi,%rbx
mov    %rsp,%r14
lea    0xec0(%rip),%r15
jmp    1185 <printip+0x65>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    %r12,%rsi
mov    %r14,%rdx
mov    $0xff,%ecx
call   1030 <inet_ntop@plt>
xor    %eax,%eax
cmpl   $0x80,(%rbx)
sete   %al
lea    (%rax,%rax,1),%esi
add    $0x4,%esi
mov    %r15,%rdi
mov    %r14,%rdx
call   1040 <printf@plt>
mov    0x8(%rbx),%rbx
test   %rbx,%rbx
je     1199 <printip+0x79>
mov    (%rbx),%edi
mov    %edi,%eax
and    $0xfffffffe,%eax
cmp    $0x80,%eax
jne    1150 <printip+0x30>
mov    0x10(%rbx),%r12
jmp    1150 <printip+0x30>
add    $0x108,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
%struct.addrinfo = type { i32, %struct.addrinfo*, i64 }
%struct.sockaddr_in = type { i32 }
%struct.sockaddr_in6 = type { i32 }
@.str = [20 x i8] c"\09IPv%d address: %s\0A\00"
define void @printip(%struct.addrinfo* %0) {
%2 = alloca %struct.addrinfo*
%3 = alloca [256 x i8]
%4 = alloca i8*
store %struct.addrinfo* %0, %struct.addrinfo** %2
br label %5
5: ; preds = %26, %1
%6 = load %struct.addrinfo*, %struct.addrinfo** %2
%7 = icmp ne %struct.addrinfo* %6, null
br i1 %7, label %8, label %44
8: ; preds = %5
%9 = load %struct.addrinfo*, %struct.addrinfo** %2
%10 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %9, i32 0, i32 0
%11 = load i32, i32* %10
switch i32 %11, label %26 [
i32 129, label %12
i32 128, label %19
]
12: ; preds = %8
%13 = load %struct.addrinfo*, %struct.addrinfo** %2
%14 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %13, i32 0, i32 2
%15 = load i64, i64* %14
%16 = inttoptr i64 %15 to %struct.sockaddr_in*
%17 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %16, i32 0, i32 0
%18 = bitcast i32* %17 to i8*
store i8* %18, i8** %4
br label %26
19: ; preds = %8
%20 = load %struct.addrinfo*, %struct.addrinfo** %2
%21 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %20, i32 0, i32 2
%22 = load i64, i64* %21
%23 = inttoptr i64 %22 to %struct.sockaddr_in6*
%24 = getelementptr inbounds %struct.sockaddr_in6, %struct.sockaddr_in6* %23, i32 0, i32 0
%25 = bitcast i32* %24 to i8*
store i8* %25, i8** %4
br label %26
26: ; preds = %8, %19, %12
%27 = load %struct.addrinfo*, %struct.addrinfo** %2
%28 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %27, i32 0, i32 0
%29 = load i32, i32* %28
%30 = load i8*, i8** %4
%31 = getelementptr inbounds [256 x i8], [256 x i8]* %3, i64 0, i64 0
%32 = call i32 @inet_ntop(i32 %29, i8* %30, i8* %31, i32 255)
%33 = load %struct.addrinfo*, %struct.addrinfo** %2
%34 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %33, i32 0, i32 0
%35 = load i32, i32* %34
%36 = icmp eq i32 %35, 128
%37 = zext i1 %36 to i64
%38 = select i1 %36, i32 6, i32 4
%39 = getelementptr inbounds [256 x i8], [256 x i8]* %3, i64 0, i64 0
%40 = call i32 @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i64 0, i64 0), i32 %38, i8* %39)
%41 = load %struct.addrinfo*, %struct.addrinfo** %2
%42 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %41, i32 0, i32 1
%43 = load %struct.addrinfo*, %struct.addrinfo** %42
store %struct.addrinfo* %43, %struct.addrinfo** %2
br label %5
44: ; preds = %5
ret void
}

LLVM IR (-O2):
%struct.addrinfo = type { i32, %struct.addrinfo*, i64 }
@.str = [20 x i8] c"\09IPv%d address: %s\0A\00"
define void @printip(%struct.addrinfo* %0) {
%2 = alloca [256 x i8]
%3 = getelementptr inbounds [256 x i8], [256 x i8]* %2, i64 0, i64 0
%4 = icmp eq %struct.addrinfo* %0, null
br i1 %4, label %26, label %5
5: ; preds = %1, %16
%6 = phi i8* [ %17, %16 ], [ undef, %1 ]
%7 = phi %struct.addrinfo* [ %24, %16 ], [ %0, %1 ]
%8 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %7, i64 0, i32 0
%9 = load i32, i32* %8
%10 = and i32 %9, -2
%11 = icmp eq i32 %10, 128
br i1 %11, label %12, label %16
12: ; preds = %5
%13 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %7, i64 0, i32 2
%14 = load i64, i64* %13
%15 = inttoptr i64 %14 to i8*
br label %16
16: ; preds = %5, %12
%17 = phi i8* [ %6, %5 ], [ %15, %12 ]
%18 = call i32 @inet_ntop(i32 %9, i8* %17, i8* %3, i32 255)
%19 = load i32, i32* %8
%20 = icmp eq i32 %19, 128
%21 = select i1 %20, i32 6, i32 4
%22 = call i32 @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i64 0, i64 0), i32 %21, i8* %3)
%23 = getelementptr inbounds %struct.addrinfo, %struct.addrinfo* %7, i64 0, i32 1
%24 = load %struct.addrinfo*, %struct.addrinfo** %23
%25 = icmp eq %struct.addrinfo* %24, null
br i1 %25, label %26, label %5
26: ; preds = %16, %1
ret void
}