#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 dirent {
  scalar_t__ d_type;
  char *d_name;
};
typedef int /*<<< orphan*/ DIR;

/* Variables and functions */
scalar_t__ DT_DIR;
scalar_t__ DT_REG;
scalar_t__ DT_SOCK;
int chdir(char *);
int /*<<< orphan*/ closedir(int /*<<< orphan*/ *);
int /*<<< orphan*/ *opendir(char *);
int /*<<< orphan*/ perror(char const *);
struct dirent *readdir(int /*<<< orphan*/ *);
int rmdir(char const *);
int unlink(char *);
int deleter(const char *dir) {
  DIR *dfd = opendir(".");
  if (dfd == NULL) {
    perror(dir);
    return 1;
  }
  struct dirent *entry;
  while (entry = readdir(dfd)) {
    if (entry->d_type == DT_DIR && entry->d_name[0] != '.') {
      if (chdir(entry->d_name) == -1) {
        perror(entry->d_name);
        return 1;
      }
      if (deleter(entry->d_name) != 0) {
        return 1;
      }
      if (chdir("..") == -1) {
        perror("..");
        return 1;
      }
    } else if (entry->d_type == DT_REG || entry->d_type == DT_SOCK) {
      if (unlink(entry->d_name) == -1) {
        perror(entry->d_name);
        return 1;
      }
    } else if (entry->d_type == DT_SOCK) {
      if (rmdir(entry->d_name) == -1) {
        perror(entry->d_name);
        return 1;
      }
    }
  }
  closedir(dfd);
  if (chdir("..") == -1) {
    perror("..");
    return 1;
  }
  if (rmdir(dir) == -1) {
    perror(dir);
    return 1;
  }
  return 0;
}


