#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 {
  scalar_t__ st_dev;
  scalar_t__ st_ino;
};
struct dirent {
  char *d_name;
  scalar_t__ d_ino;
};
typedef scalar_t__ ino_t;
typedef int /*<<< orphan*/ dots;
typedef scalar_t__ dev_t;
typedef int /*<<< orphan*/ DIR;

/* Variables and functions */
int MAX(size_t, size_t);
int PATH_MAX;
int /*<<< orphan*/ _D_ALLOC_NAMLEN(struct dirent *);
size_t _D_EXACT_NAMLEN(struct dirent *);
int /*<<< orphan*/ closedir(int /*<<< orphan*/ *);
int /*<<< orphan*/ free(char *);
char *malloc(size_t);
char *memcpy(char *, char const *, size_t);
int /*<<< orphan*/ memmove(char *, char *, int);
int /*<<< orphan*/ *opendir(char const *);
struct dirent *readdir(int /*<<< orphan*/ *);
char *realloc(char *, size_t);
scalar_t__ stat(char const *, struct stat *);
int /*<<< orphan*/ strcpy(char *, char *);
char *getcwd(char *buf, size_t size) {
  static const char dots[] = "../../../../../../../../../../../../../../../../"
                             "../../../../../../../        "
                             "../../../../../../../../../../../../../../../../"
                             "../../../../../../../../../../        "
                             "../../../../../../../../../../../../../../../../"
                             "../../../../../../../../../..";
  const char *dotp = &dots[sizeof(dots)];
  const char *dotlist = dots;
  size_t dotsize = sizeof(dots) - 1;
  dev_t rootdev, thisdev;
  ino_t rootino, thisino;
  char *path;
  register char *pathp;
  struct stat st;
  size_t allocated = size;
  if (size == 0) {
    if (buf != NULL) {
      return NULL;
    }
    allocated = PATH_MAX + 1;
  }
  if (buf != NULL) {
    path = buf;
  } else {
    path = malloc(allocated);
    if (path == NULL) {
      return NULL;
    }
  }
  pathp = path + allocated;
  *--pathp = '\0';
  if (stat(".", &st) < 0) {
    goto lose2;
  }
  thisdev = st.st_dev;
  thisino = st.st_ino;
  if (stat("/", &st) < 0) {
    goto lose2;
  }
  rootdev = st.st_dev;
  rootino = st.st_ino;
  while (!(thisdev == rootdev && thisino == rootino)) {
    register DIR *dirstream;
    struct dirent *d;
    dev_t dotdev;
    ino_t dotino;
    char mount_point;
    if (dotp == dotlist) {
      char *new;
      if (dotlist == dots) {
        new = malloc(dotsize * 2 + 1);
        if (new == NULL) {
          goto lose;
        }
        memcpy(new, dots, dotsize);
        dotp = &new[dotsize];
      } else {
        new = realloc((void *)dotlist, dotsize * 2 + 1);
        if (new == NULL) {
          goto lose;
        }
        dotp = &new[dotsize];
      }
      memcpy((char *)dotp, new, dotsize);
      dotsize *= 2;
      new[dotsize] = '\0';
      dotlist = new;
    }
    dotp -= 3;
    if (stat(dotp, &st) < 0) {
      goto lose;
    }
    dotdev = st.st_dev;
    dotino = st.st_ino;
    mount_point = dotdev != thisdev;
    dirstream = opendir(dotp);
    if (dirstream == NULL) {
      goto lose;
    }
    while ((d = readdir(dirstream)) != NULL) {
      if (d->d_name[0] == '.' &&
          (d->d_name[1] == '\0' ||
           (d->d_name[1] == '.' && d->d_name[2] == '\0'))) {
        continue;
      }
      if (mount_point || (ino_t)d->d_ino == thisino) {
        char name[dotlist + dotsize - dotp + 1 + _D_ALLOC_NAMLEN(d)];
        memcpy(name, dotp, dotlist + dotsize - dotp);
        name[dotlist + dotsize - dotp] = '/';
        strcpy(&name[dotlist + dotsize - dotp + 1], d->d_name);
        if (stat(name, &st) >= 0 && st.st_dev == thisdev &&
            st.st_ino == thisino) {
          break;
        }
      }
    }
    if (d == NULL) {
      (void)closedir(dirstream);
      goto lose;
    } else {
      size_t namlen = _D_EXACT_NAMLEN(d);
      if ((size_t)(pathp - path) <= namlen) {
        if (size != 0) {
          (void)closedir(dirstream);
          goto lose;
        } else {
          char *tmp;
          size_t oldsize = allocated;
          allocated = 2 * MAX(allocated, namlen);
          tmp = realloc(path, allocated);
          if (tmp == NULL) {
            (void)closedir(dirstream);
            goto lose;
          }
          pathp = memcpy(tmp + allocated - (path + oldsize - pathp),
                         tmp + (pathp - path), path + oldsize - pathp);
          path = tmp;
        }
      }
      pathp -= namlen;
      (void)memcpy(pathp, d->d_name, namlen);
      *--pathp = '/';
      (void)closedir(dirstream);
    }
    thisdev = dotdev;
    thisino = dotino;
  }
  if (pathp == &path[allocated - 1]) {
    *--pathp = '/';
  }
  if (dotlist != dots) {
    free((void *)dotlist);
  }
  memmove(path, pathp, path + allocated - pathp);
  return path;
lose:
  if (dotlist != dots) {
    free((void *)dotlist);
  }
lose2:
  if (buf == NULL) {
    free(path);
  }
  return NULL;
}


