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

/* Variables and functions */
scalar_t__ DT_DIR;
int closedir(int /*<<< orphan*/ *);
int errno;
int /*<<< orphan*/ *opendir(char *);
scalar_t__ readdir_r(int /*<<< orphan*/ *, struct dirent *, struct dirent **);
int rmdir(char *);
int /*<<< orphan*/ strcat(char *, char *);
scalar_t__ strcmp(char *, char *);
int /*<<< orphan*/ strcpy(char *, char *);
int strlen(char *);
int unlink(char *);
int remove_recursive(char *path) {
  char tmp[4096];
  DIR *dp;
  struct dirent entry, *result;
  errno = 0;
  if ((dp = opendir(path)) == NULL) {
    return errno;
  }
  while (readdir_r(dp, &entry, &result) == 0 && result) {
    if (strcmp(entry.d_name, ".") == 0 || strcmp(entry.d_name, "..") == 0)
      continue;
    strcpy(tmp, path);
    if (*(tmp + strlen(tmp) - 1) != '/')
      strcat(tmp, "/");
    strcat(tmp, entry.d_name);
    if (entry.d_type == DT_DIR) {
      remove_recursive(tmp);
      errno = 0;
      if (rmdir(tmp) == -1)
        return errno;
    } else {
      errno = 0;
      if (unlink(tmp) == -1)
        return errno;
    }
  }
  while (closedir(dp) == -1)
    ;
  return 0;
}


