#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 passwd {
  void *pw_shell;
  void *pw_dir;
  void *pw_gecos;
  void *pw_passwd;
  void *pw_name;
};

/* Variables and functions */
scalar_t__ malloc(int);
void *strdup(void *);
struct passwd *__pw_dup(const struct passwd *pwent) {
  struct passwd *pw;
  if (!(pw = (struct passwd *)malloc(sizeof *pw)))
    return NULL;
  *pw = *pwent;
  if (!(pw->pw_name = strdup(pwent->pw_name)))
    return NULL;
  if (!(pw->pw_passwd = strdup(pwent->pw_passwd)))
    return NULL;
  if (!(pw->pw_gecos = strdup(pwent->pw_gecos)))
    return NULL;
  if (!(pw->pw_dir = strdup(pwent->pw_dir)))
    return NULL;
  if (!(pw->pw_shell = strdup(pwent->pw_shell)))
    return NULL;
  return pw;
}


x86 assembly (clang, -O0):
<__pw_dup>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
mov    $0x28,%edi
call   1040 <malloc@plt>
mov    %rax,-0x18(%rbp)
cmp    $0x0,%rax
jne    1161 <__pw_dup+0x31>
movq   $0x0,-0x8(%rbp)
jmp    1255 <__pw_dup+0x125>
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    $0x28,%edx
call   1030 <memcpy@plt>
mov    -0x10(%rbp),%rax
mov    0x20(%rax),%rdi
call   1050 <strdup@plt>
mov    -0x18(%rbp),%rcx
mov    %rax,0x20(%rcx)
cmp    $0x0,%rax
jne    119f <__pw_dup+0x6f>
movq   $0x0,-0x8(%rbp)
jmp    1255 <__pw_dup+0x125>
mov    -0x10(%rbp),%rax
mov    0x18(%rax),%rdi
call   1050 <strdup@plt>
mov    -0x18(%rbp),%rcx
mov    %rax,0x18(%rcx)
cmp    $0x0,%rax
jne    11cb <__pw_dup+0x9b>
movq   $0x0,-0x8(%rbp)
jmp    1255 <__pw_dup+0x125>
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rdi
call   1050 <strdup@plt>
mov    -0x18(%rbp),%rcx
mov    %rax,0x10(%rcx)
cmp    $0x0,%rax
jne    11f7 <__pw_dup+0xc7>
movq   $0x0,-0x8(%rbp)
jmp    1255 <__pw_dup+0x125>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
call   1050 <strdup@plt>
mov    -0x18(%rbp),%rcx
mov    %rax,0x8(%rcx)
cmp    $0x0,%rax
jne    1223 <__pw_dup+0xf3>
movq   $0x0,-0x8(%rbp)
jmp    1255 <__pw_dup+0x125>
mov    -0x10(%rbp),%rax
mov    (%rax),%rdi
call   1050 <strdup@plt>
mov    -0x18(%rbp),%rcx
mov    %rax,(%rcx)
cmp    $0x0,%rax
jne    124d <__pw_dup+0x11d>
movq   $0x0,-0x8(%rbp)
jmp    1255 <__pw_dup+0x125>
mov    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<__pw_dup>:
push   %r14
push   %rbx
push   %rax
mov    %rdi,%r14
mov    $0x28,%edi
call   1030 <malloc@plt>
test   %rax,%rax
je     11ad <__pw_dup+0x8d>
mov    %rax,%rbx
mov    0x20(%r14),%rax
mov    %rax,0x20(%rbx)
movups (%r14),%xmm0
movups 0x10(%r14),%xmm1
movups %xmm1,0x10(%rbx)
movups %xmm0,(%rbx)
mov    0x20(%r14),%rdi
call   1040 <strdup@plt>
mov    %rax,0x20(%rbx)
test   %rax,%rax
je     11ad <__pw_dup+0x8d>
mov    0x18(%r14),%rdi
call   1040 <strdup@plt>
mov    %rax,0x18(%rbx)
test   %rax,%rax
je     11ad <__pw_dup+0x8d>
mov    0x10(%r14),%rdi
call   1040 <strdup@plt>
mov    %rax,0x10(%rbx)
test   %rax,%rax
je     11ad <__pw_dup+0x8d>
mov    0x8(%r14),%rdi
call   1040 <strdup@plt>
mov    %rax,0x8(%rbx)
test   %rax,%rax
je     11ad <__pw_dup+0x8d>
mov    (%r14),%rdi
call   1040 <strdup@plt>
mov    %rax,(%rbx)
test   %rax,%rax
cmove  %rax,%rbx
jmp    11af <__pw_dup+0x8f>
xor    %ebx,%ebx
mov    %rbx,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
%struct.passwd = type { i8*, i8*, i8*, i8*, i8* }
define %struct.passwd* @__pw_dup(%struct.passwd* %0) {
%2 = alloca %struct.passwd*
%3 = alloca %struct.passwd*
%4 = alloca %struct.passwd*
store %struct.passwd* %0, %struct.passwd** %3
%5 = call i64 @malloc(i32 40)
%6 = inttoptr i64 %5 to %struct.passwd*
store %struct.passwd* %6, %struct.passwd** %4
%7 = icmp ne %struct.passwd* %6, null
br i1 %7, label %9, label %8
8: ; preds = %1
store %struct.passwd* null, %struct.passwd** %2
br label %60
9: ; preds = %1
%10 = load %struct.passwd*, %struct.passwd** %4
%11 = load %struct.passwd*, %struct.passwd** %3
%12 = bitcast %struct.passwd* %10 to i8*
%13 = bitcast %struct.passwd* %11 to i8*
%14 = load %struct.passwd*, %struct.passwd** %3
%15 = getelementptr inbounds %struct.passwd, %struct.passwd* %14, i32 0, i32 4
%16 = load i8*, i8** %15
%17 = call i8* @strdup(i8* %16)
%18 = load %struct.passwd*, %struct.passwd** %4
%19 = getelementptr inbounds %struct.passwd, %struct.passwd* %18, i32 0, i32 4
store i8* %17, i8** %19
%20 = icmp ne i8* %17, null
br i1 %20, label %22, label %21
21: ; preds = %9
store %struct.passwd* null, %struct.passwd** %2
br label %60
22: ; preds = %9
%23 = load %struct.passwd*, %struct.passwd** %3
%24 = getelementptr inbounds %struct.passwd, %struct.passwd* %23, i32 0, i32 3
%25 = load i8*, i8** %24
%26 = call i8* @strdup(i8* %25)
%27 = load %struct.passwd*, %struct.passwd** %4
%28 = getelementptr inbounds %struct.passwd, %struct.passwd* %27, i32 0, i32 3
store i8* %26, i8** %28
%29 = icmp ne i8* %26, null
br i1 %29, label %31, label %30
30: ; preds = %22
store %struct.passwd* null, %struct.passwd** %2
br label %60
31: ; preds = %22
%32 = load %struct.passwd*, %struct.passwd** %3
%33 = getelementptr inbounds %struct.passwd, %struct.passwd* %32, i32 0, i32 2
%34 = load i8*, i8** %33
%35 = call i8* @strdup(i8* %34)
%36 = load %struct.passwd*, %struct.passwd** %4
%37 = getelementptr inbounds %struct.passwd, %struct.passwd* %36, i32 0, i32 2
store i8* %35, i8** %37
%38 = icmp ne i8* %35, null
br i1 %38, label %40, label %39
39: ; preds = %31
store %struct.passwd* null, %struct.passwd** %2
br label %60
40: ; preds = %31
%41 = load %struct.passwd*, %struct.passwd** %3
%42 = getelementptr inbounds %struct.passwd, %struct.passwd* %41, i32 0, i32 1
%43 = load i8*, i8** %42
%44 = call i8* @strdup(i8* %43)
%45 = load %struct.passwd*, %struct.passwd** %4
%46 = getelementptr inbounds %struct.passwd, %struct.passwd* %45, i32 0, i32 1
store i8* %44, i8** %46
%47 = icmp ne i8* %44, null
br i1 %47, label %49, label %48
48: ; preds = %40
store %struct.passwd* null, %struct.passwd** %2
br label %60
49: ; preds = %40
%50 = load %struct.passwd*, %struct.passwd** %3
%51 = getelementptr inbounds %struct.passwd, %struct.passwd* %50, i32 0, i32 0
%52 = load i8*, i8** %51
%53 = call i8* @strdup(i8* %52)
%54 = load %struct.passwd*, %struct.passwd** %4
%55 = getelementptr inbounds %struct.passwd, %struct.passwd* %54, i32 0, i32 0
store i8* %53, i8** %55
%56 = icmp ne i8* %53, null
br i1 %56, label %58, label %57
57: ; preds = %49
store %struct.passwd* null, %struct.passwd** %2
br label %60
58: ; preds = %49
%59 = load %struct.passwd*, %struct.passwd** %4
store %struct.passwd* %59, %struct.passwd** %2
br label %60
60: ; preds = %58, %57, %48, %39, %30, %21, %8
%61 = load %struct.passwd*, %struct.passwd** %2
ret %struct.passwd* %61
}