x86 assembly (clang, -O0):
<getcwd>:
push   %rbp
mov    %rsp,%rbp
sub    $0xf0,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
lea    0xe16(%rip),%rax
add    $0xf1,%rax
mov    %rax,-0x20(%rbp)
lea    0xe05(%rip),%rax
mov    %rax,-0x28(%rbp)
movq   $0xf0,-0x30(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x78(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    1244 <getcwd+0x74>
cmpq   $0x0,-0x10(%rbp)
je     1232 <getcwd+0x62>
movq   $0x0,-0x8(%rbp)
jmp    18a4 <getcwd+0x6d4>
mov    0x2db7(%rip),%rax
mov    (%rax),%eax
add    $0x1,%eax
cltq
mov    %rax,-0x78(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     125c <getcwd+0x8c>
mov    -0x10(%rbp),%rax
mov    %rax,-0x58(%rbp)
jmp    1286 <getcwd+0xb6>
mov    -0x78(%rbp),%rdi
call   10b0 <malloc@plt>
mov    %rax,-0x58(%rbp)
cmpq   $0x0,-0x58(%rbp)
jne    1281 <getcwd+0xb1>
movq   $0x0,-0x8(%rbp)
jmp    18a4 <getcwd+0x6d4>
jmp    1286 <getcwd+0xb6>
mov    -0x58(%rbp),%rax
add    -0x78(%rbp),%rax
mov    %rax,-0x60(%rbp)
mov    -0x60(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x60(%rbp)
movb   $0x0,-0x1(%rax)
lea    0xe45(%rip),%rdi
lea    -0x70(%rbp),%rsi
call   1080 <stat@plt>
cmp    $0x0,%rax
jge    12c4 <getcwd+0xf4>
jmp    1888 <getcwd+0x6b8>
mov    -0x70(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x68(%rbp),%rax
mov    %rax,-0x50(%rbp)
lea    0xe18(%rip),%rdi
lea    -0x70(%rbp),%rsi
call   1080 <stat@plt>
cmp    $0x0,%rax
jge    12f3 <getcwd+0x123>
jmp    1888 <getcwd+0x6b8>
mov    -0x70(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x68(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x40(%rbp),%rcx
xor    %eax,%eax
cmp    -0x38(%rbp),%rcx
mov    %al,-0xd9(%rbp)
jne    132a <getcwd+0x15a>
mov    -0x50(%rbp),%rax
cmp    -0x48(%rbp),%rax
sete   %al
mov    %al,-0xd9(%rbp)
mov    -0xd9(%rbp),%al
xor    $0xff,%al
test   $0x1,%al
jne    133f <getcwd+0x16f>
jmp    17f5 <getcwd+0x625>
mov    -0x20(%rbp),%rax
cmp    -0x28(%rbp),%rax
jne    142c <getcwd+0x25c>
lea    0xcac(%rip),%rax
cmp    %rax,-0x28(%rbp)
jne    13b4 <getcwd+0x1e4>
mov    -0x30(%rbp),%rdi
shl    $0x1,%rdi
add    $0x1,%rdi
call   10b0 <malloc@plt>
mov    %rax,-0xa8(%rbp)
cmpq   $0x0,-0xa8(%rbp)
jne    1389 <getcwd+0x1b9>
jmp    1869 <getcwd+0x699>
mov    -0xa8(%rbp),%rdi
mov    -0x30(%rbp),%rdx
lea    0xc65(%rip),%rsi
call   1090 <memcpy@plt>
mov    -0xa8(%rbp),%rax
add    -0x30(%rbp),%rax
mov    %rax,-0x20(%rbp)
jmp    13f2 <getcwd+0x222>
mov    -0x28(%rbp),%rdi
mov    -0x30(%rbp),%rsi
shl    $0x1,%rsi
add    $0x1,%rsi
call   10d0 <realloc@plt>
mov    %rax,-0xa8(%rbp)
cmpq   $0x0,-0xa8(%rbp)
jne    13e3 <getcwd+0x213>
jmp    1869 <getcwd+0x699>
mov    -0xa8(%rbp),%rax
add    -0x30(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rdi
mov    -0xa8(%rbp),%rsi
mov    -0x30(%rbp),%rdx
call   1090 <memcpy@plt>
mov    -0x30(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0xa8(%rbp),%rax
mov    -0x30(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0xa8(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
add    $0xfffffffffffffffd,%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rdi
lea    -0x70(%rbp),%rsi
call   1080 <stat@plt>
cmp    $0x0,%rax
jge    1454 <getcwd+0x284>
jmp    1869 <getcwd+0x699>
mov    -0x70(%rbp),%rax
mov    %rax,-0x90(%rbp)
mov    -0x68(%rbp),%rax
mov    %rax,-0x98(%rbp)
mov    -0x90(%rbp),%rax
cmp    -0x40(%rbp),%rax
setne  %al
and    $0x1,%al
movzbl %al,%eax
mov    %al,-0x99(%rbp)
mov    -0x20(%rbp),%rdi
call   1060 <opendir@plt>
mov    %rax,-0x80(%rbp)
cmpq   $0x0,-0x80(%rbp)
jne    14a0 <getcwd+0x2d0>
jmp    1869 <getcwd+0x699>
jmp    14a5 <getcwd+0x2d5>
mov    -0x80(%rbp),%rdi
call   10a0 <readdir@plt>
mov    %rax,-0x88(%rbp)
cmp    $0x0,%rax
je     1674 <getcwd+0x4a4>
mov    -0x88(%rbp),%rax
mov    (%rax),%rax
movsbl (%rax),%eax
cmp    $0x2e,%eax
jne    151f <getcwd+0x34f>
mov    -0x88(%rbp),%rax
mov    (%rax),%rax
movsbl 0x1(%rax),%eax
cmp    $0x0,%eax
je     151a <getcwd+0x34a>
mov    -0x88(%rbp),%rax
mov    (%rax),%rax
movsbl 0x1(%rax),%eax
cmp    $0x2e,%eax
jne    151f <getcwd+0x34f>
mov    -0x88(%rbp),%rax
mov    (%rax),%rax
movsbl 0x2(%rax),%eax
cmp    $0x0,%eax
jne    151f <getcwd+0x34f>
jmp    14a5 <getcwd+0x2d5>
movsbl -0x99(%rbp),%eax
cmp    $0x0,%eax
jne    1544 <getcwd+0x374>
mov    -0x88(%rbp),%rax
mov    0x8(%rax),%rax
cmp    -0x50(%rbp),%rax
jne    166f <getcwd+0x49f>
mov    -0x28(%rbp),%rax
mov    -0x30(%rbp),%rcx
add    %rcx,%rax
mov    -0x20(%rbp),%rcx
sub    %rcx,%rax
mov    %rax,-0xf0(%rbp)
mov    -0x88(%rbp),%rdi
call   10c0 <_D_ALLOC_NAMLEN@plt>
mov    -0xf0(%rbp),%rcx
movslq %eax,%rdx
lea    0x1(%rcx,%rdx,1),%rax
mov    %rsp,%rsi
mov    %rsi,-0xb0(%rbp)
lea    0x10(%rcx,%rdx,1),%rcx
and    $0xfffffffffffffff0,%rcx
mov    %rsp,%rdi
sub    %rcx,%rdi
mov    %rdi,-0xe8(%rbp)
mov    %rdi,%rsp
mov    %rax,-0xb8(%rbp)
mov    -0x20(%rbp),%rsi
mov    -0x28(%rbp),%rdx
add    -0x30(%rbp),%rdx
mov    -0x20(%rbp),%rax
sub    %rax,%rdx
call   1090 <memcpy@plt>
mov    -0xe8(%rbp),%rdi
mov    -0x28(%rbp),%rax
add    -0x30(%rbp),%rax
mov    -0x20(%rbp),%rcx
sub    %rcx,%rax
movb   $0x2f,(%rdi,%rax,1)
mov    -0x28(%rbp),%rax
add    -0x30(%rbp),%rax
mov    -0x20(%rbp),%rcx
sub    %rcx,%rax
add    $0x1,%rax
add    %rax,%rdi
mov    -0x88(%rbp),%rax
mov    (%rax),%rsi
call   1040 <strcpy@plt>
mov    -0xe8(%rbp),%rdi
lea    -0x70(%rbp),%rsi
call   1080 <stat@plt>
cmp    $0x0,%rax
jl     163e <getcwd+0x46e>
mov    -0x70(%rbp),%rax
cmp    -0x40(%rbp),%rax
jne    163e <getcwd+0x46e>
mov    -0x68(%rbp),%rax
cmp    -0x50(%rbp),%rax
jne    163e <getcwd+0x46e>
movl   $0x7,-0xbc(%rbp)
jmp    1648 <getcwd+0x478>
movl   $0x0,-0xbc(%rbp)
mov    -0xb0(%rbp),%rax
mov    %rax,%rsp
mov    -0xbc(%rbp),%eax
test   %eax,%eax
je     166a <getcwd+0x49a>
jmp    1665 <getcwd+0x495>
jmp    1674 <getcwd+0x4a4>
jmp    166f <getcwd+0x49f>
jmp    14a5 <getcwd+0x2d5>
cmpq   $0x0,-0x88(%rbp)
jne    1690 <getcwd+0x4c0>
mov    -0x80(%rbp),%rdi
call   1070 <closedir@plt>
jmp    1869 <getcwd+0x699>
mov    -0x88(%rbp),%rdi
call   10f0 <_D_EXACT_NAMLEN@plt>
mov    %rax,-0xc8(%rbp)
mov    -0x60(%rbp),%rax
mov    -0x58(%rbp),%rcx
sub    %rcx,%rax
cmp    -0xc8(%rbp),%rax
ja     178d <getcwd+0x5bd>
cmpq   $0x0,-0x18(%rbp)
je     16d4 <getcwd+0x504>
mov    -0x80(%rbp),%rdi
call   1070 <closedir@plt>
jmp    1869 <getcwd+0x699>
mov    -0x78(%rbp),%rax
mov    %rax,-0xd8(%rbp)
mov    -0x78(%rbp),%rdi
mov    -0xc8(%rbp),%rsi
call   1050 <MAX@plt>
shl    $0x1,%eax
cltq
mov    %rax,-0x78(%rbp)
mov    -0x58(%rbp),%rdi
mov    -0x78(%rbp),%rsi
call   10d0 <realloc@plt>
mov    %rax,-0xd0(%rbp)
cmpq   $0x0,-0xd0(%rbp)
jne    1728 <getcwd+0x558>
mov    -0x80(%rbp),%rdi
call   1070 <closedir@plt>
jmp    1869 <getcwd+0x699>
mov    -0xd0(%rbp),%rdi
add    -0x78(%rbp),%rdi
mov    -0x58(%rbp),%rcx
add    -0xd8(%rbp),%rcx
mov    -0x60(%rbp),%rax
sub    %rax,%rcx
xor    %eax,%eax
sub    %rcx,%rax
add    %rax,%rdi
mov    -0xd0(%rbp),%rsi
mov    -0x60(%rbp),%rax
mov    -0x58(%rbp),%rcx
sub    %rcx,%rax
add    %rax,%rsi
mov    -0x58(%rbp),%rdx
add    -0xd8(%rbp),%rdx
mov    -0x60(%rbp),%rax
sub    %rax,%rdx
call   1090 <memcpy@plt>
mov    %rax,-0x60(%rbp)
mov    -0xd0(%rbp),%rax
mov    %rax,-0x58(%rbp)
jmp    178d <getcwd+0x5bd>
mov    -0xc8(%rbp),%rdx
mov    -0x60(%rbp),%rax
xor    %ecx,%ecx
sub    %rdx,%rcx
add    %rcx,%rax
mov    %rax,-0x60(%rbp)
mov    -0x60(%rbp),%rdi
mov    -0x88(%rbp),%rax
mov    (%rax),%rsi
mov    -0xc8(%rbp),%rdx
call   1090 <memcpy@plt>
mov    -0x60(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x60(%rbp)
movb   $0x2f,-0x1(%rax)
mov    -0x80(%rbp),%rdi
call   1070 <closedir@plt>
mov    -0x90(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x98(%rbp),%rax
mov    %rax,-0x50(%rbp)
jmp    1303 <getcwd+0x133>
mov    -0x60(%rbp),%rax
mov    -0x58(%rbp),%rcx
mov    -0x78(%rbp),%rdx
sub    $0x1,%rdx
add    %rdx,%rcx
cmp    %rcx,%rax
jne    1824 <getcwd+0x654>
mov    -0x60(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x60(%rbp)
movb   $0x2f,-0x1(%rax)
lea    0x7d5(%rip),%rax
cmp    %rax,-0x28(%rbp)
je     183e <getcwd+0x66e>
mov    -0x28(%rbp),%rdi
call   1030 <free@plt>
mov    -0x58(%rbp),%rdi
mov    -0x60(%rbp),%rsi
mov    -0x58(%rbp),%rax
add    -0x78(%rbp),%rax
mov    -0x60(%rbp),%rcx
sub    %rcx,%rax
mov    %eax,%edx
call   10e0 <memmove@plt>
mov    -0x58(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    18a4 <getcwd+0x6d4>
lea    0x790(%rip),%rax
cmp    %rax,-0x28(%rbp)
je     1883 <getcwd+0x6b3>
mov    -0x28(%rbp),%rdi
call   1030 <free@plt>
jmp    1888 <getcwd+0x6b8>
cmpq   $0x0,-0x10(%rbp)
jne    189c <getcwd+0x6cc>
mov    -0x58(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<getcwd>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x88,%rsp
mov    %rsi,%r15
mov    %rdi,%rbx
test   %rsi,%rsi
je     11ff <getcwd+0x2f>
mov    %r15,%r14
test   %rbx,%rbx
je     1216 <getcwd+0x46>
xor    %r13d,%r13d
mov    %r15,%r14
jmp    122d <getcwd+0x5d>
test   %rbx,%rbx
jne    161e <getcwd+0x44e>
mov    0x2de1(%rip),%rax
movslq (%rax),%r14
add    $0x1,%r14
mov    %r14,%rdi
call   10b0 <malloc@plt>
test   %rax,%rax
je     161e <getcwd+0x44e>
mov    %rax,%rbx
mov    $0x1,%r13b
movb   $0x0,-0x1(%rbx,%r14,1)
lea    0xeb7(%rip),%rdi
lea    -0x70(%rbp),%rsi
call   1080 <stat@plt>
test   %rax,%rax
js     1611 <getcwd+0x441>
mov    -0x70(%rbp),%r12
mov    -0x68(%rbp),%rax
mov    %rax,-0x40(%rbp)
lea    0xe94(%rip),%rdi
lea    -0x70(%rbp),%rsi
call   1080 <stat@plt>
test   %rax,%rax
js     1611 <getcwd+0x441>
mov    %r13d,-0x44(%rbp)
lea    (%rbx,%r14,1),%r13
add    $0xffffffffffffffff,%r13
mov    -0x70(%rbp),%rax
mov    -0x68(%rbp),%rcx
cmp    %rax,%r12
jne    12d7 <getcwd+0x107>
cmp    %rcx,-0x40(%rbp)
jne    12d7 <getcwd+0x107>
lea    0xd69(%rip),%rdi
lea    (%r14,%rbx,1),%rax
add    $0xffffffffffffffff,%rax
cmp    %rax,%r13
jne    12ad <getcwd+0xdd>
movb   $0x2f,-0x1(%r13)
add    $0xffffffffffffffff,%r13
lea    0xd4c(%rip),%rax
cmp    %rax,%rdi
je     12be <getcwd+0xee>
call   1030 <free@plt>
add    %ebx,%r14d
sub    %r13d,%r14d
mov    %rbx,%rdi
mov    %r13,%rsi
mov    %r14d,%edx
call   10e0 <memmove@plt>
jmp    1620 <getcwd+0x450>
mov    %r12,-0x38(%rbp)
mov    %rcx,-0x90(%rbp)
mov    $0xf0,%r12d
lea    0xd11(%rip),%rdi
lea    0xdfb(%rip),%rdx
mov    %r15,-0x98(%rbp)
mov    %rax,-0xa0(%rbp)
cmp    %rdi,%rdx
mov    %rbx,-0x50(%rbp)
mov    %r13,-0xb0(%rbp)
je     1321 <getcwd+0x151>
mov    %r12,-0x80(%rbp)
mov    %rdi,-0x30(%rbp)
jmp    13ac <getcwd+0x1dc>
lea    (%r12,%r12,1),%rsi
add    $0x1,%rsi
lea    0xcd0(%rip),%rcx
cmp    %rcx,%rdx
je     134f <getcwd+0x17f>
mov    %rdx,%rdi
mov    %rdx,-0x58(%rbp)
call   10d0 <realloc@plt>
mov    -0x58(%rbp),%rdi
test   %rax,%rax
jne    137b <getcwd+0x1ab>
jmp    1608 <getcwd+0x438>
mov    %rsi,%rdi
call   10b0 <malloc@plt>
test   %rax,%rax
je     160d <getcwd+0x43d>
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rdi
lea    0xc91(%rip),%rsi
mov    %r12,%rdx
call   1090 <memcpy@plt>
mov    -0x30(%rbp),%rax
lea    (%r12,%r12,1),%rcx
mov    %rcx,-0x60(%rbp)
lea    (%rax,%r12,1),%r13
mov    %rax,%rbx
mov    %r13,%rdi
mov    %rax,%rsi
mov    %r12,%rdx
call   1090 <memcpy@plt>
mov    %r13,%rdx
mov    %rbx,-0x30(%rbp)
movb   $0x0,(%rbx,%r12,2)
mov    -0x60(%rbp),%r13
mov    %r13,-0x80(%rbp)
mov    -0x38(%rbp),%rbx
add    $0xfffffffffffffffd,%rdx
mov    %rdx,%rdi
lea    -0x70(%rbp),%rsi
mov    %rdx,%r12
call   1080 <stat@plt>
test   %rax,%rax
js     15f1 <getcwd+0x421>
mov    -0x70(%rbp),%rax
mov    %rax,-0x88(%rbp)
mov    -0x68(%rbp),%rax
mov    %rax,-0xa8(%rbp)
mov    %r12,%rdi
call   1060 <opendir@plt>
test   %rax,%rax
je     15f1 <getcwd+0x421>
mov    %r12,-0x58(%rbp)
mov    %r14,-0x78(%rbp)
mov    %rax,-0x60(%rbp)
mov    %rax,%rdi
call   10a0 <readdir@plt>
test   %rax,%rax
mov    -0x88(%rbp),%r12
je     15e8 <getcwd+0x418>
mov    %rax,%r15
mov    -0x30(%rbp),%rax
mov    -0x80(%rbp),%rcx
lea    (%rax,%rcx,1),%r14
sub    -0x58(%rbp),%r14
lea    0x1(%r14),%r13
jmp    1445 <getcwd+0x275>
mov    -0x60(%rbp),%rdi
call   10a0 <readdir@plt>
mov    %rax,%r15
test   %rax,%rax
je     15e8 <getcwd+0x418>
mov    (%r15),%rax
cmpb   $0x2e,(%rax)
jne    1460 <getcwd+0x290>
movzbl 0x1(%rax),%ecx
test   %cl,%cl
je     1430 <getcwd+0x260>
cmp    $0x2e,%cl
jne    1460 <getcwd+0x290>
cmpb   $0x0,0x2(%rax)
je     1430 <getcwd+0x260>
cmp    %rbx,%r12
jne    146f <getcwd+0x29f>
mov    -0x40(%rbp),%rax
cmp    %rax,0x8(%r15)
jne    1430 <getcwd+0x260>
mov    %r15,%rdi
call   10c0 <_D_ALLOC_NAMLEN@plt>
mov    %rsp,%r12
cltq
add    %r13,%rax
add    $0xf,%rax
and    $0xfffffffffffffff0,%rax
mov    %rsp,%rbx
sub    %rax,%rbx
mov    %rbx,%rsp
mov    %rbx,%rdi
mov    -0x58(%rbp),%rsi
mov    %r14,%rdx
call   1090 <memcpy@plt>
movb   $0x2f,(%r14,%rbx,1)
lea    (%rbx,%r13,1),%rdi
mov    (%r15),%rsi
call   1040 <strcpy@plt>
mov    %rbx,%rdi
lea    -0x70(%rbp),%rsi
call   1080 <stat@plt>
test   %rax,%rax
mov    %r12,%rsp
mov    -0x88(%rbp),%r12
mov    -0x38(%rbp),%rbx
js     1430 <getcwd+0x260>
cmp    %rbx,-0x70(%rbp)
jne    1430 <getcwd+0x260>
mov    -0x40(%rbp),%rax
cmp    %rax,-0x68(%rbp)
jne    1430 <getcwd+0x260>
mov    %r15,%rdi
call   10f0 <_D_EXACT_NAMLEN@plt>
mov    -0xb0(%rbp),%r13
mov    %r13,%r14
mov    -0x50(%rbp),%rbx
sub    %rbx,%r14
cmp    %rax,%r14
jbe    150f <getcwd+0x33f>
mov    -0x78(%rbp),%r14
jmp    157d <getcwd+0x3ad>
cmpq   $0x0,-0x98(%rbp)
jne    15e8 <getcwd+0x418>
mov    -0x78(%rbp),%rdi
mov    %rax,%rsi
mov    %rax,-0x40(%rbp)
call   1050 <MAX@plt>
add    %eax,%eax
movslq %eax,%rbx
mov    -0x50(%rbp),%rdi
mov    %rbx,%rsi
call   10d0 <realloc@plt>
test   %rax,%rax
je     15e8 <getcwd+0x418>
mov    %rbx,-0x38(%rbp)
add    %rax,%rbx
mov    -0x50(%rbp),%rdx
add    -0x78(%rbp),%rdx
sub    %r13,%rdx
sub    %rdx,%rbx
add    %rax,%r14
mov    %rbx,%rdi
mov    %r14,%rsi
mov    %rax,-0x50(%rbp)
call   1090 <memcpy@plt>
mov    -0x40(%rbp),%rax
mov    -0x38(%rbp),%r14
mov    %rbx,%r13
mov    -0x50(%rbp),%rbx
sub    %rax,%r13
mov    (%r15),%rsi
mov    %r13,%rdi
mov    %rax,%rdx
call   1090 <memcpy@plt>
movb   $0x2f,-0x1(%r13)
add    $0xffffffffffffffff,%r13
mov    -0x60(%rbp),%rdi
call   1070 <closedir@plt>
mov    %r12,-0x38(%rbp)
mov    -0xa8(%rbp),%rcx
mov    %rcx,-0x40(%rbp)
mov    -0xa0(%rbp),%rax
cmp    %rax,%r12
mov    -0x30(%rbp),%rdi
mov    %r12,%rsi
mov    -0x80(%rbp),%r12
mov    -0x58(%rbp),%rdx
jne    1304 <getcwd+0x134>
mov    %rsi,-0x38(%rbp)
mov    %rcx,-0x40(%rbp)
cmp    -0x90(%rbp),%rcx
jne    1304 <getcwd+0x134>
jmp    1297 <getcwd+0xc7>
mov    -0x60(%rbp),%rdi
call   1070 <closedir@plt>
lea    0xa08(%rip),%rax
mov    -0x30(%rbp),%rcx
mov    %rcx,%rdi
cmp    %rax,%rcx
mov    -0x50(%rbp),%rbx
je     160d <getcwd+0x43d>
call   1030 <free@plt>
mov    -0x44(%rbp),%r13d
test   %r13b,%r13b
je     161e <getcwd+0x44e>
mov    %rbx,%rdi
call   1030 <free@plt>
xor    %ebx,%ebx
mov    %rbx,%rax
lea    -0x28(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.stat = type { i64, i64 }
%struct.dirent = type { i8*, i64 }
@getcwd.dots = internal constant [241 x i8] c"../../../../../../../../../../../../../../../../../../../../../../../ ../../../../../../../../../../../../../../../../../../../../../../../../../../ ../../../../../../../../../../../../../../../../../../../../../../../../../..\00"
@PATH_MAX = global i32 0
@.str = [2 x i8] c".\00"
@.str.1 = [2 x i8] c"/\00"
define i8* @getcwd(i8* %0, i64 %1) {
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i64
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i64
%9 = alloca i64
%10 = alloca i64
%11 = alloca i64
%12 = alloca i64
%13 = alloca i8*
%14 = alloca i8*
%15 = alloca %struct.stat
%16 = alloca i64
%17 = alloca i32*
%18 = alloca %struct.dirent*
%19 = alloca i64
%20 = alloca i64
%21 = alloca i8
%22 = alloca i8*
%23 = alloca i8*
%24 = alloca i64
%25 = alloca i32
%26 = alloca i64
%27 = alloca i8*
%28 = alloca i64
store i8* %0, i8** %4
store i64 %1, i64* %5
store i8* getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 1, i64 0), i8** %6
store i8* getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 0, i64 0), i8** %7
store i64 240, i64* %8
%29 = load i64, i64* %5
store i64 %29, i64* %16
%30 = load i64, i64* %5
%31 = icmp eq i64 %30, 0
br i1 %31, label %32, label %40
32: ; preds = %2
%33 = load i8*, i8** %4
%34 = icmp ne i8* %33, null
br i1 %34, label %35, label %36
35: ; preds = %32
store i8* null, i8** %3
br label %393
36: ; preds = %32
%37 = load i32, i32* @PATH_MAX
%38 = add nsw i32 %37, 1
%39 = sext i32 %38 to i64
store i64 %39, i64* %16
br label %40
40: ; preds = %36, %2
%41 = load i8*, i8** %4
%42 = icmp ne i8* %41, null
br i1 %42, label %43, label %45
43: ; preds = %40
%44 = load i8*, i8** %4
store i8* %44, i8** %13
br label %52
45: ; preds = %40
%46 = load i64, i64* %16
%47 = call i8* @malloc(i64 %46)
store i8* %47, i8** %13
%48 = load i8*, i8** %13
%49 = icmp eq i8* %48, null
br i1 %49, label %50, label %51
50: ; preds = %45
store i8* null, i8** %3
br label %393
51: ; preds = %45
br label %52
52: ; preds = %51, %43
%53 = load i8*, i8** %13
%54 = load i64, i64* %16
%55 = getelementptr inbounds i8, i8* %53, i64 %54
store i8* %55, i8** %14
%56 = load i8*, i8** %14
%57 = getelementptr inbounds i8, i8* %56, i32 -1
store i8* %57, i8** %14
store i8 0, i8* %57
%58 = call i64 @stat(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), %struct.stat* %15)
%59 = icmp slt i64 %58, 0
br i1 %59, label %60, label %61
60: ; preds = %52
br label %386
61: ; preds = %52
%62 = getelementptr inbounds %struct.stat, %struct.stat* %15, i32 0, i32 0
%63 = load i64, i64* %62
store i64 %63, i64* %10
%64 = getelementptr inbounds %struct.stat, %struct.stat* %15, i32 0, i32 1
%65 = load i64, i64* %64
store i64 %65, i64* %12
%66 = call i64 @stat(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), %struct.stat* %15)
%67 = icmp slt i64 %66, 0
br i1 %67, label %68, label %69
68: ; preds = %61
br label %386
69: ; preds = %61
%70 = getelementptr inbounds %struct.stat, %struct.stat* %15, i32 0, i32 0
%71 = load i64, i64* %70
store i64 %71, i64* %9
%72 = getelementptr inbounds %struct.stat, %struct.stat* %15, i32 0, i32 1
%73 = load i64, i64* %72
store i64 %73, i64* %11
br label %74
74: ; preds = %347, %69
%75 = load i64, i64* %10
%76 = load i64, i64* %9
%77 = icmp eq i64 %75, %76
br i1 %77, label %78, label %82
78: ; preds = %74
%79 = load i64, i64* %12
%80 = load i64, i64* %11
%81 = icmp eq i64 %79, %80
br label %82
82: ; preds = %78, %74
%83 = phi i1 [ false, %74 ], [ %81, %78 ]
%84 = xor i1 %83, true
br i1 %84, label %85, label %350
85: ; preds = %82
%86 = load i8*, i8** %6
%87 = load i8*, i8** %7
%88 = icmp eq i8* %86, %87
br i1 %88, label %89, label %131
89: ; preds = %85
%90 = load i8*, i8** %7
%91 = icmp eq i8* %90, getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 0, i64 0)
br i1 %91, label %92, label %107
92: ; preds = %89
%93 = load i64, i64* %8
%94 = mul i64 %93, 2
%95 = add i64 %94, 1
%96 = call i8* @malloc(i64 %95)
store i8* %96, i8** %22
%97 = load i8*, i8** %22
%98 = icmp eq i8* %97, null
br i1 %98, label %99, label %100
99: ; preds = %92
br label %379
100: ; preds = %92
%101 = load i8*, i8** %22
%102 = load i64, i64* %8
%103 = call i8* @memcpy(i8* %101, i8* getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 0, i64 0), i64 %102)
%104 = load i8*, i8** %22
%105 = load i64, i64* %8
%106 = getelementptr inbounds i8, i8* %104, i64 %105
store i8* %106, i8** %6
br label %120
107: ; preds = %89
%108 = load i8*, i8** %7
%109 = load i64, i64* %8
%110 = mul i64 %109, 2
%111 = add i64 %110, 1
%112 = call i8* @realloc(i8* %108, i64 %111)
store i8* %112, i8** %22
%113 = load i8*, i8** %22
%114 = icmp eq i8* %113, null
br i1 %114, label %115, label %116
115: ; preds = %107
br label %379
116: ; preds = %107
%117 = load i8*, i8** %22
%118 = load i64, i64* %8
%119 = getelementptr inbounds i8, i8* %117, i64 %118
store i8* %119, i8** %6
br label %120
120: ; preds = %116, %100
%121 = load i8*, i8** %6
%122 = load i8*, i8** %22
%123 = load i64, i64* %8
%124 = call i8* @memcpy(i8* %121, i8* %122, i64 %123)
%125 = load i64, i64* %8
%126 = mul i64 %125, 2
store i64 %126, i64* %8
%127 = load i8*, i8** %22
%128 = load i64, i64* %8
%129 = getelementptr inbounds i8, i8* %127, i64 %128
store i8 0, i8* %129
%130 = load i8*, i8** %22
store i8* %130, i8** %7
br label %131
131: ; preds = %120, %85
%132 = load i8*, i8** %6
%133 = getelementptr inbounds i8, i8* %132, i64 -3
store i8* %133, i8** %6
%134 = load i8*, i8** %6
%135 = call i64 @stat(i8* %134, %struct.stat* %15)
%136 = icmp slt i64 %135, 0
br i1 %136, label %137, label %138
137: ; preds = %131
br label %379
138: ; preds = %131
%139 = getelementptr inbounds %struct.stat, %struct.stat* %15, i32 0, i32 0
%140 = load i64, i64* %139
store i64 %140, i64* %19
%141 = getelementptr inbounds %struct.stat, %struct.stat* %15, i32 0, i32 1
%142 = load i64, i64* %141
store i64 %142, i64* %20
%143 = load i64, i64* %19
%144 = load i64, i64* %10
%145 = icmp ne i64 %143, %144
%146 = zext i1 %145 to i32
%147 = trunc i32 %146 to i8
store i8 %147, i8* %21
%148 = load i8*, i8** %6
%149 = call i32* @opendir(i8* %148)
store i32* %149, i32** %17
%150 = load i32*, i32** %17
%151 = icmp eq i32* %150, null
br i1 %151, label %152, label %153
152: ; preds = %138
br label %379
153: ; preds = %138
br label %154
154: ; preds = %264, %190, %153
%155 = load i32*, i32** %17
%156 = call %struct.dirent* @readdir(i32* %155)
store %struct.dirent* %156, %struct.dirent** %18
%157 = icmp ne %struct.dirent* %156, null
br i1 %157, label %158, label %265
158: ; preds = %154
%159 = load %struct.dirent*, %struct.dirent** %18
%160 = getelementptr inbounds %struct.dirent, %struct.dirent* %159, i32 0, i32 0
%161 = load i8*, i8** %160
%162 = getelementptr inbounds i8, i8* %161, i64 0
%163 = load i8, i8* %162
%164 = sext i8 %163 to i32
%165 = icmp eq i32 %164, 46
br i1 %165, label %166, label %191
166: ; preds = %158
%167 = load %struct.dirent*, %struct.dirent** %18
%168 = getelementptr inbounds %struct.dirent, %struct.dirent* %167, i32 0, i32 0
%169 = load i8*, i8** %168
%170 = getelementptr inbounds i8, i8* %169, i64 1
%171 = load i8, i8* %170
%172 = sext i8 %171 to i32
%173 = icmp eq i32 %172, 0
br i1 %173, label %190, label %174
174: ; preds = %166
%175 = load %struct.dirent*, %struct.dirent** %18
%176 = getelementptr inbounds %struct.dirent, %struct.dirent* %175, i32 0, i32 0
%177 = load i8*, i8** %176
%178 = getelementptr inbounds i8, i8* %177, i64 1
%179 = load i8, i8* %178
%180 = sext i8 %179 to i32
%181 = icmp eq i32 %180, 46
br i1 %181, label %182, label %191
182: ; preds = %174
%183 = load %struct.dirent*, %struct.dirent** %18
%184 = getelementptr inbounds %struct.dirent, %struct.dirent* %183, i32 0, i32 0
%185 = load i8*, i8** %184
%186 = getelementptr inbounds i8, i8* %185, i64 2
%187 = load i8, i8* %186
%188 = sext i8 %187 to i32
%189 = icmp eq i32 %188, 0
br i1 %189, label %190, label %191
190: ; preds = %182, %166
br label %154
191: ; preds = %182, %174, %158
%192 = load i8, i8* %21
%193 = sext i8 %192 to i32
%194 = icmp ne i32 %193, 0
br i1 %194, label %201, label %195
195: ; preds = %191
%196 = load %struct.dirent*, %struct.dirent** %18
%197 = getelementptr inbounds %struct.dirent, %struct.dirent* %196, i32 0, i32 1
%198 = load i64, i64* %197
%199 = load i64, i64* %12
%200 = icmp eq i64 %198, %199
br i1 %200, label %201, label %264
201: ; preds = %195, %191
%202 = load i8*, i8** %7
%203 = load i64, i64* %8
%204 = getelementptr inbounds i8, i8* %202, i64 %203
%205 = load i8*, i8** %6
%206 = ptrtoint i8* %204 to i64
%207 = ptrtoint i8* %205 to i64
%208 = sub i64 %206, %207
%209 = add nsw i64 %208, 1
%210 = load %struct.dirent*, %struct.dirent** %18
%211 = call i32 @_D_ALLOC_NAMLEN(%struct.dirent* %210)
%212 = sext i32 %211 to i64
%213 = add nsw i64 %209, %212
%214 = call i8* @llvm.stacksave()
store i8* %214, i8** %23
%215 = alloca i8, i64 %213
store i64 %213, i64* %24
%216 = load i8*, i8** %6
%217 = load i8*, i8** %7
%218 = load i64, i64* %8
%219 = getelementptr inbounds i8, i8* %217, i64 %218
%220 = load i8*, i8** %6
%221 = ptrtoint i8* %219 to i64
%222 = ptrtoint i8* %220 to i64
%223 = sub i64 %221, %222
%224 = call i8* @memcpy(i8* %215, i8* %216, i64 %223)
%225 = load i8*, i8** %7
%226 = load i64, i64* %8
%227 = getelementptr inbounds i8, i8* %225, i64 %226
%228 = load i8*, i8** %6
%229 = ptrtoint i8* %227 to i64
%230 = ptrtoint i8* %228 to i64
%231 = sub i64 %229, %230
%232 = getelementptr inbounds i8, i8* %215, i64 %231
store i8 47, i8* %232
%233 = load i8*, i8** %7
%234 = load i64, i64* %8
%235 = getelementptr inbounds i8, i8* %233, i64 %234
%236 = load i8*, i8** %6
%237 = ptrtoint i8* %235 to i64
%238 = ptrtoint i8* %236 to i64
%239 = sub i64 %237, %238
%240 = add nsw i64 %239, 1
%241 = getelementptr inbounds i8, i8* %215, i64 %240
%242 = load %struct.dirent*, %struct.dirent** %18
%243 = getelementptr inbounds %struct.dirent, %struct.dirent* %242, i32 0, i32 0
%244 = load i8*, i8** %243
%245 = call i32 @strcpy(i8* %241, i8* %244)
%246 = call i64 @stat(i8* %215, %struct.stat* %15)
%247 = icmp sge i64 %246, 0
br i1 %247, label %248, label %259
248: ; preds = %201
%249 = getelementptr inbounds %struct.stat, %struct.stat* %15, i32 0, i32 0
%250 = load i64, i64* %249
%251 = load i64, i64* %10
%252 = icmp eq i64 %250, %251
br i1 %252, label %253, label %259
253: ; preds = %248
%254 = getelementptr inbounds %struct.stat, %struct.stat* %15, i32 0, i32 1
%255 = load i64, i64* %254
%256 = load i64, i64* %12
%257 = icmp eq i64 %255, %256
br i1 %257, label %258, label %259
258: ; preds = %253
store i32 7, i32* %25
br label %260
259: ; preds = %253, %248, %201
store i32 0, i32* %25
br label %260
260: ; preds = %259, %258
%261 = load i8*, i8** %23
%262 = load i32, i32* %25
switch i32 %262, label %395 [
i32 0, label %263
i32 7, label %265
]
263: ; preds = %260
br label %264
264: ; preds = %263, %195
br label %154
265: ; preds = %260, %154
%266 = load %struct.dirent*, %struct.dirent** %18
%267 = icmp eq %struct.dirent* %266, null
br i1 %267, label %268, label %271
268: ; preds = %265
%269 = load i32*, i32** %17
%270 = call i32 @closedir(i32* %269)
br label %379
271: ; preds = %265
%272 = load %struct.dirent*, %struct.dirent** %18
%273 = call i64 @_D_EXACT_NAMLEN(%struct.dirent* %272)
store i64 %273, i64* %26
%274 = load i8*, i8** %14
%275 = load i8*, i8** %13
%276 = ptrtoint i8* %274 to i64
%277 = ptrtoint i8* %275 to i64
%278 = sub i64 %276, %277
%279 = load i64, i64* %26
%280 = icmp ule i64 %278, %279
br i1 %280, label %281, label %332
281: ; preds = %271
%282 = load i64, i64* %5
%283 = icmp ne i64 %282, 0
br i1 %283, label %284, label %287
284: ; preds = %281
%285 = load i32*, i32** %17
%286 = call i32 @closedir(i32* %285)
br label %379
287: ; preds = %281
%288 = load i64, i64* %16
store i64 %288, i64* %28
%289 = load i64, i64* %16
%290 = load i64, i64* %26
%291 = call i32 @MAX(i64 %289, i64 %290)
%292 = mul nsw i32 2, %291
%293 = sext i32 %292 to i64
store i64 %293, i64* %16
%294 = load i8*, i8** %13
%295 = load i64, i64* %16
%296 = call i8* @realloc(i8* %294, i64 %295)
store i8* %296, i8** %27
%297 = load i8*, i8** %27
%298 = icmp eq i8* %297, null
br i1 %298, label %299, label %302
299: ; preds = %287
%300 = load i32*, i32** %17
%301 = call i32 @closedir(i32* %300)
br label %379
302: ; preds = %287
%303 = load i8*, i8** %27
%304 = load i64, i64* %16
%305 = getelementptr inbounds i8, i8* %303, i64 %304
%306 = load i8*, i8** %13
%307 = load i64, i64* %28
%308 = getelementptr inbounds i8, i8* %306, i64 %307
%309 = load i8*, i8** %14
%310 = ptrtoint i8* %308 to i64
%311 = ptrtoint i8* %309 to i64
%312 = sub i64 %310, %311
%313 = sub i64 0, %312
%314 = getelementptr inbounds i8, i8* %305, i64 %313
%315 = load i8*, i8** %27
%316 = load i8*, i8** %14
%317 = load i8*, i8** %13
%318 = ptrtoint i8* %316 to i64
%319 = ptrtoint i8* %317 to i64
%320 = sub i64 %318, %319
%321 = getelementptr inbounds i8, i8* %315, i64 %320
%322 = load i8*, i8** %13
%323 = load i64, i64* %28
%324 = getelementptr inbounds i8, i8* %322, i64 %323
%325 = load i8*, i8** %14
%326 = ptrtoint i8* %324 to i64
%327 = ptrtoint i8* %325 to i64
%328 = sub i64 %326, %327
%329 = call i8* @memcpy(i8* %314, i8* %321, i64 %328)
store i8* %329, i8** %14
%330 = load i8*, i8** %27
store i8* %330, i8** %13
br label %331
331: ; preds = %302
br label %332
332: ; preds = %331, %271
%333 = load i64, i64* %26
%334 = load i8*, i8** %14
%335 = sub i64 0, %333
%336 = getelementptr inbounds i8, i8* %334, i64 %335
store i8* %336, i8** %14
%337 = load i8*, i8** %14
%338 = load %struct.dirent*, %struct.dirent** %18
%339 = getelementptr inbounds %struct.dirent, %struct.dirent* %338, i32 0, i32 0
%340 = load i8*, i8** %339
%341 = load i64, i64* %26
%342 = call i8* @memcpy(i8* %337, i8* %340, i64 %341)
%343 = load i8*, i8** %14
%344 = getelementptr inbounds i8, i8* %343, i32 -1
store i8* %344, i8** %14
store i8 47, i8* %344
%345 = load i32*, i32** %17
%346 = call i32 @closedir(i32* %345)
br label %347
347: ; preds = %332
%348 = load i64, i64* %19
store i64 %348, i64* %10
%349 = load i64, i64* %20
store i64 %349, i64* %12
br label %74
350: ; preds = %82
%351 = load i8*, i8** %14
%352 = load i8*, i8** %13
%353 = load i64, i64* %16
%354 = sub i64 %353, 1
%355 = getelementptr inbounds i8, i8* %352, i64 %354
%356 = icmp eq i8* %351, %355
br i1 %356, label %357, label %360
357: ; preds = %350
%358 = load i8*, i8** %14
%359 = getelementptr inbounds i8, i8* %358, i32 -1
store i8* %359, i8** %14
store i8 47, i8* %359
br label %360
360: ; preds = %357, %350
%361 = load i8*, i8** %7
%362 = icmp ne i8* %361, getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 0, i64 0)
br i1 %362, label %363, label %366
363: ; preds = %360
%364 = load i8*, i8** %7
%365 = call i32 @free(i8* %364)
br label %366
366: ; preds = %363, %360
%367 = load i8*, i8** %13
%368 = load i8*, i8** %14
%369 = load i8*, i8** %13
%370 = load i64, i64* %16
%371 = getelementptr inbounds i8, i8* %369, i64 %370
%372 = load i8*, i8** %14
%373 = ptrtoint i8* %371 to i64
%374 = ptrtoint i8* %372 to i64
%375 = sub i64 %373, %374
%376 = trunc i64 %375 to i32
%377 = call i32 @memmove(i8* %367, i8* %368, i32 %376)
%378 = load i8*, i8** %13
store i8* %378, i8** %3
br label %393
379: ; preds = %299, %284, %268, %152, %137, %115, %99
%380 = load i8*, i8** %7
%381 = icmp ne i8* %380, getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 0, i64 0)
br i1 %381, label %382, label %385
382: ; preds = %379
%383 = load i8*, i8** %7
%384 = call i32 @free(i8* %383)
br label %385
385: ; preds = %382, %379
br label %386
386: ; preds = %385, %68, %60
%387 = load i8*, i8** %4
%388 = icmp eq i8* %387, null
br i1 %388, label %389, label %392
389: ; preds = %386
%390 = load i8*, i8** %13
%391 = call i32 @free(i8* %390)
br label %392
392: ; preds = %389, %386
store i8* null, i8** %3
br label %393
393: ; preds = %392, %366, %50, %35
%394 = load i8*, i8** %3
ret i8* %394
395: ; preds = %260
unreachable
}

LLVM IR (-O2):
%struct.stat = type { i64, i64 }
%struct.dirent = type { i8*, i64 }
@getcwd.dots = internal constant [241 x i8] c"../../../../../../../../../../../../../../../../../../../../../../../ ../../../../../../../../../../../../../../../../../../../../../../../../../../ ../../../../../../../../../../../../../../../../../../../../../../../../../..\00"
@PATH_MAX = global i32 0
@.str = [2 x i8] c".\00"
@.str.1 = [2 x i8] c"/\00"
define i8* @getcwd(i8* %0, i64 %1) {
%3 = alloca %struct.stat
%4 = bitcast %struct.stat* %3 to i8*
%5 = icmp eq i64 %1, 0
%6 = icmp eq i8* %0, null
br i1 %5, label %7, label %12
7: ; preds = %2
br i1 %6, label %8, label %190
8: ; preds = %7
%9 = load i32, i32* @PATH_MAX
%10 = add nsw i32 %9, 1
%11 = sext i32 %10 to i64
br label %13
12: ; preds = %2
br i1 %6, label %13, label %17
13: ; preds = %8, %12
%14 = phi i64 [ %11, %8 ], [ %1, %12 ]
%15 = tail call i8* @malloc(i64 %14)
%16 = icmp eq i8* %15, null
br i1 %16, label %190, label %17
17: ; preds = %12, %13
%18 = phi i1 [ true, %13 ], [ false, %12 ]
%19 = phi i64 [ %14, %13 ], [ %1, %12 ]
%20 = phi i8* [ %15, %13 ], [ %0, %12 ]
%21 = getelementptr inbounds i8, i8* %20, i64 %19
%22 = getelementptr inbounds i8, i8* %21, i64 -1
store i8 0, i8* %22
%23 = call i64 @stat(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), %struct.stat* %3)
%24 = icmp slt i64 %23, 0
br i1 %24, label %186, label %25
25: ; preds = %17
%26 = getelementptr inbounds %struct.stat, %struct.stat* %3, i64 0, i32 0
%27 = load i64, i64* %26
%28 = getelementptr inbounds %struct.stat, %struct.stat* %3, i64 0, i32 1
%29 = load i64, i64* %28
%30 = call i64 @stat(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), %struct.stat* %3)
%31 = icmp slt i64 %30, 0
br i1 %31, label %186, label %32
32: ; preds = %25
%33 = load i64, i64* %26
%34 = load i64, i64* %28
%35 = icmp ne i64 %27, %33
%36 = icmp ne i64 %29, %34
%37 = select i1 %35, i1 true, i1 %36
br i1 %37, label %38, label %157
38: ; preds = %32, %145
%39 = phi i8* [ %67, %145 ], [ getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 1, i64 0), %32 ]
%40 = phi i8* [ %65, %145 ], [ getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 0, i64 0), %32 ]
%41 = phi i64 [ %64, %145 ], [ 240, %32 ]
%42 = phi i64 [ %71, %145 ], [ %27, %32 ]
%43 = phi i64 [ %72, %145 ], [ %29, %32 ]
%44 = phi i8* [ %148, %145 ], [ %20, %32 ]
%45 = phi i8* [ %152, %145 ], [ %22, %32 ]
%46 = phi i64 [ %146, %145 ], [ %19, %32 ]
%47 = icmp eq i8* %39, %40
br i1 %47, label %48, label %63
48: ; preds = %38
%49 = icmp eq i8* %39, getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 0, i64 0)
%50 = shl i64 %41, 1
%51 = or i64 %50, 1
br i1 %49, label %52, label %56
52: ; preds = %48
%53 = call i8* @malloc(i64 %51)
%54 = icmp eq i8* %53, null
br i1 %54, label %186, label %55
55: ; preds = %52
br label %59
56: ; preds = %48
%57 = call i8* @realloc(i8* %39, i64 %51)
%58 = icmp eq i8* %57, null
br i1 %58, label %183, label %59
59: ; preds = %55, %56
%60 = phi i8* [ %53, %55 ], [ %57, %56 ]
%61 = getelementptr inbounds i8, i8* %60, i64 %41
%62 = getelementptr inbounds i8, i8* %60, i64 %50
store i8 0, i8* %62
br label %63
63: ; preds = %59, %38
%64 = phi i64 [ %50, %59 ], [ %41, %38 ]
%65 = phi i8* [ %60, %59 ], [ %40, %38 ]
%66 = phi i8* [ %61, %59 ], [ %39, %38 ]
%67 = getelementptr inbounds i8, i8* %66, i64 -3
%68 = call i64 @stat(i8* %67, %struct.stat* %3)
%69 = icmp slt i64 %68, 0
br i1 %69, label %181, label %70
70: ; preds = %63
%71 = load i64, i64* %26
%72 = load i64, i64* %28
%73 = icmp eq i64 %71, %42
%74 = call i32* @opendir(i8* %67)
%75 = icmp eq i32* %74, null
br i1 %75, label %181, label %76
76: ; preds = %70
%77 = call %struct.dirent* @readdir(i32* %74)
%78 = icmp eq %struct.dirent* %77, null
br i1 %78, label %179, label %79
79: ; preds = %76
%80 = getelementptr inbounds i8, i8* %65, i64 %64
%81 = ptrtoint i8* %80 to i64
%82 = ptrtoint i8* %67 to i64
%83 = sub i64 %81, %82
%84 = add nsw i64 %83, 1
br label %85
85: ; preds = %79, %98
%86 = phi %struct.dirent* [ %77, %79 ], [ %99, %98 ]
%87 = getelementptr inbounds %struct.dirent, %struct.dirent* %86, i64 0, i32 0
%88 = load i8*, i8** %87
%89 = load i8, i8* %88
%90 = icmp eq i8 %89, 46
br i1 %90, label %91, label %101
91: ; preds = %85
%92 = getelementptr inbounds i8, i8* %88, i64 1
%93 = load i8, i8* %92
switch i8 %93, label %101 [
i8 0, label %98
i8 46, label %94
]
94: ; preds = %91
%95 = getelementptr inbounds i8, i8* %88, i64 2
%96 = load i8, i8* %95
%97 = icmp eq i8 %96, 0
br i1 %97, label %98, label %101
98: ; preds = %102, %106, %94, %91
%99 = call %struct.dirent* @readdir(i32* %74)
%100 = icmp eq %struct.dirent* %99, null
br i1 %100, label %179, label %85
101: ; preds = %91, %94, %85
br i1 %73, label %102, label %106
102: ; preds = %101
%103 = getelementptr inbounds %struct.dirent, %struct.dirent* %86, i64 0, i32 1
%104 = load i64, i64* %103
%105 = icmp eq i64 %104, %43
br i1 %105, label %106, label %98
106: ; preds = %102, %101
%107 = call i32 @_D_ALLOC_NAMLEN(%struct.dirent* %86)
%108 = sext i32 %107 to i64
%109 = add nsw i64 %84, %108
%110 = call i8* @llvm.stacksave()
%111 = alloca i8, i64 %109
%112 = getelementptr inbounds i8, i8* %111, i64 %83
store i8 47, i8* %112
%113 = getelementptr inbounds i8, i8* %111, i64 %84
%114 = load i8*, i8** %87
%115 = call i32 @strcpy(i8* %113, i8* %114)
%116 = call i64 @stat(i8* %111, %struct.stat* %3)
%117 = icmp sgt i64 %116, -1
%118 = load i64, i64* %26
%119 = icmp eq i64 %118, %42
%120 = select i1 %117, i1 %119, i1 false
%121 = load i64, i64* %28
%122 = icmp eq i64 %121, %43
%123 = select i1 %120, i1 %122, i1 false
br i1 %123, label %124, label %98
124: ; preds = %106
%125 = call i64 @_D_EXACT_NAMLEN(%struct.dirent* %86)
%126 = ptrtoint i8* %45 to i64
%127 = ptrtoint i8* %44 to i64
%128 = sub i64 %126, %127
%129 = icmp ugt i64 %128, %125
br i1 %129, label %145, label %130
130: ; preds = %124
br i1 %5, label %131, label %179
131: ; preds = %130
%132 = call i32 @MAX(i64 %46, i64 %125)
%133 = shl nsw i32 %132, 1
%134 = sext i32 %133 to i64
%135 = call i8* @realloc(i8* %44, i64 %134)
%136 = icmp eq i8* %135, null
br i1 %136, label %179, label %137
137: ; preds = %131
%138 = getelementptr inbounds i8, i8* %135, i64 %134
%139 = getelementptr inbounds i8, i8* %44, i64 %46
%140 = ptrtoint i8* %139 to i64
%141 = sub i64 %140, %126
%142 = sub i64 0, %141
%143 = getelementptr inbounds i8, i8* %138, i64 %142
%144 = getelementptr inbounds i8, i8* %135, i64 %128
br label %145
145: ; preds = %124, %137
%146 = phi i64 [ %134, %137 ], [ %46, %124 ]
%147 = phi i8* [ %143, %137 ], [ %45, %124 ]
%148 = phi i8* [ %135, %137 ], [ %44, %124 ]
%149 = sub i64 0, %125
%150 = getelementptr inbounds i8, i8* %147, i64 %149
%151 = load i8*, i8** %87
%152 = getelementptr inbounds i8, i8* %150, i64 -1
store i8 47, i8* %152
%153 = call i32 @closedir(i32* %74)
%154 = icmp ne i64 %71, %33
%155 = icmp ne i64 %72, %34
%156 = select i1 %154, i1 true, i1 %155
br i1 %156, label %38, label %157
157: ; preds = %145, %32
%158 = phi i64 [ %19, %32 ], [ %146, %145 ]
%159 = phi i8* [ %22, %32 ], [ %152, %145 ]
%160 = phi i8* [ %20, %32 ], [ %148, %145 ]
%161 = phi i8* [ getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 0, i64 0), %32 ], [ %65, %145 ]
%162 = add i64 %158, -1
%163 = getelementptr inbounds i8, i8* %160, i64 %162
%164 = icmp eq i8* %159, %163
br i1 %164, label %165, label %167
165: ; preds = %157
%166 = getelementptr inbounds i8, i8* %159, i64 -1
store i8 47, i8* %166
br label %167
167: ; preds = %165, %157
%168 = phi i8* [ %166, %165 ], [ %159, %157 ]
%169 = icmp eq i8* %161, getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 0, i64 0)
br i1 %169, label %172, label %170
170: ; preds = %167
%171 = call i32 @free(i8* %161)
br label %172
172: ; preds = %170, %167
%173 = getelementptr inbounds i8, i8* %160, i64 %158
%174 = ptrtoint i8* %173 to i64
%175 = ptrtoint i8* %168 to i64
%176 = sub i64 %174, %175
%177 = trunc i64 %176 to i32
%178 = call i32 @memmove(i8* %160, i8* %168, i32 %177)
br label %190
179: ; preds = %131, %130, %76, %98
%180 = call i32 @closedir(i32* %74)
br label %181
181: ; preds = %63, %70, %179
%182 = icmp eq i8* %65, getelementptr inbounds ([241 x i8], [241 x i8]* @getcwd.dots, i64 0, i64 0)
br i1 %182, label %186, label %183
183: ; preds = %56, %181
%184 = phi i8* [ %65, %181 ], [ %39, %56 ]
%185 = call i32 @free(i8* %184)
br label %186
186: ; preds = %52, %181, %183, %25, %17
%187 = phi i8* [ %20, %17 ], [ %20, %25 ], [ %44, %183 ], [ %44, %181 ], [ %44, %52 ]
br i1 %18, label %188, label %190
188: ; preds = %186
%189 = call i32 @free(i8* %187)
br label %190
190: ; preds = %186, %188, %13, %7, %172
%191 = phi i8* [ %160, %172 ], [ null, %7 ], [ null, %13 ], [ null, %188 ], [ null, %186 ]
ret i8* %191
}