x86 assembly (clang, -O0):
<remove_recursive>:
push   %rbp
mov    %rsp,%rbp
sub    $0x1040,%rsp
mov    %rdi,-0x10(%rbp)
mov    0x2e22(%rip),%rax
movl   $0x0,(%rax)
mov    -0x10(%rbp),%rdi
call   1060 <opendir@plt>
mov    %rax,-0x1018(%rbp)
cmp    $0x0,%rax
jne    11e7 <remove_recursive+0x47>
mov    0x2dfb(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x4(%rbp)
jmp    1391 <remove_recursive+0x1f1>
jmp    11ec <remove_recursive+0x4c>
mov    -0x1018(%rbp),%rdi
lea    -0x1028(%rbp),%rsi
lea    -0x1030(%rbp),%rdx
call   1050 <readdir_r@plt>
mov    %rax,%rcx
xor    %eax,%eax
cmp    $0x0,%rcx
mov    %al,-0x1031(%rbp)
jne    122c <remove_recursive+0x8c>
cmpq   $0x0,-0x1030(%rbp)
setne  %al
mov    %al,-0x1031(%rbp)
mov    -0x1031(%rbp),%al
test   $0x1,%al
jne    123f <remove_recursive+0x9f>
jmp    136b <remove_recursive+0x1cb>
mov    -0x1028(%rbp),%rdi
lea    0xdb4(%rip),%rsi
call   10a0 <strcmp@plt>
cmp    $0x0,%rax
je     1279 <remove_recursive+0xd9>
mov    -0x1028(%rbp),%rdi
lea    0xd96(%rip),%rsi
call   10a0 <strcmp@plt>
cmp    $0x0,%rax
jne    127e <remove_recursive+0xde>
jmp    11ec <remove_recursive+0x4c>
lea    -0x1010(%rbp),%rdi
mov    -0x10(%rbp),%rsi
call   1040 <strcpy@plt>
lea    -0x1010(%rbp),%rdi
call   1080 <strlen@plt>
cltq
movsbl -0x1011(%rbp,%rax,1),%eax
ff
cmp    $0x2f,%eax
je     12c0 <remove_recursive+0x120>
lea    -0x1010(%rbp),%rdi
lea    0xd48(%rip),%rsi
call   10b0 <strcat@plt>
lea    -0x1010(%rbp),%rdi
mov    -0x1028(%rbp),%rsi
call   10b0 <strcat@plt>
mov    -0x1020(%rbp),%rax
mov    0x2cff(%rip),%rcx
cmp    (%rcx),%rax
jne    132e <remove_recursive+0x18e>
lea    -0x1010(%rbp),%rdi
call   10c0 <remove_recursive@plt>
mov    0x2cdb(%rip),%rax
movl   $0x0,(%rax)
lea    -0x1010(%rbp),%rdi
call   1070 <rmdir@plt>
cmp    $0xffffffff,%eax
jne    1329 <remove_recursive+0x189>
mov    0x2cb9(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x4(%rbp)
jmp    1391 <remove_recursive+0x1f1>
jmp    1366 <remove_recursive+0x1c6>
mov    0x2ca3(%rip),%rax
movl   $0x0,(%rax)
lea    -0x1010(%rbp),%rdi
call   1030 <unlink@plt>
cmp    $0xffffffff,%eax
jne    1361 <remove_recursive+0x1c1>
mov    0x2c81(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x4(%rbp)
jmp    1391 <remove_recursive+0x1f1>
jmp    1366 <remove_recursive+0x1c6>
jmp    11ec <remove_recursive+0x4c>
jmp    1370 <remove_recursive+0x1d0>
mov    -0x1018(%rbp),%rdi
call   1090 <closedir@plt>
cmp    $0xffffffff,%eax
jne    138a <remove_recursive+0x1ea>
jmp    1370 <remove_recursive+0x1d0>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x1040,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<remove_recursive>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x1028,%rsp
mov    %rdi,%r14
mov    0x2e1d(%rip),%rbp
movl   $0x0,0x0(%rbp)
call   1060 <opendir@plt>
test   %rax,%rax
je     1301 <remove_recursive+0x161>
mov    %rax,%rbx
lea    0x10(%rsp),%rsi
lea    0x8(%rsp),%rdx
mov    %rax,%rdi
call   1050 <readdir_r@plt>
test   %rax,%rax
jne    12f0 <remove_recursive+0x150>
cmpq   $0x0,0x8(%rsp)
je     12f0 <remove_recursive+0x150>
lea    0xe00(%rip),%r15
lea    0x10(%rsp),%r12
lea    0x8(%rsp),%r13
lea    0x20(%rsp),%rbp
mov    0x10(%rsp),%rdi
mov    %r15,%rsi
call   10a0 <strcmp@plt>
test   %rax,%rax
je     12c2 <remove_recursive+0x122>
mov    0x10(%rsp),%rdi
lea    0xdce(%rip),%rsi
call   10a0 <strcmp@plt>
test   %rax,%rax
je     12c2 <remove_recursive+0x122>
mov    %rbp,%rdi
mov    %r14,%rsi
call   1040 <strcpy@plt>
mov    %rbp,%rdi
call   1080 <strlen@plt>
cltq
cmpb   $0x2f,0x1f(%rsp,%rax,1)
je     126b <remove_recursive+0xcb>
mov    %rbp,%rdi
lea    0xd9d(%rip),%rsi
call   10b0 <strcat@plt>
mov    0x10(%rsp),%rsi
mov    %rbp,%rdi
call   10b0 <strcat@plt>
mov    0x18(%rsp),%rax
mov    0x2d5c(%rip),%rcx
cmp    (%rcx),%rax
jne    12a8 <remove_recursive+0x108>
mov    %rbp,%rdi
call   10c0 <remove_recursive@plt>
mov    0x2d40(%rip),%rax
movl   $0x0,(%rax)
mov    %rbp,%rdi
call   1070 <rmdir@plt>
jmp    12bd <remove_recursive+0x11d>
mov    0x2d29(%rip),%rax
movl   $0x0,(%rax)
mov    %rbp,%rdi
call   1030 <unlink@plt>
cmp    $0xffffffff,%eax
je     1306 <remove_recursive+0x166>
mov    %rbx,%rdi
mov    %r12,%rsi
mov    %r13,%rdx
call   1050 <readdir_r@plt>
test   %rax,%rax
jne    12f0 <remove_recursive+0x150>
cmpq   $0x0,0x8(%rsp)
jne    1210 <remove_recursive+0x70>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    %rbx,%rdi
call   1090 <closedir@plt>
cmp    $0xffffffff,%eax
je     12f0 <remove_recursive+0x150>
xor    %eax,%eax
jmp    130f <remove_recursive+0x16f>
mov    0x0(%rbp),%eax
jmp    130f <remove_recursive+0x16f>
mov    0x2ccb(%rip),%rax
mov    (%rax),%eax
add    $0x1028,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.dirent = type { i8*, i64 }
@errno = global i32 0
@.str = [2 x i8] c".\00"
@.str.1 = [3 x i8] c"..\00"
@.str.2 = [2 x i8] c"/\00"
@DT_DIR = global i64 0
define i32 @remove_recursive(i8* %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca [4096 x i8]
%5 = alloca i32*
%6 = alloca %struct.dirent
%7 = alloca %struct.dirent*
store i8* %0, i8** %3
store i32 0, i32* @errno
%8 = load i8*, i8** %3
%9 = call i32* @opendir(i8* %8)
store i32* %9, i32** %5
%10 = icmp eq i32* %9, null
br i1 %10, label %11, label %13
11: ; preds = %1
%12 = load i32, i32* @errno
store i32 %12, i32* %2
br label %83
13: ; preds = %1
br label %14
14: ; preds = %75, %33, %13
%15 = load i32*, i32** %5
%16 = call i64 @readdir_r(i32* %15, %struct.dirent* %6, %struct.dirent** %7)
%17 = icmp eq i64 %16, 0
br i1 %17, label %18, label %21
18: ; preds = %14
%19 = load %struct.dirent*, %struct.dirent** %7
%20 = icmp ne %struct.dirent* %19, null
br label %21
21: ; preds = %18, %14
%22 = phi i1 [ false, %14 ], [ %20, %18 ]
br i1 %22, label %23, label %76
23: ; preds = %21
%24 = getelementptr inbounds %struct.dirent, %struct.dirent* %6, i32 0, i32 0
%25 = load i8*, i8** %24
%26 = call i64 @strcmp(i8* %25, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%27 = icmp eq i64 %26, 0
br i1 %27, label %33, label %28
28: ; preds = %23
%29 = getelementptr inbounds %struct.dirent, %struct.dirent* %6, i32 0, i32 0
%30 = load i8*, i8** %29
%31 = call i64 @strcmp(i8* %30, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
%32 = icmp eq i64 %31, 0
br i1 %32, label %33, label %34
33: ; preds = %28, %23
br label %14
34: ; preds = %28
%35 = getelementptr inbounds [4096 x i8], [4096 x i8]* %4, i64 0, i64 0
%36 = load i8*, i8** %3
%37 = call i32 @strcpy(i8* %35, i8* %36)
%38 = getelementptr inbounds [4096 x i8], [4096 x i8]* %4, i64 0, i64 0
%39 = getelementptr inbounds [4096 x i8], [4096 x i8]* %4, i64 0, i64 0
%40 = call i32 @strlen(i8* %39)
%41 = sext i32 %40 to i64
%42 = getelementptr inbounds i8, i8* %38, i64 %41
%43 = getelementptr inbounds i8, i8* %42, i64 -1
%44 = load i8, i8* %43
%45 = sext i8 %44 to i32
%46 = icmp ne i32 %45, 47
br i1 %46, label %47, label %50
47: ; preds = %34
%48 = getelementptr inbounds [4096 x i8], [4096 x i8]* %4, i64 0, i64 0
%49 = call i32 @strcat(i8* %48, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.2, i64 0, i64 0))
br label %50
50: ; preds = %47, %34
%51 = getelementptr inbounds [4096 x i8], [4096 x i8]* %4, i64 0, i64 0
%52 = getelementptr inbounds %struct.dirent, %struct.dirent* %6, i32 0, i32 0
%53 = load i8*, i8** %52
%54 = call i32 @strcat(i8* %51, i8* %53)
%55 = getelementptr inbounds %struct.dirent, %struct.dirent* %6, i32 0, i32 1
%56 = load i64, i64* %55
%57 = load i64, i64* @DT_DIR
%58 = icmp eq i64 %56, %57
br i1 %58, label %59, label %68
59: ; preds = %50
%60 = getelementptr inbounds [4096 x i8], [4096 x i8]* %4, i64 0, i64 0
%61 = call i32 @remove_recursive(i8* %60)
store i32 0, i32* @errno
%62 = getelementptr inbounds [4096 x i8], [4096 x i8]* %4, i64 0, i64 0
%63 = call i32 @rmdir(i8* %62)
%64 = icmp eq i32 %63, -1
br i1 %64, label %65, label %67
65: ; preds = %59
%66 = load i32, i32* @errno
store i32 %66, i32* %2
br label %83
67: ; preds = %59
br label %75
68: ; preds = %50
store i32 0, i32* @errno
%69 = getelementptr inbounds [4096 x i8], [4096 x i8]* %4, i64 0, i64 0
%70 = call i32 @unlink(i8* %69)
%71 = icmp eq i32 %70, -1
br i1 %71, label %72, label %74
72: ; preds = %68
%73 = load i32, i32* @errno
store i32 %73, i32* %2
br label %83
74: ; preds = %68
br label %75
75: ; preds = %74, %67
br label %14
76: ; preds = %21
br label %77
77: ; preds = %81, %76
%78 = load i32*, i32** %5
%79 = call i32 @closedir(i32* %78)
%80 = icmp eq i32 %79, -1
br i1 %80, label %81, label %82
81: ; preds = %77
br label %77
82: ; preds = %77
store i32 0, i32* %2
br label %83
83: ; preds = %82, %72, %65, %11
%84 = load i32, i32* %2
ret i32 %84
}

LLVM IR (-O2):
%struct.dirent = type { i8*, i64 }
@errno = global i32 0
@.str = [2 x i8] c".\00"
@.str.1 = [3 x i8] c"..\00"
@.str.2 = [2 x i8] c"/\00"
@DT_DIR = global i64 0
define i32 @remove_recursive(i8* %0) {
%2 = alloca [4096 x i8]
%3 = alloca %struct.dirent
%4 = alloca %struct.dirent*
%5 = getelementptr inbounds [4096 x i8], [4096 x i8]* %2, i64 0, i64 0
%6 = bitcast %struct.dirent* %3 to i8*
%7 = bitcast %struct.dirent** %4 to i8*
store i32 0, i32* @errno
%8 = tail call i32* @opendir(i8* %0)
%9 = icmp eq i32* %8, null
br i1 %9, label %20, label %10
10: ; preds = %1
%11 = call i64 @readdir_r(i32* %8, %struct.dirent* %3, %struct.dirent** %4)
%12 = icmp eq i64 %11, 0
%13 = load %struct.dirent*, %struct.dirent** %4
%14 = icmp ne %struct.dirent* %13, null
%15 = select i1 %12, i1 %14, i1 false
br i1 %15, label %17, label %16
16: ; preds = %30, %10
br label %63
17: ; preds = %10
%18 = getelementptr inbounds %struct.dirent, %struct.dirent* %3, i64 0, i32 0
%19 = getelementptr inbounds %struct.dirent, %struct.dirent* %3, i64 0, i32 1
br label %22
20: ; preds = %1
%21 = load i32, i32* @errno
br label %66
22: ; preds = %17, %30
%23 = load i8*, i8** %18
%24 = call i64 @strcmp(i8* %23, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%25 = icmp eq i64 %24, 0
br i1 %25, label %30, label %26
26: ; preds = %22
%27 = load i8*, i8** %18
%28 = call i64 @strcmp(i8* %27, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
%29 = icmp eq i64 %28, 0
br i1 %29, label %30, label %36
30: ; preds = %52, %58, %22, %26
%31 = call i64 @readdir_r(i32* %8, %struct.dirent* %3, %struct.dirent** %4)
%32 = icmp eq i64 %31, 0
%33 = load %struct.dirent*, %struct.dirent** %4
%34 = icmp ne %struct.dirent* %33, null
%35 = select i1 %32, i1 %34, i1 false
br i1 %35, label %22, label %16
36: ; preds = %26
%37 = call i32 @strcpy(i8* %5, i8* %0)
%38 = call i32 @strlen(i8* %5)
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds [4096 x i8], [4096 x i8]* %2, i64 0, i64 %39
%41 = getelementptr inbounds i8, i8* %40, i64 -1
%42 = load i8, i8* %41
%43 = icmp eq i8 %42, 47
br i1 %43, label %46, label %44
44: ; preds = %36
%45 = call i32 @strcat(i8* %5, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.2, i64 0, i64 0))
br label %46
46: ; preds = %44, %36
%47 = load i8*, i8** %18
%48 = call i32 @strcat(i8* %5, i8* %47)
%49 = load i64, i64* %19
%50 = load i64, i64* @DT_DIR
%51 = icmp eq i64 %49, %50
br i1 %51, label %52, label %58
52: ; preds = %46
%53 = call i32 @remove_recursive(i8* %5)
store i32 0, i32* @errno
%54 = call i32 @rmdir(i8* %5)
%55 = icmp eq i32 %54, -1
br i1 %55, label %56, label %30
56: ; preds = %52
%57 = load i32, i32* @errno
br label %66
58: ; preds = %46
store i32 0, i32* @errno
%59 = call i32 @unlink(i8* %5)
%60 = icmp eq i32 %59, -1
br i1 %60, label %61, label %30
61: ; preds = %58
%62 = load i32, i32* @errno
br label %66
63: ; preds = %16, %63
%64 = call i32 @closedir(i32* %8)
%65 = icmp eq i32 %64, -1
br i1 %65, label %63, label %66
66: ; preds = %63, %61, %56, %20
%67 = phi i32 [ %21, %20 ], [ %57, %56 ], [ %62, %61 ], [ 0, %63 ]
ret i32 %67
}