x86 assembly (clang, -O0):
<deleter>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
lea    0xe6e(%rip),%rdi
call   1040 <opendir@plt>
mov    %rax,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    11bc <deleter+0x3c>
mov    -0x10(%rbp),%rdi
call   1090 <perror@plt>
movl   $0x1,-0x4(%rbp)
jmp    13a6 <deleter+0x226>
jmp    11c1 <deleter+0x41>
mov    -0x18(%rbp),%rdi
call   1080 <readdir@plt>
mov    %rax,-0x20(%rbp)
cmp    $0x0,%rax
je     1342 <deleter+0x1c2>
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    0x2df2(%rip),%rcx
cmp    (%rcx),%rax
jne    1286 <deleter+0x106>
mov    -0x20(%rbp),%rax
mov    0x8(%rax),%rax
movsbl (%rax),%eax
cmp    $0x2e,%eax
je     1286 <deleter+0x106>
mov    -0x20(%rbp),%rax
mov    0x8(%rax),%rdi
call   1060 <chdir@plt>
cmp    $0xffffffff,%eax
jne    1232 <deleter+0xb2>
mov    -0x20(%rbp),%rax
mov    0x8(%rax),%rdi
call   1090 <perror@plt>
movl   $0x1,-0x4(%rbp)
jmp    13a6 <deleter+0x226>
mov    -0x20(%rbp),%rax
mov    0x8(%rax),%rdi
call   10a0 <deleter@plt>
cmp    $0x0,%eax
je     1254 <deleter+0xd4>
movl   $0x1,-0x4(%rbp)
jmp    13a6 <deleter+0x226>
lea    0xda5(%rip),%rdi
call   1060 <chdir@plt>
cmp    $0xffffffff,%eax
jne    1281 <deleter+0x101>
lea    0xd90(%rip),%rdi
call   1090 <perror@plt>
movl   $0x1,-0x4(%rbp)
jmp    13a6 <deleter+0x226>
jmp    133d <deleter+0x1bd>
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    0x2d4c(%rip),%rcx
cmp    (%rcx),%rax
je     12b4 <deleter+0x134>
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    0x2d1d(%rip),%rcx
cmp    (%rcx),%rax
jne    12e8 <deleter+0x168>
mov    -0x20(%rbp),%rax
mov    0x8(%rax),%rdi
call   1030 <unlink@plt>
cmp    $0xffffffff,%eax
jne    12e3 <deleter+0x163>
mov    -0x20(%rbp),%rax
mov    0x8(%rax),%rdi
call   1090 <perror@plt>
movl   $0x1,-0x4(%rbp)
jmp    13a6 <deleter+0x226>
jmp    1338 <deleter+0x1b8>
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    0x2cd2(%rip),%rcx
cmp    (%rcx),%rax
jne    1333 <deleter+0x1b3>
mov    -0x20(%rbp),%rax
mov    0x8(%rax),%rdi
call   1050 <rmdir@plt>
cmp    $0xffffffff,%eax
jne    132e <deleter+0x1ae>
mov    -0x20(%rbp),%rax
mov    0x8(%rax),%rdi
call   1090 <perror@plt>
movl   $0x1,-0x4(%rbp)
jmp    13a6 <deleter+0x226>
jmp    1333 <deleter+0x1b3>
jmp    1338 <deleter+0x1b8>
jmp    133d <deleter+0x1bd>
jmp    11c1 <deleter+0x41>
mov    -0x18(%rbp),%rdi
call   1070 <closedir@plt>
lea    0xcae(%rip),%rdi
call   1060 <chdir@plt>
cmp    $0xffffffff,%eax
jne    1378 <deleter+0x1f8>
lea    0xc99(%rip),%rdi
call   1090 <perror@plt>
movl   $0x1,-0x4(%rbp)
jmp    13a6 <deleter+0x226>
mov    -0x10(%rbp),%rdi
call   1050 <rmdir@plt>
cmp    $0xffffffff,%eax
jne    139f <deleter+0x21f>
mov    -0x10(%rbp),%rdi
call   1090 <perror@plt>
movl   $0x1,-0x4(%rbp)
jmp    13a6 <deleter+0x226>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<deleter>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %rdi,%r15
lea    0xe6c(%rip),%rdi
call   1040 <opendir@plt>
test   %rax,%rax
je     1293 <deleter+0x113>
mov    %rax,%r12
mov    %r15,(%rsp)
mov    %rax,%rdi
call   1080 <readdir@plt>
test   %rax,%rax
je     1259 <deleter+0xd9>
mov    %rax,%rbx
mov    0x2e13(%rip),%r13
lea    0xe34(%rip),%r15
mov    0x2e0d(%rip),%rbp
mov    0x2dee(%rip),%r14
jmp    1202 <deleter+0x82>
nopl   0x0(%rax)
mov    0x8(%rbx),%rdi
call   1030 <unlink@plt>
cmp    $0xffffffff,%eax
je     128c <deleter+0x10c>
mov    %r12,%rdi
call   1080 <readdir@plt>
mov    %rax,%rbx
test   %rax,%rax
je     1259 <deleter+0xd9>
mov    (%rbx),%rax
cmp    0x0(%r13),%rax
jne    1214 <deleter+0x94>
mov    0x8(%rbx),%rdi
cmpb   $0x2e,(%rdi)
jne    1230 <deleter+0xb0>
cmp    0x0(%rbp),%rax
je     11e0 <deleter+0x60>
cmp    (%r14),%rax
jne    11f2 <deleter+0x72>
jmp    11e0 <deleter+0x60>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
add    $0x8,%rbx
call   1060 <chdir@plt>
cmp    $0xffffffff,%eax
je     1290 <deleter+0x110>
mov    (%rbx),%rdi
call   10a0 <deleter@plt>
test   %eax,%eax
jne    129b <deleter+0x11b>
mov    %r15,%rdi
call   1060 <chdir@plt>
cmp    $0xffffffff,%eax
jne    11f2 <deleter+0x72>
jmp    1293 <deleter+0x113>
mov    %r12,%rdi
call   1070 <closedir@plt>
lea    0xd98(%rip),%r15
mov    %r15,%rdi
call   1060 <chdir@plt>
cmp    $0xffffffff,%eax
je     1293 <deleter+0x113>
mov    (%rsp),%r15
mov    %r15,%rdi
call   1050 <rmdir@plt>
mov    %eax,%ecx
xor    %eax,%eax
cmp    $0xffffffff,%ecx
jne    12a0 <deleter+0x120>
jmp    1293 <deleter+0x113>
add    $0x8,%rbx
mov    (%rbx),%r15
mov    %r15,%rdi
call   1090 <perror@plt>
mov    $0x1,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.dirent = type { i64, i8* }
@.str = [2 x i8] c".\00"
@DT_DIR = global i64 0
@.str.1 = [3 x i8] c"..\00"
@DT_REG = global i64 0
@DT_SOCK = global i64 0
define i32 @deleter(i8* %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca i32*
%5 = alloca %struct.dirent*
store i8* %0, i8** %3
%6 = call i32* @opendir(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
store i32* %6, i32** %4
%7 = load i32*, i32** %4
%8 = icmp eq i32* %7, null
br i1 %8, label %9, label %12
9: ; preds = %1
%10 = load i8*, i8** %3
%11 = call i32 @perror(i8* %10)
store i32 1, i32* %2
br label %115
12: ; preds = %1
br label %13
13: ; preds = %99, %12
%14 = load i32*, i32** %4
%15 = call %struct.dirent* @readdir(i32* %14)
store %struct.dirent* %15, %struct.dirent** %5
%16 = icmp ne %struct.dirent* %15, null
br i1 %16, label %17, label %100
17: ; preds = %13
%18 = load %struct.dirent*, %struct.dirent** %5
%19 = getelementptr inbounds %struct.dirent, %struct.dirent* %18, i32 0, i32 0
%20 = load i64, i64* %19
%21 = load i64, i64* @DT_DIR
%22 = icmp eq i64 %20, %21
br i1 %22, label %23, label %55
23: ; preds = %17
%24 = load %struct.dirent*, %struct.dirent** %5
%25 = getelementptr inbounds %struct.dirent, %struct.dirent* %24, i32 0, i32 1
%26 = load i8*, i8** %25
%27 = getelementptr inbounds i8, i8* %26, i64 0
%28 = load i8, i8* %27
%29 = sext i8 %28 to i32
%30 = icmp ne i32 %29, 46
br i1 %30, label %31, label %55
31: ; preds = %23
%32 = load %struct.dirent*, %struct.dirent** %5
%33 = getelementptr inbounds %struct.dirent, %struct.dirent* %32, i32 0, i32 1
%34 = load i8*, i8** %33
%35 = call i32 @chdir(i8* %34)
%36 = icmp eq i32 %35, -1
br i1 %36, label %37, label %42
37: ; preds = %31
%38 = load %struct.dirent*, %struct.dirent** %5
%39 = getelementptr inbounds %struct.dirent, %struct.dirent* %38, i32 0, i32 1
%40 = load i8*, i8** %39
%41 = call i32 @perror(i8* %40)
store i32 1, i32* %2
br label %115
42: ; preds = %31
%43 = load %struct.dirent*, %struct.dirent** %5
%44 = getelementptr inbounds %struct.dirent, %struct.dirent* %43, i32 0, i32 1
%45 = load i8*, i8** %44
%46 = call i32 @deleter(i8* %45)
%47 = icmp ne i32 %46, 0
br i1 %47, label %48, label %49
48: ; preds = %42
store i32 1, i32* %2
br label %115
49: ; preds = %42
%50 = call i32 @chdir(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
%51 = icmp eq i32 %50, -1
br i1 %51, label %52, label %54
52: ; preds = %49
%53 = call i32 @perror(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
store i32 1, i32* %2
br label %115
54: ; preds = %49
br label %99
55: ; preds = %23, %17
%56 = load %struct.dirent*, %struct.dirent** %5
%57 = getelementptr inbounds %struct.dirent, %struct.dirent* %56, i32 0, i32 0
%58 = load i64, i64* %57
%59 = load i64, i64* @DT_REG
%60 = icmp eq i64 %58, %59
br i1 %60, label %67, label %61
61: ; preds = %55
%62 = load %struct.dirent*, %struct.dirent** %5
%63 = getelementptr inbounds %struct.dirent, %struct.dirent* %62, i32 0, i32 0
%64 = load i64, i64* %63
%65 = load i64, i64* @DT_SOCK
%66 = icmp eq i64 %64, %65
br i1 %66, label %67, label %79
67: ; preds = %61, %55
%68 = load %struct.dirent*, %struct.dirent** %5
%69 = getelementptr inbounds %struct.dirent, %struct.dirent* %68, i32 0, i32 1
%70 = load i8*, i8** %69
%71 = call i32 @unlink(i8* %70)
%72 = icmp eq i32 %71, -1
br i1 %72, label %73, label %78
73: ; preds = %67
%74 = load %struct.dirent*, %struct.dirent** %5
%75 = getelementptr inbounds %struct.dirent, %struct.dirent* %74, i32 0, i32 1
%76 = load i8*, i8** %75
%77 = call i32 @perror(i8* %76)
store i32 1, i32* %2
br label %115
78: ; preds = %67
br label %98
79: ; preds = %61
%80 = load %struct.dirent*, %struct.dirent** %5
%81 = getelementptr inbounds %struct.dirent, %struct.dirent* %80, i32 0, i32 0
%82 = load i64, i64* %81
%83 = load i64, i64* @DT_SOCK
%84 = icmp eq i64 %82, %83
br i1 %84, label %85, label %97
85: ; preds = %79
%86 = load %struct.dirent*, %struct.dirent** %5
%87 = getelementptr inbounds %struct.dirent, %struct.dirent* %86, i32 0, i32 1
%88 = load i8*, i8** %87
%89 = call i32 @rmdir(i8* %88)
%90 = icmp eq i32 %89, -1
br i1 %90, label %91, label %96
91: ; preds = %85
%92 = load %struct.dirent*, %struct.dirent** %5
%93 = getelementptr inbounds %struct.dirent, %struct.dirent* %92, i32 0, i32 1
%94 = load i8*, i8** %93
%95 = call i32 @perror(i8* %94)
store i32 1, i32* %2
br label %115
96: ; preds = %85
br label %97
97: ; preds = %96, %79
br label %98
98: ; preds = %97, %78
br label %99
99: ; preds = %98, %54
br label %13
100: ; preds = %13
%101 = load i32*, i32** %4
%102 = call i32 @closedir(i32* %101)
%103 = call i32 @chdir(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
%104 = icmp eq i32 %103, -1
br i1 %104, label %105, label %107
105: ; preds = %100
%106 = call i32 @perror(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
store i32 1, i32* %2
br label %115
107: ; preds = %100
%108 = load i8*, i8** %3
%109 = call i32 @rmdir(i8* %108)
%110 = icmp eq i32 %109, -1
br i1 %110, label %111, label %114
111: ; preds = %107
%112 = load i8*, i8** %3
%113 = call i32 @perror(i8* %112)
store i32 1, i32* %2
br label %115
114: ; preds = %107
store i32 0, i32* %2
br label %115
115: ; preds = %114, %111, %105, %91, %73, %52, %48, %37, %9
%116 = load i32, i32* %2
ret i32 %116
}

LLVM IR (-O2):
%struct.dirent = type { i64, i8* }
@.str = [2 x i8] c".\00"
@DT_DIR = global i64 0
@.str.1 = [3 x i8] c"..\00"
@DT_REG = global i64 0
@DT_SOCK = global i64 0
define i32 @deleter(i8* nocapture %0) {
%2 = tail call i32* @opendir(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%3 = icmp eq i32* %2, null
br i1 %3, label %54, label %4
4: ; preds = %1
%5 = tail call %struct.dirent* @readdir(i32* %2)
%6 = icmp eq %struct.dirent* %5, null
br i1 %6, label %44, label %7
7: ; preds = %4, %41
%8 = phi %struct.dirent* [ %42, %41 ], [ %5, %4 ]
%9 = getelementptr inbounds %struct.dirent, %struct.dirent* %8, i64 0, i32 0
%10 = load i64, i64* %9
%11 = load i64, i64* @DT_DIR
%12 = icmp eq i64 %10, %11
br i1 %12, label %13, label %28
13: ; preds = %7
%14 = getelementptr inbounds %struct.dirent, %struct.dirent* %8, i64 0, i32 1
%15 = load i8*, i8** %14
%16 = load i8, i8* %15
%17 = icmp eq i8 %16, 46
br i1 %17, label %28, label %18
18: ; preds = %13
%19 = tail call i32 @chdir(i8* %15)
%20 = icmp eq i32 %19, -1
br i1 %20, label %51, label %21
21: ; preds = %18
%22 = load i8*, i8** %14
%23 = tail call i32 @deleter(i8* %22)
%24 = icmp eq i32 %23, 0
br i1 %24, label %25, label %57
25: ; preds = %21
%26 = tail call i32 @chdir(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
%27 = icmp eq i32 %26, -1
br i1 %27, label %54, label %41
28: ; preds = %13, %7
%29 = load i64, i64* @DT_REG
%30 = icmp eq i64 %10, %29
%31 = load i64, i64* @DT_SOCK
%32 = icmp eq i64 %10, %31
%33 = select i1 %30, i1 true, i1 %32
br i1 %33, label %34, label %41
34: ; preds = %28
%35 = getelementptr inbounds %struct.dirent, %struct.dirent* %8, i64 0, i32 1
%36 = load i8*, i8** %35
%37 = tail call i32 @unlink(i8* %36)
%38 = icmp eq i32 %37, -1
br i1 %38, label %39, label %41
39: ; preds = %34
%40 = getelementptr inbounds %struct.dirent, %struct.dirent* %8, i64 0, i32 1
br label %51
41: ; preds = %28, %34, %25
%42 = tail call %struct.dirent* @readdir(i32* %2)
%43 = icmp eq %struct.dirent* %42, null
br i1 %43, label %44, label %7
44: ; preds = %41, %4
%45 = tail call i32 @closedir(i32* %2)
%46 = tail call i32 @chdir(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
%47 = icmp eq i32 %46, -1
br i1 %47, label %54, label %48
48: ; preds = %44
%49 = tail call i32 @rmdir(i8* %0)
%50 = icmp eq i32 %49, -1
br i1 %50, label %54, label %57
51: ; preds = %18, %39
%52 = phi i8** [ %40, %39 ], [ %14, %18 ]
%53 = load i8*, i8** %52
br label %54
54: ; preds = %25, %51, %48, %44, %1
%55 = phi i8* [ %0, %1 ], [ getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0), %44 ], [ %0, %48 ], [ %53, %51 ], [ getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0), %25 ]
%56 = tail call i32 @perror(i8* %55)
br label %57
57: ; preds = %21, %54, %48
%58 = phi i32 [ 0, %48 ], [ 1, %54 ], [ 1, %21 ]
ret i32 %58
}