#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 stat {
  int st_mode;
  int /*<<< orphan*/ st_atime;
  int /*<<< orphan*/ st_mtime;
  int /*<<< orphan*/ st_gid;
  int /*<<< orphan*/ st_uid;
  int /*<<< orphan*/ st_size;
};
struct passwd {
  int /*<<< orphan*/ pw_name;
};
struct mytar {
  int dummy;
};
struct group {
  int /*<<< orphan*/ gr_name;
};

/* Variables and functions */
int S_IFMT;
scalar_t__ S_ISDIR(int);
scalar_t__ S_ISLNK(int);
struct group *getgrgid(int /*<<< orphan*/);
struct passwd *getpwuid(int /*<<< orphan*/);
int /*<<< orphan*/ mytar_set_atime(struct mytar *, int /*<<< orphan*/);
int /*<<< orphan*/ mytar_set_filetype(struct mytar *, int);
int /*<<< orphan*/ mytar_set_gid(struct mytar *, int /*<<< orphan*/);
int /*<<< orphan*/ mytar_set_gname(struct mytar *, int /*<<< orphan*/);
int /*<<< orphan*/ mytar_set_mode(struct mytar *, int);
int /*<<< orphan*/ mytar_set_mtime(struct mytar *, int /*<<< orphan*/);
int /*<<< orphan*/ mytar_set_size(struct mytar *, int /*<<< orphan*/);
int /*<<< orphan*/ mytar_set_uid(struct mytar *, int /*<<< orphan*/);
int /*<<< orphan*/ mytar_set_uname(struct mytar *, int /*<<< orphan*/);
void mytar_set_from_stat(struct mytar *t, struct stat *s) {
  mytar_set_mode(t, s->st_mode & ~S_IFMT);
  if (S_ISDIR(s->st_mode) || S_ISLNK(s->st_mode))
    mytar_set_size(t, 0);
  else
    mytar_set_size(t, s->st_size);
  mytar_set_uid(t, s->st_uid);
  {
    struct passwd *p = getpwuid(s->st_uid);
    if (p)
      mytar_set_uname(t, p->pw_name);
  }
  mytar_set_gid(t, s->st_gid);
  {
    struct group *p = getgrgid(s->st_gid);
    if (p)
      mytar_set_gname(t, p->gr_name);
  }
  mytar_set_filetype(t, s->st_mode & S_IFMT);
  mytar_set_mtime(t, s->st_mtime);
  mytar_set_atime(t, s->st_atime);
}


