#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 /*<<< orphan*/ st_mode;
};

/* Variables and functions */
int /*<<< orphan*/ EINVAL;
int /*<<< orphan*/ ELOOP;
int /*<<< orphan*/ ENAMETOOLONG;
int /*<<< orphan*/ ENOENT;
int MAXSYMLINKS;
scalar_t__ S_ISLNK(int /*<<< orphan*/);
int /*<<< orphan*/ _PC_PATH_MAX;
int /*<<< orphan*/ _STAT_VER;
int /*<<< orphan*/ __getcwd(char *, long);
scalar_t__ __lxstat(int /*<<< orphan*/, char *, struct stat *);
char *__mempcpy(char *, char const *, int);
int __readlink(char *, char *, long);
int /*<<< orphan*/ __set_errno(int /*<<< orphan*/);
char *alloca(long);
int /*<<< orphan*/ free(char *);
char *malloc(long);
char *memcpy(char *, char *, int);
int /*<<< orphan*/ memmove(char *, char const *, size_t);
long pathconf(char const *, int /*<<< orphan*/);
char *realloc(char *, size_t);
char *strchr(char *, char);
int /*<<< orphan*/ strcpy(char *, char *);
size_t strlen(char const *);
char *canonicalize(const char *name, char *resolved) {
  char *rpath, *dest, *extra_buf = NULL;
  const char *start, *end, *rpath_limit;
  long int path_max;
  int num_links = 0;
  if (name == NULL) {
    __set_errno(EINVAL);
    return NULL;
  }
  if (name[0] == '\0') {
    __set_errno(ENOENT);
    return NULL;
  }
  path_max = pathconf(name, _PC_PATH_MAX);
  if (path_max <= 0)
    path_max = 1024;
  rpath = resolved ? alloca(path_max) : malloc(path_max);
  rpath_limit = rpath + path_max;
  if (name[0] != '/' || name[0] == '\\') {
    if (!__getcwd(rpath, path_max))
      goto error;
    dest = strchr(rpath, '\0');
  } else {
    rpath[0] = '/';
    dest = rpath + 1;
  }
  for (start = end = name; *start; start = end) {
    struct stat st;
    int n;
    while (*start == '/' || *start == '\\')
      ++start;
    for (end = start; *end && *end != '/' && *end != '\\'; ++end)
      ;
    if (end - start == 0)
      break;
    else if (end - start == 1 && start[0] == '.')
      ;
    else if (end - start == 2 && start[0] == '.' && start[1] == '.') {
      if (dest > rpath + 1)
        while ((--dest)[-1] != '/' && dest[-1] != '\\')
          ;
    } else {
      size_t new_size;
      if (dest[-1] != '/' && dest[-1] != '\\')
        *dest++ = '/';
      if (dest + (end - start) >= rpath_limit) {
        long dest_offset = dest - rpath;
        if (resolved) {
          __set_errno(ENAMETOOLONG);
          goto error;
        }
        new_size = rpath_limit - rpath;
        if (end - start + 1 > path_max)
          new_size += end - start + 1;
        else
          new_size += path_max;
        rpath = realloc(rpath, new_size);
        rpath_limit = rpath + new_size;
        if (rpath == NULL)
          return NULL;
        dest = rpath + dest_offset;
      }
      dest = __mempcpy(dest, start, end - start);
      *dest = '\0';
      if (__lxstat(_STAT_VER, rpath, &st) < 0)
        goto error;
      if (S_ISLNK(st.st_mode)) {
        char *buf = alloca(path_max);
        size_t len;
        if (++num_links > MAXSYMLINKS) {
          __set_errno(ELOOP);
          goto error;
        }
        n = __readlink(rpath, buf, path_max);
        if (n < 0)
          goto error;
        buf[n] = '\0';
        if (!extra_buf)
          extra_buf = alloca(path_max);
        len = strlen(end);
        if ((long int)(n + len) >= path_max) {
          __set_errno(ENAMETOOLONG);
          goto error;
        }
        memmove(&extra_buf[n], end, len + 1);
        name = end = memcpy(extra_buf, buf, n);
        if (buf[0] == '/' || buf[0] == '\\')
          dest = rpath + 1;
        else if (dest > rpath + 1)
          while ((--dest)[-1] != '/' && dest[-1] != '\\')
            ;
      }
    }
  }
  if (dest > rpath + 1 && (dest[-1] == '/' || dest[-1] == '\\'))
    --dest;
  *dest = '\0';
  return resolved ? memcpy(resolved, rpath, dest - rpath + 1) : rpath;
error:
  if (resolved)
    strcpy(resolved, rpath);
  else
    free(rpath);
  return NULL;
}


