#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 zip {
  int dummy;
};
typedef int /*<<< orphan*/ FILE;

/* Variables and functions */
struct zip *_zip_allocate_new(char const *, unsigned int, int *);
int _zip_file_exists(char const *, unsigned int, int *);
struct zip *_zip_open(char const *, int /*<<< orphan*/ *, unsigned int, int *);
int /*<<< orphan*/ fclose(int /*<<< orphan*/ *);
int /*<<< orphan*/ *fopen(char const *, char *);
int /*<<< orphan*/ set_error(int *, int /*<<< orphan*/ *, int);
struct zip *zip_open(const char *fn, int _flags, int *zep) {
  FILE *fp;
  unsigned int flags;
  if (_flags < 0) {
    if (zep)
      *zep = 18;
    return NULL;
  }
  flags = (unsigned int)_flags;
  switch (_zip_file_exists(fn, flags, zep)) {
  case -1:
    return NULL;
  case 0:
    return _zip_allocate_new(fn, flags, zep);
  default:
    if (flags & 8) {
      FILE *f;
      if ((f = fopen(fn, "rb")) == NULL) {
        set_error(zep, NULL, 11);
        return NULL;
      }
      fclose(f);
      return _zip_allocate_new(fn, flags, zep);
    }
    break;
  }
  if ((fp = fopen(fn, "rb")) == NULL) {
    set_error(zep, NULL, 11);
    return NULL;
  }
  return _zip_open(fn, fp, flags, zep);
}