x86 assembly (clang, -O0):
<mytar_set_from_stat>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rax
mov    (%rax),%esi
mov    0x2def(%rip),%rax
mov    (%rax),%eax
xor    $0xffffffff,%eax
and    %eax,%esi
call   1090 <mytar_set_mode@plt>
mov    -0x10(%rbp),%rax
mov    (%rax),%edi
call   1070 <S_ISDIR@plt>
cmp    $0x0,%rax
jne    1227 <mytar_set_from_stat+0x57>
mov    -0x10(%rbp),%rax
mov    (%rax),%edi
call   1050 <S_ISLNK@plt>
cmp    $0x0,%rax
je     1237 <mytar_set_from_stat+0x67>
mov    -0x8(%rbp),%rdi
xor    %esi,%esi
call   1040 <mytar_set_size@plt>
jmp    1247 <mytar_set_from_stat+0x77>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rax
mov    0x14(%rax),%esi
call   1040 <mytar_set_size@plt>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%esi
call   10f0 <mytar_set_uid@plt>
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%edi
call   1060 <getpwuid@plt>
mov    %rax,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
je     1281 <mytar_set_from_stat+0xb1>
mov    -0x8(%rbp),%rdi
mov    -0x18(%rbp),%rax
mov    (%rax),%esi
call   10e0 <mytar_set_uname@plt>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rax
mov    0xc(%rax),%esi
call   10a0 <mytar_set_gid@plt>
mov    -0x10(%rbp),%rax
mov    0xc(%rax),%edi
call   1080 <getgrgid@plt>
mov    %rax,-0x20(%rbp)
cmpq   $0x0,-0x20(%rbp)
je     12bb <mytar_set_from_stat+0xeb>
mov    -0x8(%rbp),%rdi
mov    -0x20(%rbp),%rax
mov    (%rax),%esi
call   10b0 <mytar_set_gname@plt>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rax
mov    (%rax),%esi
mov    0x2d14(%rip),%rax
and    (%rax),%esi
call   1030 <mytar_set_filetype@plt>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%esi
call   10c0 <mytar_set_mtime@plt>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rax
mov    0x4(%rax),%esi
call   10d0 <mytar_set_atime@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<mytar_set_from_stat>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %rsi,%rbx
mov    %rdi,%r14
mov    0x2dfc(%rip),%r15
mov    (%r15),%esi
not    %esi
and    (%rbx),%esi
call   1090 <mytar_set_mode@plt>
mov    (%rbx),%edi
call   1070 <S_ISDIR@plt>
xor    %ebp,%ebp
test   %rax,%rax
jne    120d <mytar_set_from_stat+0x3d>
mov    (%rbx),%edi
call   1050 <S_ISLNK@plt>
test   %rax,%rax
jne    120d <mytar_set_from_stat+0x3d>
mov    0x14(%rbx),%ebp
mov    %r14,%rdi
mov    %ebp,%esi
call   1040 <mytar_set_size@plt>
mov    0x10(%rbx),%esi
mov    %r14,%rdi
call   10f0 <mytar_set_uid@plt>
mov    0x10(%rbx),%edi
call   1060 <getpwuid@plt>
test   %rax,%rax
je     1239 <mytar_set_from_stat+0x69>
mov    (%rax),%esi
mov    %r14,%rdi
call   10e0 <mytar_set_uname@plt>
mov    0xc(%rbx),%esi
mov    %r14,%rdi
call   10a0 <mytar_set_gid@plt>
mov    0xc(%rbx),%edi
call   1080 <getgrgid@plt>
test   %rax,%rax
je     125b <mytar_set_from_stat+0x8b>
mov    (%rax),%esi
mov    %r14,%rdi
call   10b0 <mytar_set_gname@plt>
mov    (%r15),%esi
and    (%rbx),%esi
mov    %r14,%rdi
call   1030 <mytar_set_filetype@plt>
mov    0x8(%rbx),%esi
mov    %r14,%rdi
call   10c0 <mytar_set_mtime@plt>
mov    0x4(%rbx),%esi
mov    %r14,%rdi
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
jmp    10d0 <mytar_set_atime@plt>

