#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 */

/* Variables and functions */
int /*<<< orphan*/ memcpy(char *, char *, size_t);
int strlen(char *);
char *dirname(char *path) {
  static char result[1024];
  const char *lastp;
  size_t len;
  if ((path == NULL) || (*path == '\0'))
    goto singledot;
  lastp = path + strlen(path) - 1;
  while (lastp != path && *lastp == '/')
    lastp--;
  do {
    if (*lastp == '/') {
      while (lastp != path && *lastp == '/')
        lastp--;
      len = (lastp - path) + 1;
      if (len > (1024 - 1))
        len = 1024 - 1;
      memcpy(result, path, len);
      result[len] = '\0';
      return (result);
    }
  } while (--lastp >= path);
singledot:
  result[0] = '.';
  result[1] = '\0';
  return (result);
}


x86 assembly (clang, -O0):
<dirname>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     1147 <dirname+0x27>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
jne    114c <dirname+0x2c>
jmp    128f <dirname+0x16f>
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%rdi
call   1030 <strlen@plt>
mov    %eax,%ecx
mov    -0x28(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rcx
xor    %eax,%eax
cmp    -0x10(%rbp),%rcx
mov    %al,-0x29(%rbp)
je     1194 <dirname+0x74>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2f,%eax
sete   %al
mov    %al,-0x29(%rbp)
mov    -0x29(%rbp),%al
test   $0x1,%al
jne    11a4 <dirname+0x84>
jmp    11b5 <dirname+0x95>
mov    -0x18(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x18(%rbp)
jmp    1171 <dirname+0x51>
jmp    11ba <dirname+0x9a>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2f,%eax
jne    126f <dirname+0x14f>
jmp    11cf <dirname+0xaf>
mov    -0x18(%rbp),%rcx
xor    %eax,%eax
cmp    -0x10(%rbp),%rcx
mov    %al,-0x2a(%rbp)
je     11f2 <dirname+0xd2>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2f,%eax
sete   %al
mov    %al,-0x2a(%rbp)
mov    -0x2a(%rbp),%al
test   $0x1,%al
jne    1202 <dirname+0xe2>
jmp    1213 <dirname+0xf3>
mov    -0x18(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x18(%rbp)
jmp    11cf <dirname+0xaf>
mov    -0x18(%rbp),%rax
mov    -0x10(%rbp),%rcx
sub    %rcx,%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
cmpq   $0x3ff,-0x20(%rbp)
jbe    123c <dirname+0x11c>
movq   $0x3ff,-0x20(%rbp)
mov    -0x10(%rbp),%rsi
mov    -0x20(%rbp),%rdx
lea    0x2df5(%rip),%rdi
call   1040 <memcpy@plt>
mov    -0x20(%rbp),%rcx
lea    0x2de5(%rip),%rax
movb   $0x0,(%rax,%rcx,1)
lea    0x2dda(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    12a8 <dirname+0x188>
jmp    1274 <dirname+0x154>
mov    -0x18(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x18(%rbp)
cmp    -0x10(%rbp),%rax
jae    11ba <dirname+0x9a>
jmp    128f <dirname+0x16f>
movb   $0x2e,0x2daa(%rip)
movb   $0x0,0x2da4(%rip)
lea    0x2d9c(%rip),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<dirname>:
push   %r15
push   %r14
push   %rbx
test   %rdi,%rdi
je     1182 <dirname+0x62>
mov    %rdi,%rbx
cmpb   $0x0,(%rdi)
je     1182 <dirname+0x62>
mov    %rbx,%rdi
call   1030 <strlen@plt>
cltq
nopl   0x0(%rax)
cmp    $0x1,%rax
je     1159 <dirname+0x39>
lea    -0x1(%rax),%rcx
cmpb   $0x2f,-0x1(%rbx,%rax,1)
mov    %rcx,%rax
je     1140 <dirname+0x20>
add    %rbx,%rcx
jmp    115c <dirname+0x3c>
mov    %rbx,%rcx
mov    %rbx,%rax
sub    %rcx,%rax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
cmpb   $0x2f,(%rcx)
je     11a1 <dirname+0x81>
add    $0xffffffffffffffff,%rcx
add    $0x1,%rax
cmp    %rbx,%rcx
jae    1170 <dirname+0x50>
movb   $0x2e,0x2eb7(%rip)
lea    0x2eb1(%rip),%r14
movb   $0x0,(%r14)
lea    0x2ea5(%rip),%rax
pop    %rbx
pop    %r14
pop    %r15
ret
cmp    %rbx,%rcx
je     11ca <dirname+0xaa>
lea    -0x1(%rcx),%rdx
add    %rcx,%rax
nopl   (%rax)
cmp    %rbx,%rdx
je     11cd <dirname+0xad>
lea    -0x1(%rdx),%rcx
cmpb   $0x2f,(%rdx)
mov    %rcx,%rdx
je     11b0 <dirname+0x90>
add    $0x1,%rcx
mov    %rcx,%rax
jmp    11cd <dirname+0xad>
mov    %rbx,%rax
sub    %rbx,%rax
add    $0x1,%rax
cmp    $0x3ff,%rax
mov    $0x3ff,%r14d
cmovb  %rax,%r14
lea    0x2e55(%rip),%r15
mov    %r15,%rdi
mov    %rbx,%rsi
mov    %r14,%rdx
call   1040 <memcpy@plt>
add    %r15,%r14
jmp    1190 <dirname+0x70>

LLVM IR (-O0):
@dirname.result = internal global [1024 x i8] zeroinitializer
define i8* @dirname(i8* %0) {
%2 = alloca i8*
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i64
store i8* %0, i8** %3
%6 = load i8*, i8** %3
%7 = icmp eq i8* %6, null
br i1 %7, label %13, label %8
8: ; preds = %1
%9 = load i8*, i8** %3
%10 = load i8, i8* %9
%11 = sext i8 %10 to i32
%12 = icmp eq i32 %11, 0
br i1 %12, label %13, label %14
13: ; preds = %8, %1
br label %79
14: ; preds = %8
%15 = load i8*, i8** %3
%16 = load i8*, i8** %3
%17 = call i32 @strlen(i8* %16)
%18 = sext i32 %17 to i64
%19 = getelementptr inbounds i8, i8* %15, i64 %18
%20 = getelementptr inbounds i8, i8* %19, i64 -1
store i8* %20, i8** %4
br label %21
21: ; preds = %32, %14
%22 = load i8*, i8** %4
%23 = load i8*, i8** %3
%24 = icmp ne i8* %22, %23
br i1 %24, label %25, label %30
25: ; preds = %21
%26 = load i8*, i8** %4
%27 = load i8, i8* %26
%28 = sext i8 %27 to i32
%29 = icmp eq i32 %28, 47
br label %30
30: ; preds = %25, %21
%31 = phi i1 [ false, %21 ], [ %29, %25 ]
br i1 %31, label %32, label %35
32: ; preds = %30
%33 = load i8*, i8** %4
%34 = getelementptr inbounds i8, i8* %33, i32 -1
store i8* %34, i8** %4
br label %21
35: ; preds = %30
br label %36
36: ; preds = %73, %35
%37 = load i8*, i8** %4
%38 = load i8, i8* %37
%39 = sext i8 %38 to i32
%40 = icmp eq i32 %39, 47
br i1 %40, label %41, label %72
41: ; preds = %36
br label %42
42: ; preds = %53, %41
%43 = load i8*, i8** %4
%44 = load i8*, i8** %3
%45 = icmp ne i8* %43, %44
br i1 %45, label %46, label %51
46: ; preds = %42
%47 = load i8*, i8** %4
%48 = load i8, i8* %47
%49 = sext i8 %48 to i32
%50 = icmp eq i32 %49, 47
br label %51
51: ; preds = %46, %42
%52 = phi i1 [ false, %42 ], [ %50, %46 ]
br i1 %52, label %53, label %56
53: ; preds = %51
%54 = load i8*, i8** %4
%55 = getelementptr inbounds i8, i8* %54, i32 -1
store i8* %55, i8** %4
br label %42
56: ; preds = %51
%57 = load i8*, i8** %4
%58 = load i8*, i8** %3
%59 = ptrtoint i8* %57 to i64
%60 = ptrtoint i8* %58 to i64
%61 = sub i64 %59, %60
%62 = add nsw i64 %61, 1
store i64 %62, i64* %5
%63 = load i64, i64* %5
%64 = icmp ugt i64 %63, 1023
br i1 %64, label %65, label %66
65: ; preds = %56
store i64 1023, i64* %5
br label %66
66: ; preds = %65, %56
%67 = load i8*, i8** %3
%68 = load i64, i64* %5
%69 = call i32 @memcpy(i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dirname.result, i64 0, i64 0), i8* %67, i64 %68)
%70 = load i64, i64* %5
%71 = getelementptr inbounds [1024 x i8], [1024 x i8]* @dirname.result, i64 0, i64 %70
store i8 0, i8* %71
store i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dirname.result, i64 0, i64 0), i8** %2
br label %80
72: ; preds = %36
br label %73
73: ; preds = %72
%74 = load i8*, i8** %4
%75 = getelementptr inbounds i8, i8* %74, i32 -1
store i8* %75, i8** %4
%76 = load i8*, i8** %3
%77 = icmp uge i8* %75, %76
br i1 %77, label %36, label %78
78: ; preds = %73
br label %79
79: ; preds = %78, %13
store i8 46, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dirname.result, i64 0, i64 0)
store i8 0, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dirname.result, i64 0, i64 1)
store i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dirname.result, i64 0, i64 0), i8** %2
br label %80
80: ; preds = %79, %66
%81 = load i8*, i8** %2
ret i8* %81
}

