#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 *uint64_t;
struct msghdr {
  char *msg_control;
  int msg_controllen;
  scalar_t__ msg_flags;
};
struct cmsghdr {
  int dummy;
};

/* Variables and functions */
struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *);
uint64_t c_get_cmsg_overhead() {
  char buf[1];
  struct msghdr mhdr;
  struct cmsghdr *p = 0;
  mhdr.msg_control = buf;
  mhdr.msg_controllen = 256;
  mhdr.msg_flags = 0;
  p = CMSG_FIRSTHDR(&mhdr);
  return ((char *)(CMSG_DATA(p)) - ((char *)p));
}


x86 assembly (clang, -O0):
<c_get_cmsg_overhead>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movq   $0x0,-0x28(%rbp)
lea    -0x1(%rbp),%rax
mov    %rax,-0x20(%rbp)
movl   $0x100,-0x18(%rbp)
movq   $0x0,-0x10(%rbp)
lea    -0x20(%rbp),%rdi
call   1040 <CMSG_FIRSTHDR@plt>
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rdi
mov    $0x0,%al
call   1030 <CMSG_DATA@plt>
cltq
mov    -0x28(%rbp),%rcx
sub    %rcx,%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<c_get_cmsg_overhead>:
push   %rbx
sub    $0x20,%rsp
lea    0x7(%rsp),%rax
mov    %rax,0x8(%rsp)
movl   $0x100,0x10(%rsp)
movq   $0x0,0x18(%rsp)
lea    0x8(%rsp),%rdi
call   1040 <CMSG_FIRSTHDR@plt>
mov    %rax,%rbx
mov    %rax,%rdi
xor    %eax,%eax
call   1030 <CMSG_DATA@plt>
cltq
sub    %rbx,%rax
add    $0x20,%rsp
pop    %rbx
ret

LLVM IR (-O0):
%struct.msghdr = type { i8*, i32, i64 }
%struct.cmsghdr = type { i32 }
define i8* @c_get_cmsg_overhead() {
%1 = alloca [1 x i8]
%2 = alloca %struct.msghdr
%3 = alloca %struct.cmsghdr*
store %struct.cmsghdr* null, %struct.cmsghdr** %3
%4 = getelementptr inbounds [1 x i8], [1 x i8]* %1, i64 0, i64 0
%5 = getelementptr inbounds %struct.msghdr, %struct.msghdr* %2, i32 0, i32 0
store i8* %4, i8** %5
%6 = getelementptr inbounds %struct.msghdr, %struct.msghdr* %2, i32 0, i32 1
store i32 256, i32* %6
%7 = getelementptr inbounds %struct.msghdr, %struct.msghdr* %2, i32 0, i32 2
store i64 0, i64* %7
%8 = call %struct.cmsghdr* @CMSG_FIRSTHDR(%struct.msghdr* %2)
store %struct.cmsghdr* %8, %struct.cmsghdr** %3
%9 = load %struct.cmsghdr*, %struct.cmsghdr** %3
%10 = call i32 (%struct.cmsghdr*, ...) bitcast (i32 (...)* @CMSG_DATA to i32 (%struct.cmsghdr*, ...)*)(%struct.cmsghdr* %9)
%11 = sext i32 %10 to i64
%12 = inttoptr i64 %11 to i8*
%13 = load %struct.cmsghdr*, %struct.cmsghdr** %3
%14 = bitcast %struct.cmsghdr* %13 to i8*
%15 = ptrtoint i8* %12 to i64
%16 = ptrtoint i8* %14 to i64
%17 = sub i64 %15, %16
%18 = inttoptr i64 %17 to i8*
ret i8* %18
}

LLVM IR (-O2):
%struct.msghdr = type { i8*, i32, i64 }
%struct.cmsghdr = type { i32 }
define i8* @c_get_cmsg_overhead() {
%1 = alloca [1 x i8]
%2 = alloca %struct.msghdr
%3 = getelementptr inbounds [1 x i8], [1 x i8]* %1, i64 0, i64 0
%4 = bitcast %struct.msghdr* %2 to i8*
%5 = getelementptr inbounds %struct.msghdr, %struct.msghdr* %2, i64 0, i32 0
store i8* %3, i8** %5
%6 = getelementptr inbounds %struct.msghdr, %struct.msghdr* %2, i64 0, i32 1
store i32 256, i32* %6
%7 = getelementptr inbounds %struct.msghdr, %struct.msghdr* %2, i64 0, i32 2
store i64 0, i64* %7
%8 = call %struct.cmsghdr* @CMSG_FIRSTHDR(%struct.msghdr* %2)
%9 = call i32 (%struct.cmsghdr*, ...) bitcast (i32 (...)* @CMSG_DATA to i32 (%struct.cmsghdr*, ...)*)(%struct.cmsghdr* %8)
%10 = sext i32 %9 to i64
%11 = ptrtoint %struct.cmsghdr* %8 to i64
%12 = sub i64 %10, %11
%13 = inttoptr i64 %12 to i8*
ret i8* %13
}