x86 assembly (clang, -O0):
<canonicalize>:
push   %rbp
mov    %rsp,%rbp
sub    $0xa0,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
movq   $0x0,-0x30(%rbp)
movl   $0x0,-0x54(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1248 <canonicalize+0x48>
mov    0x2d8c(%rip),%rax
mov    (%rax),%edi
call   1030 <__set_errno@plt>
movq   $0x0,-0x8(%rbp)
jmp    18f6 <canonicalize+0x6f6>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
jne    1273 <canonicalize+0x73>
mov    0x2d49(%rip),%rax
mov    (%rax),%edi
call   1030 <__set_errno@plt>
movq   $0x0,-0x8(%rbp)
jmp    18f6 <canonicalize+0x6f6>
mov    -0x10(%rbp),%rdi
mov    0x2d52(%rip),%rax
mov    (%rax),%esi
call   1080 <pathconf@plt>
mov    %rax,-0x50(%rbp)
cmpq   $0x0,-0x50(%rbp)
jg     129c <canonicalize+0x9c>
movq   $0x400,-0x50(%rbp)
cmpq   $0x0,-0x18(%rbp)
je     12bc <canonicalize+0xbc>
mov    -0x50(%rbp),%rdi
call   10d0 <alloca@plt>
mov    %rax,-0x88(%rbp)
jmp    12cc <canonicalize+0xcc>
mov    -0x50(%rbp),%rdi
call   10f0 <malloc@plt>
mov    %rax,-0x88(%rbp)
mov    -0x88(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
add    -0x50(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2f,%eax
jne    1303 <canonicalize+0x103>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x5c,%eax
jne    1332 <canonicalize+0x132>
mov    -0x20(%rbp),%rdi
mov    -0x50(%rbp),%rsi
call   1120 <__getcwd@plt>
cmp    $0x0,%eax
jne    131e <canonicalize+0x11e>
jmp    18c8 <canonicalize+0x6c8>
mov    -0x20(%rbp),%rdi
xor    %esi,%esi
call   10b0 <strchr@plt>
mov    %rax,-0x28(%rbp)
jmp    1345 <canonicalize+0x145>
mov    -0x20(%rbp),%rax
movb   $0x2f,(%rax)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    %rax,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmpb   $0x0,(%rax)
je     182e <canonicalize+0x62e>
jmp    1363 <canonicalize+0x163>
mov    -0x38(%rbp),%rax
movsbl (%rax),%ecx
mov    $0x1,%al
cmp    $0x2f,%ecx
mov    %al,-0x89(%rbp)
je     138e <canonicalize+0x18e>
mov    -0x38(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x5c,%eax
sete   %al
mov    %al,-0x89(%rbp)
mov    -0x89(%rbp),%al
test   $0x1,%al
jne    13a1 <canonicalize+0x1a1>
jmp    13b2 <canonicalize+0x1b2>
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    1363 <canonicalize+0x163>
mov    -0x38(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x40(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x8a(%rbp)
je     13fd <canonicalize+0x1fd>
mov    -0x40(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x2f,%ecx
mov    %al,-0x8a(%rbp)
je     13fd <canonicalize+0x1fd>
mov    -0x40(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x5c,%eax
setne  %al
mov    %al,-0x8a(%rbp)
mov    -0x8a(%rbp),%al
test   $0x1,%al
jne    1410 <canonicalize+0x210>
jmp    1426 <canonicalize+0x226>
jmp    1415 <canonicalize+0x215>
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    13ba <canonicalize+0x1ba>
mov    -0x40(%rbp),%rax
mov    -0x38(%rbp),%rcx
sub    %rcx,%rax
cmp    $0x0,%rax
jne    1440 <canonicalize+0x240>
jmp    182e <canonicalize+0x62e>
mov    -0x40(%rbp),%rax
mov    -0x38(%rbp),%rcx
sub    %rcx,%rax
cmp    $0x1,%rax
jne    146a <canonicalize+0x26a>
mov    -0x38(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2e,%eax
jne    146a <canonicalize+0x26a>
jmp    1817 <canonicalize+0x617>
mov    -0x40(%rbp),%rax
mov    -0x38(%rbp),%rcx
sub    %rcx,%rax
cmp    $0x2,%rax
jne    1514 <canonicalize+0x314>
mov    -0x38(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2e,%eax
jne    1514 <canonicalize+0x314>
mov    -0x38(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x2e,%eax
jne    1514 <canonicalize+0x314>
mov    -0x28(%rbp),%rax
mov    -0x20(%rbp),%rcx
add    $0x1,%rcx
cmp    %rcx,%rax
jbe    150f <canonicalize+0x30f>
jmp    14ba <canonicalize+0x2ba>
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x28(%rbp)
movsbl -0x2(%rax),%ecx
xor    %eax,%eax
cmp    $0x2f,%ecx
mov    %al,-0x8b(%rbp)
je     14f2 <canonicalize+0x2f2>
mov    -0x28(%rbp),%rax
movsbl -0x1(%rax),%eax
cmp    $0x5c,%eax
setne  %al
mov    %al,-0x8b(%rbp)
mov    -0x8b(%rbp),%al
test   $0x1,%al
jne    1505 <canonicalize+0x305>
jmp    150a <canonicalize+0x30a>
jmp    14ba <canonicalize+0x2ba>
jmp    150f <canonicalize+0x30f>
jmp    1812 <canonicalize+0x612>
mov    -0x28(%rbp),%rax
movsbl -0x1(%rax),%eax
cmp    $0x2f,%eax
je     1548 <canonicalize+0x348>
mov    -0x28(%rbp),%rax
movsbl -0x1(%rax),%eax
cmp    $0x5c,%eax
je     1548 <canonicalize+0x348>
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movb   $0x2f,(%rax)
mov    -0x28(%rbp),%rax
mov    -0x40(%rbp),%rcx
mov    -0x38(%rbp),%rdx
sub    %rdx,%rcx
add    %rcx,%rax
cmp    -0x48(%rbp),%rax
jb     1622 <canonicalize+0x422>
mov    -0x28(%rbp),%rax
mov    -0x20(%rbp),%rcx
sub    %rcx,%rax
mov    %rax,-0x70(%rbp)
cmpq   $0x0,-0x18(%rbp)
je     1591 <canonicalize+0x391>
mov    0x2a33(%rip),%rax
mov    (%rax),%edi
call   1030 <__set_errno@plt>
jmp    18c8 <canonicalize+0x6c8>
mov    -0x48(%rbp),%rax
mov    -0x20(%rbp),%rcx
sub    %rcx,%rax
mov    %rax,-0x68(%rbp)
mov    -0x40(%rbp),%rax
mov    -0x38(%rbp),%rcx
sub    %rcx,%rax
add    $0x1,%rax
cmp    -0x50(%rbp),%rax
jle    15d5 <canonicalize+0x3d5>
mov    -0x40(%rbp),%rax
mov    -0x38(%rbp),%rcx
sub    %rcx,%rax
add    $0x1,%rax
add    -0x68(%rbp),%rax
mov    %rax,-0x68(%rbp)
jmp    15e1 <canonicalize+0x3e1>
mov    -0x50(%rbp),%rax
add    -0x68(%rbp),%rax
mov    %rax,-0x68(%rbp)
mov    -0x20(%rbp),%rdi
mov    -0x68(%rbp),%rsi
call   1100 <realloc@plt>
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
add    -0x68(%rbp),%rax
mov    %rax,-0x48(%rbp)
cmpq   $0x0,-0x20(%rbp)
jne    1616 <canonicalize+0x416>
movq   $0x0,-0x8(%rbp)
jmp    18f6 <canonicalize+0x6f6>
mov    -0x20(%rbp),%rax
add    -0x70(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rdi
mov    -0x38(%rbp),%rsi
mov    -0x40(%rbp),%rax
mov    -0x38(%rbp),%rcx
sub    %rcx,%rax
mov    %eax,%edx
call   1070 <__mempcpy@plt>
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
movb   $0x0,(%rax)
mov    0x297a(%rip),%rax
mov    (%rax),%edi
mov    -0x20(%rbp),%rsi
lea    -0x58(%rbp),%rdx
call   10a0 <__lxstat@plt>
cmp    $0x0,%rax
jge    166c <canonicalize+0x46c>
jmp    18c8 <canonicalize+0x6c8>
mov    -0x58(%rbp),%edi
call   1060 <S_ISLNK@plt>
cmp    $0x0,%rax
je     180d <canonicalize+0x60d>
mov    -0x50(%rbp),%rdi
call   10d0 <alloca@plt>
mov    %rax,-0x78(%rbp)
mov    -0x54(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x54(%rbp)
mov    0x294d(%rip),%rcx
cmp    (%rcx),%eax
jle    16b6 <canonicalize+0x4b6>
mov    0x2936(%rip),%rax
mov    (%rax),%edi
call   1030 <__set_errno@plt>
jmp    18c8 <canonicalize+0x6c8>
mov    -0x20(%rbp),%rdi
mov    -0x78(%rbp),%rsi
mov    -0x50(%rbp),%rdx
call   10c0 <__readlink@plt>
mov    %eax,-0x5c(%rbp)
cmpl   $0x0,-0x5c(%rbp)
jge    16d9 <canonicalize+0x4d9>
jmp    18c8 <canonicalize+0x6c8>
mov    -0x78(%rbp),%rax
movslq -0x5c(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
cmpq   $0x0,-0x30(%rbp)
jne    16fd <canonicalize+0x4fd>
mov    -0x50(%rbp),%rdi
call   10d0 <alloca@plt>
mov    %rax,-0x30(%rbp)
mov    -0x40(%rbp),%rdi
call   1090 <strlen@plt>
mov    %rax,-0x80(%rbp)
movslq -0x5c(%rbp),%rax
add    -0x80(%rbp),%rax
cmp    -0x50(%rbp),%rax
jl     172f <canonicalize+0x52f>
mov    0x2895(%rip),%rax
mov    (%rax),%edi
call   1030 <__set_errno@plt>
jmp    18c8 <canonicalize+0x6c8>
mov    -0x30(%rbp),%rdi
movslq -0x5c(%rbp),%rax
add    %rax,%rdi
mov    -0x40(%rbp),%rsi
mov    -0x80(%rbp),%rdx
add    $0x1,%rdx
call   1110 <memmove@plt>
mov    -0x30(%rbp),%rdi
mov    -0x78(%rbp),%rsi
mov    -0x5c(%rbp),%edx
call   10e0 <memcpy@plt>
mov    %rax,-0x40(%rbp)
mov    %rax,-0x10(%rbp)
mov    -0x78(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2f,%eax
je     1783 <canonicalize+0x583>
mov    -0x78(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x5c,%eax
jne    1794 <canonicalize+0x594>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    1808 <canonicalize+0x608>
mov    -0x28(%rbp),%rax
mov    -0x20(%rbp),%rcx
add    $0x1,%rcx
cmp    %rcx,%rax
jbe    1803 <canonicalize+0x603>
jmp    17ae <canonicalize+0x5ae>
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x28(%rbp)
movsbl -0x2(%rax),%ecx
xor    %eax,%eax
cmp    $0x2f,%ecx
mov    %al,-0x8c(%rbp)
je     17e6 <canonicalize+0x5e6>
mov    -0x28(%rbp),%rax
movsbl -0x1(%rax),%eax
cmp    $0x5c,%eax
setne  %al
mov    %al,-0x8c(%rbp)
mov    -0x8c(%rbp),%al
test   $0x1,%al
jne    17f9 <canonicalize+0x5f9>
jmp    17fe <canonicalize+0x5fe>
jmp    17ae <canonicalize+0x5ae>
jmp    1803 <canonicalize+0x603>
jmp    1808 <canonicalize+0x608>
jmp    180d <canonicalize+0x60d>
jmp    1812 <canonicalize+0x612>
jmp    1817 <canonicalize+0x617>
jmp    181c <canonicalize+0x61c>
jmp    1821 <canonicalize+0x621>
mov    -0x40(%rbp),%rax
mov    %rax,-0x38(%rbp)
jmp    1351 <canonicalize+0x151>
mov    -0x28(%rbp),%rax
mov    -0x20(%rbp),%rcx
add    $0x1,%rcx
cmp    %rcx,%rax
jbe    1871 <canonicalize+0x671>
mov    -0x28(%rbp),%rax
movsbl -0x1(%rax),%eax
cmp    $0x2f,%eax
je     1865 <canonicalize+0x665>
mov    -0x28(%rbp),%rax
movsbl -0x1(%rax),%eax
cmp    $0x5c,%eax
jne    1871 <canonicalize+0x671>
mov    -0x28(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
movb   $0x0,(%rax)
cmpq   $0x0,-0x18(%rbp)
je     18ad <canonicalize+0x6ad>
mov    -0x18(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    -0x28(%rbp),%rax
mov    -0x20(%rbp),%rcx
sub    %rcx,%rax
add    $0x1,%rax
mov    %eax,%edx
call   10e0 <memcpy@plt>
mov    %rax,-0x98(%rbp)
jmp    18b8 <canonicalize+0x6b8>
mov    -0x20(%rbp),%rax
mov    %rax,-0x98(%rbp)
mov    -0x98(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    18f6 <canonicalize+0x6f6>
cmpq   $0x0,-0x18(%rbp)
je     18e5 <canonicalize+0x6e5>
mov    -0x18(%rbp),%rdi
mov    -0x20(%rbp),%rsi
call   1050 <strcpy@plt>
jmp    18ee <canonicalize+0x6ee>
mov    -0x20(%rbp),%rdi
call   1040 <free@plt>
movq   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0xa0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<canonicalize>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x38,%rsp
test   %rdi,%rdi
je     123b <canonicalize+0x4b>
mov    %rdi,%r14
cmpb   $0x0,(%rdi)
je     1244 <canonicalize+0x54>
mov    %rsi,%rbx
mov    0x2dbb(%rip),%rax
mov    (%rax),%esi
mov    %r14,%rdi
call   1080 <pathconf@plt>
test   %rax,%rax
mov    $0x400,%r15d
cmovg  %rax,%r15
mov    %r15,%rdi
test   %rbx,%rbx
je     1267 <canonicalize+0x77>
call   10c0 <alloca@plt>
jmp    126c <canonicalize+0x7c>
mov    0x2d7e(%rip),%rax
jmp    124b <canonicalize+0x5b>
mov    0x2d5d(%rip),%rax
mov    (%rax),%edi
call   1030 <__set_errno@plt>
xor    %r12d,%r12d
mov    %r12,%rax
add    $0x38,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
call   10e0 <malloc@plt>
mov    %rax,%r12
cmpb   $0x2f,(%r14)
jne    1286 <canonicalize+0x96>
mov    %rbx,(%rsp)
movb   $0x2f,(%r12)
mov    $0x1,%r13d
jmp    12a8 <canonicalize+0xb8>
mov    %r12,%rdi
mov    %r15,%rsi
call   1110 <__getcwd@plt>
test   %eax,%eax
je     15e5 <canonicalize+0x3f5>
mov    %rbx,(%rsp)
mov    %r12,%rdi
call   1090 <strlen@plt>
mov    %rax,%r13
add    %r12,%r13
mov    (%r14),%al
test   %al,%al
je     156a <canonicalize+0x37a>
lea    (%r12,%r15,1),%rdx
xor    %ecx,%ecx
mov    %rcx,0x20(%rsp)
xor    %ecx,%ecx
mov    %rcx,0x18(%rsp)
mov    %r15,0x8(%rsp)
jmp    12ef <canonicalize+0xff>
nop
mov    0x30(%rsp),%r12
lea    0x1(%r12),%r13
mov    0x8(%rsp),%r15
mov    0x10(%rsp),%rdx
mov    (%r14),%al
test   %al,%al
je     156a <canonicalize+0x37a>
mov    %r14,%rbx
jmp    130c <canonicalize+0x11c>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movzbl 0x1(%rbx),%eax
add    $0x1,%rbx
add    $0x1,%r14
cmp    $0x2f,%al
je     1300 <canonicalize+0x110>
cmp    $0x5c,%al
je     1300 <canonicalize+0x110>
xor    %ebp,%ebp
mov    %eax,%ecx
test   %cl,%cl
je     1337 <canonicalize+0x147>
nopl   0x0(%rax)
cmp    $0x2f,%cl
je     1337 <canonicalize+0x147>
cmp    $0x5c,%cl
je     1337 <canonicalize+0x147>
movzbl 0x1(%rbx,%rbp,1),%ecx
add    $0x1,%rbp
test   %cl,%cl
jne    1320 <canonicalize+0x130>
lea    (%rbx,%rbp,1),%r14
cmp    $0x1,%rbp
je     1360 <canonicalize+0x170>
cmp    $0x2,%rbp
je     1370 <canonicalize+0x180>
test   %rbp,%rbp
jne    13b0 <canonicalize+0x1c0>
jmp    156a <canonicalize+0x37a>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
cmp    $0x2e,%al
je     12e4 <canonicalize+0xf4>
jmp    13b0 <canonicalize+0x1c0>
cs nopw 0x0(%rax,%rax,1)
cmp    $0x2e,%al
jne    13b0 <canonicalize+0x1c0>
cmpb   $0x2e,0x1(%rbx)
jne    13b0 <canonicalize+0x1c0>
lea    0x1(%r12),%rax
cmp    %rax,%r13
jbe    12e4 <canonicalize+0xf4>
nopl   0x0(%rax,%rax,1)
movzbl -0x2(%r13),%eax
add    $0xffffffffffffffff,%r13
cmp    $0x2f,%al
je     12e4 <canonicalize+0xf4>
cmp    $0x5c,%al
jne    1390 <canonicalize+0x1a0>
jmp    12e4 <canonicalize+0xf4>
nopw   0x0(%rax,%rax,1)
mov    -0x1(%r13),%al
cmp    $0x2f,%al
je     13c5 <canonicalize+0x1d5>
cmp    $0x5c,%al
je     13c5 <canonicalize+0x1d5>
movb   $0x2f,0x0(%r13)
add    $0x1,%r13
mov    %r13,%rax
add    %rbp,%rax
cmp    %rdx,%rax
jae    13e0 <canonicalize+0x1f0>
mov    %rdx,0x10(%rsp)
jmp    1429 <canonicalize+0x239>
nopw   0x0(%rax,%rax,1)
cmpq   $0x0,(%rsp)
jne    15c6 <canonicalize+0x3d6>
sub    %r12,%rdx
mov    %r15,%rax
lea    0x1(%rbp),%r15
cmp    %rax,%rbp
cmovl  %rax,%r15
add    %rdx,%r15
mov    %r12,%rdi
mov    %r15,%rsi
call   10f0 <realloc@plt>
test   %rax,%rax
je     1252 <canonicalize+0x62>
sub    %r12,%r13
add    %rax,%r15
add    %rax,%r13
mov    %r15,0x10(%rsp)
mov    %rax,%r12
mov    0x8(%rsp),%r15
mov    %r13,%rdi
mov    %rbx,%rsi
mov    %ebp,%edx
call   1070 <__mempcpy@plt>
mov    %rax,%r13
movb   $0x0,(%rax)
mov    0x2b85(%rip),%rax
mov    (%rax),%edi
mov    %r12,%rsi
lea    0x28(%rsp),%rdx
call   10a0 <__lxstat@plt>
test   %rax,%rax
js     15b0 <canonicalize+0x3c0>
mov    0x28(%rsp),%edi
call   1060 <S_ISLNK@plt>
test   %rax,%rax
je     12df <canonicalize+0xef>
mov    %r15,%rdi
call   10c0 <alloca@plt>
mov    %rax,%rbx
mov    0x20(%rsp),%rax
mov    0x2b64(%rip),%rcx
cmp    (%rcx),%eax
jge    15d3 <canonicalize+0x3e3>
mov    %r12,%rdi
mov    %rbx,%rsi
mov    %r15,%rdx
call   10b0 <__readlink@plt>
test   %eax,%eax
js     15b0 <canonicalize+0x3c0>
mov    %eax,%ebp
mov    %eax,%r15d
movb   $0x0,(%rbx,%r15,1)
cmpq   $0x0,0x18(%rsp)
jne    14c3 <canonicalize+0x2d3>
mov    0x8(%rsp),%rdi
call   10c0 <alloca@plt>
mov    %rax,0x18(%rsp)
mov    %r14,%rdi
call   1090 <strlen@plt>
lea    (%rax,%r15,1),%rcx
cmp    0x8(%rsp),%rcx
jge    15c6 <canonicalize+0x3d6>
mov    %r12,0x30(%rsp)
mov    0x20(%rsp),%rcx
add    $0x1,%ecx
mov    %rcx,0x20(%rsp)
mov    0x18(%rsp),%r12
add    %r12,%r15
add    $0x1,%rax
mov    %r15,%rdi
mov    %r14,%rsi
mov    %rax,%rdx
call   1100 <memmove@plt>
mov    %r12,%rdi
mov    %rbx,%rsi
mov    %ebp,%edx
call   10d0 <memcpy@plt>
mov    %rax,%r14
mov    (%rbx),%al
cmp    $0x5c,%al
je     12d0 <canonicalize+0xe0>
cmp    $0x2f,%al
je     12d0 <canonicalize+0xe0>
mov    0x30(%rsp),%r12
lea    0x1(%r12),%rax
cmp    %rax,%r13
mov    0x8(%rsp),%r15
mov    0x10(%rsp),%rdx
jbe    12e4 <canonicalize+0xf4>
cs nopw 0x0(%rax,%rax,1)
nop
movzbl -0x2(%r13),%eax
add    $0xffffffffffffffff,%r13
cmp    $0x2f,%al
je     12e4 <canonicalize+0xf4>
cmp    $0x5c,%al
jne    1550 <canonicalize+0x360>
jmp    12e4 <canonicalize+0xf4>
lea    0x1(%r12),%rax
cmp    %rax,%r13
jbe    1584 <canonicalize+0x394>
mov    -0x1(%r13),%al
cmp    $0x5c,%al
je     1580 <canonicalize+0x390>
cmp    $0x2f,%al
jne    1584 <canonicalize+0x394>
add    $0xffffffffffffffff,%r13
movb   $0x0,0x0(%r13)
mov    (%rsp),%rdi
test   %rdi,%rdi
je     1255 <canonicalize+0x65>
sub    %r12d,%r13d
add    $0x1,%r13d
mov    %r12,%rsi
mov    %r13d,%edx
call   10d0 <memcpy@plt>
mov    %rax,%r12
jmp    1255 <canonicalize+0x65>
mov    (%rsp),%rbx
test   %rbx,%rbx
jne    15ea <canonicalize+0x3fa>
mov    %r12,%rdi
call   1040 <free@plt>
jmp    1252 <canonicalize+0x62>
mov    (%rsp),%rbx
mov    0x29e7(%rip),%rax
jmp    15de <canonicalize+0x3ee>
mov    0x2a06(%rip),%rax
mov    (%rsp),%rbx
mov    (%rax),%edi
call   1030 <__set_errno@plt>
test   %rbx,%rbx
je     15b9 <canonicalize+0x3c9>
mov    %rbx,%rdi
mov    %r12,%rsi
call   1050 <strcpy@plt>
jmp    1252 <canonicalize+0x62>

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

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