LLVM IR (-O0):
%struct.mytar = type { i32 }
%struct.stat = type { i32, i32, i32, i32, i32, i32 }
%struct.passwd = type { i32 }
%struct.group = type { i32 }
@S_IFMT = global i32 0
define void @mytar_set_from_stat(%struct.mytar* %0, %struct.stat* %1) {
%3 = alloca %struct.mytar*
%4 = alloca %struct.stat*
%5 = alloca %struct.passwd*
%6 = alloca %struct.group*
store %struct.mytar* %0, %struct.mytar** %3
store %struct.stat* %1, %struct.stat** %4
%7 = load %struct.mytar*, %struct.mytar** %3
%8 = load %struct.stat*, %struct.stat** %4
%9 = getelementptr inbounds %struct.stat, %struct.stat* %8, i32 0, i32 0
%10 = load i32, i32* %9
%11 = load i32, i32* @S_IFMT
%12 = xor i32 %11, -1
%13 = and i32 %10, %12
%14 = call i32 @mytar_set_mode(%struct.mytar* %7, i32 %13)
%15 = load %struct.stat*, %struct.stat** %4
%16 = getelementptr inbounds %struct.stat, %struct.stat* %15, i32 0, i32 0
%17 = load i32, i32* %16
%18 = call i64 @S_ISDIR(i32 %17)
%19 = icmp ne i64 %18, 0
br i1 %19, label %26, label %20
20: ; preds = %2
%21 = load %struct.stat*, %struct.stat** %4
%22 = getelementptr inbounds %struct.stat, %struct.stat* %21, i32 0, i32 0
%23 = load i32, i32* %22
%24 = call i64 @S_ISLNK(i32 %23)
%25 = icmp ne i64 %24, 0
br i1 %25, label %26, label %29
26: ; preds = %20, %2
%27 = load %struct.mytar*, %struct.mytar** %3
%28 = call i32 @mytar_set_size(%struct.mytar* %27, i32 0)
br label %35
29: ; preds = %20
%30 = load %struct.mytar*, %struct.mytar** %3
%31 = load %struct.stat*, %struct.stat** %4
%32 = getelementptr inbounds %struct.stat, %struct.stat* %31, i32 0, i32 5
%33 = load i32, i32* %32
%34 = call i32 @mytar_set_size(%struct.mytar* %30, i32 %33)
br label %35
35: ; preds = %29, %26
%36 = load %struct.mytar*, %struct.mytar** %3
%37 = load %struct.stat*, %struct.stat** %4
%38 = getelementptr inbounds %struct.stat, %struct.stat* %37, i32 0, i32 4
%39 = load i32, i32* %38
%40 = call i32 @mytar_set_uid(%struct.mytar* %36, i32 %39)
%41 = load %struct.stat*, %struct.stat** %4
%42 = getelementptr inbounds %struct.stat, %struct.stat* %41, i32 0, i32 4
%43 = load i32, i32* %42
%44 = call %struct.passwd* @getpwuid(i32 %43)
store %struct.passwd* %44, %struct.passwd** %5
%45 = load %struct.passwd*, %struct.passwd** %5
%46 = icmp ne %struct.passwd* %45, null
br i1 %46, label %47, label %53
47: ; preds = %35
%48 = load %struct.mytar*, %struct.mytar** %3
%49 = load %struct.passwd*, %struct.passwd** %5
%50 = getelementptr inbounds %struct.passwd, %struct.passwd* %49, i32 0, i32 0
%51 = load i32, i32* %50
%52 = call i32 @mytar_set_uname(%struct.mytar* %48, i32 %51)
br label %53
53: ; preds = %47, %35
%54 = load %struct.mytar*, %struct.mytar** %3
%55 = load %struct.stat*, %struct.stat** %4
%56 = getelementptr inbounds %struct.stat, %struct.stat* %55, i32 0, i32 3
%57 = load i32, i32* %56
%58 = call i32 @mytar_set_gid(%struct.mytar* %54, i32 %57)
%59 = load %struct.stat*, %struct.stat** %4
%60 = getelementptr inbounds %struct.stat, %struct.stat* %59, i32 0, i32 3
%61 = load i32, i32* %60
%62 = call %struct.group* @getgrgid(i32 %61)
store %struct.group* %62, %struct.group** %6
%63 = load %struct.group*, %struct.group** %6
%64 = icmp ne %struct.group* %63, null
br i1 %64, label %65, label %71
65: ; preds = %53
%66 = load %struct.mytar*, %struct.mytar** %3
%67 = load %struct.group*, %struct.group** %6
%68 = getelementptr inbounds %struct.group, %struct.group* %67, i32 0, i32 0
%69 = load i32, i32* %68
%70 = call i32 @mytar_set_gname(%struct.mytar* %66, i32 %69)
br label %71
71: ; preds = %65, %53
%72 = load %struct.mytar*, %struct.mytar** %3
%73 = load %struct.stat*, %struct.stat** %4
%74 = getelementptr inbounds %struct.stat, %struct.stat* %73, i32 0, i32 0
%75 = load i32, i32* %74
%76 = load i32, i32* @S_IFMT
%77 = and i32 %75, %76
%78 = call i32 @mytar_set_filetype(%struct.mytar* %72, i32 %77)
%79 = load %struct.mytar*, %struct.mytar** %3
%80 = load %struct.stat*, %struct.stat** %4
%81 = getelementptr inbounds %struct.stat, %struct.stat* %80, i32 0, i32 2
%82 = load i32, i32* %81
%83 = call i32 @mytar_set_mtime(%struct.mytar* %79, i32 %82)
%84 = load %struct.mytar*, %struct.mytar** %3
%85 = load %struct.stat*, %struct.stat** %4
%86 = getelementptr inbounds %struct.stat, %struct.stat* %85, i32 0, i32 1
%87 = load i32, i32* %86
%88 = call i32 @mytar_set_atime(%struct.mytar* %84, i32 %87)
ret void
}