LLVM IR (-O2):
@dirname.result = internal global [1024 x i8] zeroinitializer
define i8* @dirname(i8* %0) {
%2 = ptrtoint i8* %0 to i64
%3 = icmp eq i8* %0, null
br i1 %3, label %51, label %4
4: ; preds = %1
%5 = load i8, i8* %0
%6 = icmp eq i8 %5, 0
br i1 %6, label %51, label %7
7: ; preds = %4
%8 = tail call i32 @strlen(i8* %0)
%9 = sext i32 %8 to i64
%10 = getelementptr inbounds i8, i8* %0, i64 %9
br label %11
11: ; preds = %15, %7
%12 = phi i8* [ %10, %7 ], [ %13, %15 ]
%13 = getelementptr inbounds i8, i8* %12, i64 -1
%14 = icmp eq i8* %13, %0
br i1 %14, label %18, label %15
15: ; preds = %11
%16 = load i8, i8* %13
%17 = icmp eq i8 %16, 47
br i1 %17, label %11, label %18
18: ; preds = %11, %15
%19 = phi i8* [ %13, %15 ], [ %0, %11 ]
br label %20
20: ; preds = %18, %48
%21 = phi i8* [ %49, %48 ], [ %19, %18 ]
%22 = load i8, i8* %21
%23 = icmp eq i8 %22, 47
br i1 %23, label %24, label %48
24: ; preds = %20
%25 = icmp eq i8* %21, %0
br i1 %25, label %40, label %26
26: ; preds = %24
%27 = ptrtoint i8* %21 to i64
%28 = sub i64 %2, %27
%29 = getelementptr i8, i8* %21, i64 %28
br label %30
30: ; preds = %26, %34
%31 = phi i8* [ %21, %26 ], [ %32, %34 ]
%32 = getelementptr inbounds i8, i8* %31, i64 -1
%33 = icmp eq i8* %32, %0
br i1 %33, label %37, label %34
34: ; preds = %30
%35 = load i8, i8* %32
%36 = icmp eq i8 %35, 47
br i1 %36, label %30, label %37
37: ; preds = %30, %34
%38 = phi i8* [ %32, %34 ], [ %29, %30 ]
%39 = ptrtoint i8* %38 to i64
br label %40
40: ; preds = %37, %24
%41 = phi i64 [ %39, %37 ], [ %2, %24 ]
%42 = sub i64 %41, %2
%43 = add nsw i64 %42, 1
%44 = icmp ult i64 %43, 1023
%45 = select i1 %44, i64 %43, i64 1023
%46 = tail call i32 @memcpy(i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dirname.result, i64 0, i64 0), i8* %0, i64 %45)
%47 = getelementptr inbounds [1024 x i8], [1024 x i8]* @dirname.result, i64 0, i64 %45
br label %52
48: ; preds = %20
%49 = getelementptr inbounds i8, i8* %21, i64 -1
%50 = icmp ult i8* %49, %0
br i1 %50, label %51, label %20
51: ; preds = %48, %1, %4
store i8 46, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dirname.result, i64 0, i64 0)
br label %52
52: ; preds = %51, %40
%53 = phi i8* [ getelementptr inbounds ([1024 x i8], [1024 x i8]* @dirname.result, i64 0, i64 1), %51 ], [ %47, %40 ]
store i8 0, i8* %53
ret i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dirname.result, i64 0, i64 0)
}