LLVM IR (-O2):
%struct.passwd = type { i8*, i8*, i8*, i8*, i8* }
define %struct.passwd* @__pw_dup(%struct.passwd* nocapture %0) {
%2 = tail call i64 @malloc(i32 40)
%3 = inttoptr i64 %2 to %struct.passwd*
%4 = icmp eq i64 %2, 0
br i1 %4, label %38, label %5
5: ; preds = %1
%6 = inttoptr i64 %2 to i8*
%7 = bitcast %struct.passwd* %0 to i8*
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 dereferenceable(40) %6, i8* align 8 dereferenceable(40) %7, i64 40, i1 false)
%8 = getelementptr inbounds %struct.passwd, %struct.passwd* %0, i64 0, i32 4
%9 = load i8*, i8** %8
%10 = tail call i8* @strdup(i8* %9)
%11 = getelementptr inbounds %struct.passwd, %struct.passwd* %3, i64 0, i32 4
store i8* %10, i8** %11
%12 = icmp eq i8* %10, null
br i1 %12, label %38, label %13
13: ; preds = %5
%14 = getelementptr inbounds %struct.passwd, %struct.passwd* %0, i64 0, i32 3
%15 = load i8*, i8** %14
%16 = tail call i8* @strdup(i8* %15)
%17 = getelementptr inbounds %struct.passwd, %struct.passwd* %3, i64 0, i32 3
store i8* %16, i8** %17
%18 = icmp eq i8* %16, null
br i1 %18, label %38, label %19
19: ; preds = %13
%20 = getelementptr inbounds %struct.passwd, %struct.passwd* %0, i64 0, i32 2
%21 = load i8*, i8** %20
%22 = tail call i8* @strdup(i8* %21)
%23 = getelementptr inbounds %struct.passwd, %struct.passwd* %3, i64 0, i32 2
store i8* %22, i8** %23
%24 = icmp eq i8* %22, null
br i1 %24, label %38, label %25
25: ; preds = %19
%26 = getelementptr inbounds %struct.passwd, %struct.passwd* %0, i64 0, i32 1
%27 = load i8*, i8** %26
%28 = tail call i8* @strdup(i8* %27)
%29 = getelementptr inbounds %struct.passwd, %struct.passwd* %3, i64 0, i32 1
store i8* %28, i8** %29
%30 = icmp eq i8* %28, null
br i1 %30, label %38, label %31
31: ; preds = %25
%32 = getelementptr inbounds %struct.passwd, %struct.passwd* %0, i64 0, i32 0
%33 = load i8*, i8** %32
%34 = tail call i8* @strdup(i8* %33)
%35 = getelementptr inbounds %struct.passwd, %struct.passwd* %3, i64 0, i32 0
store i8* %34, i8** %35
%36 = icmp eq i8* %34, null
%37 = select i1 %36, %struct.passwd* null, %struct.passwd* %3
br label %38
38: ; preds = %31, %25, %19, %13, %5, %1
%39 = phi %struct.passwd* [ null, %1 ], [ null, %5 ], [ null, %13 ], [ null, %19 ], [ null, %25 ], [ %37, %31 ]
ret %struct.passwd* %39
}