LLVM IR (-O2):
%struct.mytar = type { i32 }
%struct.stat = type { i32, i32, i32, i32, i32, i32 }
%struct.passwd = type { i32 }
%struct.group = type { i32 }
@S_IFMT = global i32 0
define void @mytar_set_from_stat(%struct.mytar* %0, %struct.stat* nocapture %1) {
%3 = getelementptr inbounds %struct.stat, %struct.stat* %1, i64 0, i32 0
%4 = load i32, i32* %3
%5 = load i32, i32* @S_IFMT
%6 = xor i32 %5, -1
%7 = and i32 %4, %6
%8 = tail call i32 @mytar_set_mode(%struct.mytar* %0, i32 %7)
%9 = load i32, i32* %3
%10 = tail call i64 @S_ISDIR(i32 %9)
%11 = icmp eq i64 %10, 0
br i1 %11, label %12, label %19
12: ; preds = %2
%13 = load i32, i32* %3
%14 = tail call i64 @S_ISLNK(i32 %13)
%15 = icmp eq i64 %14, 0
br i1 %15, label %16, label %19
16: ; preds = %12
%17 = getelementptr inbounds %struct.stat, %struct.stat* %1, i64 0, i32 5
%18 = load i32, i32* %17
br label %19
19: ; preds = %2, %12, %16
%20 = phi i32 [ %18, %16 ], [ 0, %12 ], [ 0, %2 ]
%21 = tail call i32 @mytar_set_size(%struct.mytar* %0, i32 %20)
%22 = getelementptr inbounds %struct.stat, %struct.stat* %1, i64 0, i32 4
%23 = load i32, i32* %22
%24 = tail call i32 @mytar_set_uid(%struct.mytar* %0, i32 %23)
%25 = load i32, i32* %22
%26 = tail call %struct.passwd* @getpwuid(i32 %25)
%27 = icmp eq %struct.passwd* %26, null
br i1 %27, label %32, label %28
28: ; preds = %19
%29 = getelementptr inbounds %struct.passwd, %struct.passwd* %26, i64 0, i32 0
%30 = load i32, i32* %29
%31 = tail call i32 @mytar_set_uname(%struct.mytar* %0, i32 %30)
br label %32
32: ; preds = %28, %19
%33 = getelementptr inbounds %struct.stat, %struct.stat* %1, i64 0, i32 3
%34 = load i32, i32* %33
%35 = tail call i32 @mytar_set_gid(%struct.mytar* %0, i32 %34)
%36 = load i32, i32* %33
%37 = tail call %struct.group* @getgrgid(i32 %36)
%38 = icmp eq %struct.group* %37, null
br i1 %38, label %43, label %39
39: ; preds = %32
%40 = getelementptr inbounds %struct.group, %struct.group* %37, i64 0, i32 0
%41 = load i32, i32* %40
%42 = tail call i32 @mytar_set_gname(%struct.mytar* %0, i32 %41)
br label %43
43: ; preds = %39, %32
%44 = load i32, i32* %3
%45 = load i32, i32* @S_IFMT
%46 = and i32 %45, %44
%47 = tail call i32 @mytar_set_filetype(%struct.mytar* %0, i32 %46)
%48 = getelementptr inbounds %struct.stat, %struct.stat* %1, i64 0, i32 2
%49 = load i32, i32* %48
%50 = tail call i32 @mytar_set_mtime(%struct.mytar* %0, i32 %49)
%51 = getelementptr inbounds %struct.stat, %struct.stat* %1, i64 0, i32 1
%52 = load i32, i32* %51
%53 = tail call i32 @mytar_set_atime(%struct.mytar* %0, i32 %52)
ret void
}