x86 assembly (clang, -O0):
<zip_open>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
cmpl   $0x0,-0x14(%rbp)
jge    119f <zip_open+0x3f>
cmpq   $0x0,-0x20(%rbp)
je     1192 <zip_open+0x32>
mov    -0x20(%rbp),%rax
movl   $0x12,(%rax)
movq   $0x0,-0x8(%rbp)
jmp    12c6 <zip_open+0x166>
mov    -0x14(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x10(%rbp),%rdi
mov    -0x2c(%rbp),%esi
mov    -0x20(%rbp),%rdx
call   1060 <_zip_file_exists@plt>
mov    %eax,%ecx
mov    %ecx,-0x3c(%rbp)
sub    $0xffffffff,%eax
je     11d8 <zip_open+0x78>
jmp    11c8 <zip_open+0x68>
mov    -0x3c(%rbp),%eax
test   %eax,%eax
je     11e5 <zip_open+0x85>
jmp    11fe <zip_open+0x9e>
movq   $0x0,-0x8(%rbp)
jmp    12c6 <zip_open+0x166>
mov    -0x10(%rbp),%rdi
mov    -0x2c(%rbp),%esi
mov    -0x20(%rbp),%rdx
call   1080 <_zip_allocate_new@plt>
mov    %rax,-0x8(%rbp)
jmp    12c6 <zip_open+0x166>
mov    -0x2c(%rbp),%eax
and    $0x8,%eax
cmp    $0x0,%eax
je     126c <zip_open+0x10c>
mov    -0x10(%rbp),%rdi
lea    0xde8(%rip),%rsi
call   1070 <fopen@plt>
mov    %rax,-0x38(%rbp)
cmp    $0x0,%rax
jne    124a <zip_open+0xea>
mov    -0x20(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%esi
mov    $0xb,%edx
call   1040 <set_error@plt>
movq   $0x0,-0x8(%rbp)
jmp    12c6 <zip_open+0x166>
mov    -0x38(%rbp),%rdi
call   1030 <fclose@plt>
mov    -0x10(%rbp),%rdi
mov    -0x2c(%rbp),%esi
mov    -0x20(%rbp),%rdx
call   1080 <_zip_allocate_new@plt>
mov    %rax,-0x8(%rbp)
jmp    12c6 <zip_open+0x166>
jmp    1271 <zip_open+0x111>
mov    -0x10(%rbp),%rdi
lea    0xd84(%rip),%rsi
call   1070 <fopen@plt>
mov    %rax,-0x28(%rbp)
cmp    $0x0,%rax
jne    12ae <zip_open+0x14e>
mov    -0x20(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%esi
mov    $0xb,%edx
call   1040 <set_error@plt>
movq   $0x0,-0x8(%rbp)
jmp    12c6 <zip_open+0x166>
mov    -0x10(%rbp),%rdi
mov    -0x28(%rbp),%rsi
mov    -0x2c(%rbp),%edx
mov    -0x20(%rbp),%rcx
call   1050 <_zip_open@plt>
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<zip_open>:
push   %rbp
push   %r14
push   %rbx
mov    %rdx,%r14
test   %esi,%esi
js     11af <zip_open+0x4f>
mov    %esi,%ebp
mov    %rdi,%rbx
mov    %r14,%rdx
call   1060 <_zip_file_exists@plt>
cmp    $0xffffffff,%eax
je     11ea <zip_open+0x8a>
test   %eax,%eax
je     11ca <zip_open+0x6a>
lea    0xe78(%rip),%rsi
mov    %rbx,%rdi
call   1070 <fopen@plt>
test   $0x8,%bpl
jne    11bd <zip_open+0x5d>
test   %rax,%rax
je     11db <zip_open+0x7b>
mov    %rbx,%rdi
mov    %rax,%rsi
mov    %ebp,%edx
mov    %r14,%rcx
pop    %rbx
pop    %r14
pop    %rbp
jmp    1050 <_zip_open@plt>
test   %r14,%r14
je     11ea <zip_open+0x8a>
movl   $0x12,(%r14)
jmp    11ea <zip_open+0x8a>
test   %rax,%rax
je     11db <zip_open+0x7b>
mov    %rax,%rdi
call   1030 <fclose@plt>
mov    %rbx,%rdi
mov    %ebp,%esi
mov    %r14,%rdx
pop    %rbx
pop    %r14
pop    %rbp
jmp    1080 <_zip_allocate_new@plt>
mov    %r14,%rdi
xor    %esi,%esi
mov    $0xb,%edx
call   1040 <set_error@plt>
xor    %eax,%eax
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
%struct.zip = type { i32 }
@.str = [3 x i8] c"rb\00"
define %struct.zip* @zip_open(i8* %0, i32 %1, i32* %2) {
%4 = alloca %struct.zip*
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32*
%8 = alloca i32*
%9 = alloca i32
%10 = alloca i32*
store i8* %0, i8** %5
store i32 %1, i32* %6
store i32* %2, i32** %7
%11 = load i32, i32* %6
%12 = icmp slt i32 %11, 0
br i1 %12, label %13, label %19
13: ; preds = %3
%14 = load i32*, i32** %7
%15 = icmp ne i32* %14, null
br i1 %15, label %16, label %18
16: ; preds = %13
%17 = load i32*, i32** %7
store i32 18, i32* %17
br label %18
18: ; preds = %16, %13
store %struct.zip* null, %struct.zip** %4
br label %63
19: ; preds = %3
%20 = load i32, i32* %6
store i32 %20, i32* %9
%21 = load i8*, i8** %5
%22 = load i32, i32* %9
%23 = load i32*, i32** %7
%24 = call i32 @_zip_file_exists(i8* %21, i32 %22, i32* %23)
switch i32 %24, label %31 [
i32 -1, label %25
i32 0, label %26
]
25: ; preds = %19
store %struct.zip* null, %struct.zip** %4
br label %63
26: ; preds = %19
%27 = load i8*, i8** %5
%28 = load i32, i32* %9
%29 = load i32*, i32** %7
%30 = call %struct.zip* @_zip_allocate_new(i8* %27, i32 %28, i32* %29)
store %struct.zip* %30, %struct.zip** %4
br label %63
31: ; preds = %19
%32 = load i32, i32* %9
%33 = and i32 %32, 8
%34 = icmp ne i32 %33, 0
br i1 %34, label %35, label %49
35: ; preds = %31
%36 = load i8*, i8** %5
%37 = call i32* @fopen(i8* %36, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0))
store i32* %37, i32** %10
%38 = icmp eq i32* %37, null
br i1 %38, label %39, label %42
39: ; preds = %35
%40 = load i32*, i32** %7
%41 = call i32 @set_error(i32* %40, i32* null, i32 11)
store %struct.zip* null, %struct.zip** %4
br label %63
42: ; preds = %35
%43 = load i32*, i32** %10
%44 = call i32 @fclose(i32* %43)
%45 = load i8*, i8** %5
%46 = load i32, i32* %9
%47 = load i32*, i32** %7
%48 = call %struct.zip* @_zip_allocate_new(i8* %45, i32 %46, i32* %47)
store %struct.zip* %48, %struct.zip** %4
br label %63
49: ; preds = %31
br label %50
50: ; preds = %49
%51 = load i8*, i8** %5
%52 = call i32* @fopen(i8* %51, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0))
store i32* %52, i32** %8
%53 = icmp eq i32* %52, null
br i1 %53, label %54, label %57
54: ; preds = %50
%55 = load i32*, i32** %7
%56 = call i32 @set_error(i32* %55, i32* null, i32 11)
store %struct.zip* null, %struct.zip** %4
br label %63
57: ; preds = %50
%58 = load i8*, i8** %5
%59 = load i32*, i32** %8
%60 = load i32, i32* %9
%61 = load i32*, i32** %7
%62 = call %struct.zip* @_zip_open(i8* %58, i32* %59, i32 %60, i32* %61)
store %struct.zip* %62, %struct.zip** %4
br label %63
63: ; preds = %57, %54, %42, %39, %26, %25, %18
%64 = load %struct.zip*, %struct.zip** %4
ret %struct.zip* %64
}

LLVM IR (-O2):
%struct.zip = type { i32 }
@.str = [3 x i8] c"rb\00"
define %struct.zip* @zip_open(i8* %0, i32 %1, i32* %2) {
%4 = icmp slt i32 %1, 0
br i1 %4, label %5, label %8
5: ; preds = %3
%6 = icmp eq i32* %2, null
br i1 %6, label %28, label %7
7: ; preds = %5
store i32 18, i32* %2
br label %28
8: ; preds = %3
%9 = tail call i32 @_zip_file_exists(i8* %0, i32 %1, i32* %2)
switch i32 %9, label %12 [
i32 -1, label %28
i32 0, label %10
]
10: ; preds = %8
%11 = tail call %struct.zip* @_zip_allocate_new(i8* %0, i32 %1, i32* %2)
br label %28
12: ; preds = %8
%13 = and i32 %1, 8
%14 = icmp eq i32 %13, 0
%15 = tail call i32* @fopen(i8* %0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0))
%16 = icmp eq i32* %15, null
br i1 %14, label %23, label %17
17: ; preds = %12
br i1 %16, label %18, label %20
18: ; preds = %17
%19 = tail call i32 @set_error(i32* %2, i32* null, i32 11)
br label %28
20: ; preds = %17
%21 = tail call i32 @fclose(i32* %15)
%22 = tail call %struct.zip* @_zip_allocate_new(i8* %0, i32 %1, i32* %2)
br label %28
23: ; preds = %12
br i1 %16, label %24, label %26
24: ; preds = %23
%25 = tail call i32 @set_error(i32* %2, i32* null, i32 11)
br label %28
26: ; preds = %23
%27 = tail call %struct.zip* @_zip_open(i8* %0, i32* %15, i32 %1, i32* %2)
br label %28
28: ; preds = %18, %20, %8, %5, %7, %26, %24, %10
%29 = phi %struct.zip* [ null, %24 ], [ %27, %26 ], [ %11, %10 ], [ null, %7 ], [ null, %5 ], [ null, %8 ], [ null, %18 ], [ %22, %20 ]
ret %struct.zip* %29
}