#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 sockaddr {
  scalar_t__ sa_family;
};

/* Variables and functions */
scalar_t__ AF_INET;
void *getIpAsString(struct sockaddr *socketAddr) {
  struct sockaddr_in *socketAddrIPv4;
  struct sockaddr_in6 *socketAddrIPv6;
  void *result = NULL;
  if (socketAddr->sa_family == AF_INET) {
    socketAddrIPv4 = (struct sockaddr_in *)socketAddr;
    result = &(socketAddrIPv4->sin_addr);
  } else {
    socketAddrIPv6 = (struct sockaddr_in6 *)socketAddr;
    result = &(socketAddrIPv6->sin6_addr);
  }
  return result;
}


x86 assembly (clang, -O0):
<getIpAsString>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movq   $0x0,-0x20(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%rax
mov    0x2eca(%rip),%rcx
cmp    (%rcx),%rax
jne    113c <getIpAsString+0x3c>
mov    -0x8(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
jmp    114c <getIpAsString+0x4c>
mov    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<getIpAsString>:
mov    %rdi,%rax
ret

LLVM IR (-O0):
%struct.sockaddr = type { i64 }
%struct.sockaddr_in = type { i32 }
%struct.sockaddr_in6 = type { i32 }
@AF_INET = global i64 0
define i8* @getIpAsString(%struct.sockaddr* %0) {
%2 = alloca %struct.sockaddr*
%3 = alloca %struct.sockaddr_in*
%4 = alloca %struct.sockaddr_in6*
%5 = alloca i8*
store %struct.sockaddr* %0, %struct.sockaddr** %2
store i8* null, i8** %5
%6 = load %struct.sockaddr*, %struct.sockaddr** %2
%7 = getelementptr inbounds %struct.sockaddr, %struct.sockaddr* %6, i32 0, i32 0
%8 = load i64, i64* %7
%9 = load i64, i64* @AF_INET
%10 = icmp eq i64 %8, %9
br i1 %10, label %11, label %17
11: ; preds = %1
%12 = load %struct.sockaddr*, %struct.sockaddr** %2
%13 = bitcast %struct.sockaddr* %12 to %struct.sockaddr_in*
store %struct.sockaddr_in* %13, %struct.sockaddr_in** %3
%14 = load %struct.sockaddr_in*, %struct.sockaddr_in** %3
%15 = getelementptr inbounds %struct.sockaddr_in, %struct.sockaddr_in* %14, i32 0, i32 0
%16 = bitcast i32* %15 to i8*
store i8* %16, i8** %5
br label %23
17: ; preds = %1
%18 = load %struct.sockaddr*, %struct.sockaddr** %2
%19 = bitcast %struct.sockaddr* %18 to %struct.sockaddr_in6*
store %struct.sockaddr_in6* %19, %struct.sockaddr_in6** %4
%20 = load %struct.sockaddr_in6*, %struct.sockaddr_in6** %4
%21 = getelementptr inbounds %struct.sockaddr_in6, %struct.sockaddr_in6* %20, i32 0, i32 0
%22 = bitcast i32* %21 to i8*
store i8* %22, i8** %5
br label %23
23: ; preds = %17, %11
%24 = load i8*, i8** %5
ret i8* %24
}

LLVM IR (-O2):
%struct.sockaddr = type { i64 }
@AF_INET = global i64 0
define i8* @getIpAsString(%struct.sockaddr* readnone %0) {
%2 = bitcast %struct.sockaddr* %0 to i8*
ret i8* %2
}