#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 {
  size_t st_size;
};
struct fb_var_screeninfo {
  size_t yres_virtual;
  size_t line_length;
};
struct fb_fix_screeninfo {
  size_t yres_virtual;
  size_t line_length;
};

/* Variables and functions */
int /*<<< orphan*/ FBIOGET_FSCREENINFO;
int /*<<< orphan*/ FBIOGET_VSCREENINFO;
char *MAP_FAILED;
int /*<<< orphan*/ MAP_SHARED;
int /*<<< orphan*/ O_RDONLY;
int /*<<< orphan*/ O_RDWR;
int PROT_READ;
int PROT_WRITE;
int /*<<< orphan*/ close(int);
scalar_t__ fstat(int, struct stat *);
scalar_t__ ioctl(int, int /*<<< orphan*/, struct fb_var_screeninfo *);
int /*<<< orphan*/ memmove(char *, char *, int);
int /*<<< orphan*/ memset(char *, int /*<<< orphan*/, size_t);
char *mmap(int /*<<< orphan*/ *, size_t, int, int /*<<< orphan*/, int,
           int /*<<< orphan*/);
int /*<<< orphan*/ munmap(char *, size_t);
int open(char const *, int /*<<< orphan*/);
int /*<<< orphan*/ perror(char *);
int bmp_draw(const char *path, int left, int top, int fbclear) {
  int filefd = -1;
  int fbfd = -1;
  char *filemap = NULL;
  char *fbmap = NULL;
  size_t fblen;
  struct fb_var_screeninfo screen_info;
  struct fb_fix_screeninfo fixed_info;
  struct stat st;
  int y;
  filefd = open(path, O_RDONLY);
  if (filefd == -1) {
    perror("open failed");
    goto cleanup;
  }
  if (fstat(filefd, &st) < 0) {
    perror("fstat failed");
    goto cleanup;
  }
  filemap = mmap(0, st.st_size, PROT_READ, MAP_SHARED, filefd, 0);
  if (filemap == MAP_FAILED) {
    close(filefd);
    perror("file mmap failed");
    goto cleanup;
  }
  fbfd = open("/dev/fb0", O_RDWR);
  if (fbfd < 0) {
    perror("fb open failed");
    goto cleanup;
  }
  if (ioctl(fbfd, FBIOGET_VSCREENINFO, &screen_info) ||
      ioctl(fbfd, FBIOGET_FSCREENINFO, &fixed_info)) {
    perror("fb info failed");
    goto cleanup;
  }
  fblen = screen_info.yres_virtual * fixed_info.line_length;
  fbmap = mmap(NULL, fblen, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
  if (fbmap == MAP_FAILED) {
    perror("fb mmap failed");
    goto cleanup;
  }
  if (fbclear) {
    memset(fbmap, 0, fblen);
  }
  for (y = 0; y < 128; y++) {
    memmove(fbmap + left * 4 + (top + y) * fixed_info.line_length,
            filemap + st.st_size - (y + 1) * (128 * 4), (128 * 4));
  }
cleanup:
  if (fbmap && fbmap != MAP_FAILED)
    munmap(fbmap, fblen);
  if (fbfd >= 0)
    close(fbfd);
  if (filemap && filemap != MAP_FAILED)
    munmap(filemap, st.st_size);
  if (filefd >= 0)
    close(filefd);
  return 0;
}


x86 assembly (clang, -O0):
<bmp_draw>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
movl   $0xffffffff,-0x18(%rbp)
movl   $0xffffffff,-0x1c(%rbp)
movq   $0x0,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
mov    -0x8(%rbp),%rdi
mov    0x2e02(%rip),%rax
mov    (%rax),%esi
call   1090 <open@plt>
mov    %eax,-0x18(%rbp)
cmpl   $0xffffffff,-0x18(%rbp)
jne    11f3 <bmp_draw+0x63>
lea    0xe41(%rip),%rdi
call   10a0 <perror@plt>
jmp    13dd <bmp_draw+0x24d>
mov    -0x18(%rbp),%edi
lea    -0x60(%rbp),%rsi
call   10b0 <fstat@plt>
cmp    $0x0,%rax
jge    121a <bmp_draw+0x8a>
lea    0xdf0(%rip),%rdi
call   10a0 <perror@plt>
jmp    13dd <bmp_draw+0x24d>
mov    -0x60(%rbp),%rsi
mov    0x2dd3(%rip),%rax
mov    (%rax),%edx
mov    0x2dba(%rip),%rax
mov    (%rax),%ecx
mov    -0x18(%rbp),%r8d
xor    %eax,%eax
mov    %eax,%edi
xor    %r9d,%r9d
call   1030 <mmap@plt>
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
mov    0x2d59(%rip),%rcx
cmp    (%rcx),%rax
jne    1271 <bmp_draw+0xe1>
mov    -0x18(%rbp),%edi
call   1060 <close@plt>
lea    0xda6(%rip),%rdi
call   10a0 <perror@plt>
jmp    13dd <bmp_draw+0x24d>
mov    0x2d60(%rip),%rax
mov    (%rax),%esi
lea    0xd9d(%rip),%rdi
call   1090 <open@plt>
mov    %eax,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jge    12a4 <bmp_draw+0x114>
lea    0xd8d(%rip),%rdi
call   10a0 <perror@plt>
jmp    13dd <bmp_draw+0x24d>
mov    -0x1c(%rbp),%edi
mov    0x2d02(%rip),%rax
mov    (%rax),%esi
lea    -0x48(%rbp),%rdx
call   1050 <ioctl@plt>
cmp    $0x0,%rax
jne    12e2 <bmp_draw+0x152>
mov    -0x1c(%rbp),%edi
mov    0x2cf3(%rip),%rax
mov    (%rax),%esi
lea    -0x58(%rbp),%rdx
call   1050 <ioctl@plt>
cmp    $0x0,%rax
je     12f3 <bmp_draw+0x163>
lea    0xd4d(%rip),%rdi
call   10a0 <perror@plt>
jmp    13dd <bmp_draw+0x24d>
mov    -0x48(%rbp),%rax
imul   -0x50(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x38(%rbp),%rsi
mov    0x2ced(%rip),%rax
mov    (%rax),%edx
mov    0x2ca4(%rip),%rax
or     (%rax),%edx
mov    0x2ccb(%rip),%rax
mov    (%rax),%ecx
mov    -0x1c(%rbp),%r8d
xor    %eax,%eax
mov    %eax,%edi
xor    %r9d,%r9d
call   1030 <mmap@plt>
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
mov    0x2c6a(%rip),%rcx
cmp    (%rcx),%rax
jne    1358 <bmp_draw+0x1c8>
lea    0xcf7(%rip),%rdi
call   10a0 <perror@plt>
jmp    13dd <bmp_draw+0x24d>
cmpl   $0x0,-0x14(%rbp)
je     1371 <bmp_draw+0x1e1>
mov    -0x30(%rbp),%rdi
mov    -0x38(%rbp),%rdx
xor    %esi,%esi
call   1040 <memset@plt>
movl   $0x0,-0x64(%rbp)
cmpl   $0x80,-0x64(%rbp)
jge    13d8 <bmp_draw+0x248>
mov    -0x30(%rbp),%rdi
mov    -0xc(%rbp),%eax
shl    $0x2,%eax
cltq
add    %rax,%rdi
mov    -0x10(%rbp),%eax
add    -0x64(%rbp),%eax
cltq
imul   -0x50(%rbp),%rax
add    %rax,%rdi
mov    -0x28(%rbp),%rsi
add    -0x60(%rbp),%rsi
mov    -0x64(%rbp),%eax
add    $0x1,%eax
shl    $0x9,%eax
movslq %eax,%rcx
xor    %eax,%eax
sub    %rcx,%rax
add    %rax,%rsi
mov    $0x200,%edx
call   1080 <memmove@plt>
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    1378 <bmp_draw+0x1e8>
jmp    13dd <bmp_draw+0x24d>
cmpq   $0x0,-0x30(%rbp)
je     1409 <bmp_draw+0x279>
mov    -0x30(%rbp),%rax
mov    0x2bb5(%rip),%rcx
cmp    (%rcx),%rax
je     1409 <bmp_draw+0x279>
mov    -0x30(%rbp),%rdi
mov    -0x38(%rbp),%rsi
call   1070 <munmap@plt>
cmpl   $0x0,-0x1c(%rbp)
jl     141b <bmp_draw+0x28b>
mov    -0x1c(%rbp),%edi
call   1060 <close@plt>
cmpq   $0x0,-0x28(%rbp)
je     1447 <bmp_draw+0x2b7>
mov    -0x28(%rbp),%rax
mov    0x2b77(%rip),%rcx
cmp    (%rcx),%rax
je     1447 <bmp_draw+0x2b7>
mov    -0x28(%rbp),%rdi
mov    -0x60(%rbp),%rsi
call   1070 <munmap@plt>
cmpl   $0x0,-0x18(%rbp)
jl     1459 <bmp_draw+0x2c9>
mov    -0x18(%rbp),%edi
call   1060 <close@plt>
xor    %eax,%eax
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<bmp_draw>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x48,%rsp
mov    %ecx,%ebp
mov    %edx,%r14d
mov    %esi,%r15d
mov    0x2e23(%rip),%rax
mov    (%rax),%esi
call   1090 <open@plt>
cmp    $0xffffffff,%eax
je     13a5 <bmp_draw+0x215>
mov    %eax,%ebx
lea    0x20(%rsp),%rsi
mov    %eax,%edi
call   10b0 <fstat@plt>
test   %rax,%rax
js     13b3 <bmp_draw+0x223>
mov    %ebp,0xc(%rsp)
mov    0x20(%rsp),%r12
mov    0x2e14(%rip),%rax
mov    (%rax),%edx
mov    0x2dfb(%rip),%rax
mov    (%rax),%ecx
xor    %edi,%edi
mov    %r12,%rsi
mov    %ebx,%r8d
xor    %r9d,%r9d
call   1030 <mmap@plt>
mov    %rax,%rbp
mov    0x2d9f(%rip),%r13
cmp    0x0(%r13),%rax
je     13c5 <bmp_draw+0x235>
mov    %r14d,0x8(%rsp)
mov    0x2db9(%rip),%rax
mov    (%rax),%esi
lea    0xdf6(%rip),%rdi
call   1090 <open@plt>
test   %eax,%eax
js     13da <bmp_draw+0x24a>
mov    %eax,%r14d
mov    0x2d71(%rip),%rax
mov    (%rax),%esi
lea    0x38(%rsp),%rdx
mov    %r14d,%edi
call   1050 <ioctl@plt>
test   %rax,%rax
jne    1394 <bmp_draw+0x204>
mov    0x2d62(%rip),%rax
mov    (%rax),%esi
lea    0x28(%rsp),%rdx
mov    %r14d,%edi
call   1050 <ioctl@plt>
test   %rax,%rax
jne    1394 <bmp_draw+0x204>
mov    0x30(%rsp),%rsi
imul   0x38(%rsp),%rsi
mov    0x2d30(%rip),%rax
mov    (%rax),%edx
mov    0x2d67(%rip),%rax
or     (%rax),%edx
mov    0x2d4e(%rip),%rax
mov    (%rax),%ecx
xor    %edi,%edi
mov    %rsi,0x10(%rsp)
mov    %r14d,(%rsp)
mov    %r14d,%r8d
xor    %r9d,%r9d
call   1030 <mmap@plt>
mov    %rax,%r14
cmp    0x0(%r13),%rax
mov    %ebx,0x4(%rsp)
mov    %r12,0x18(%rsp)
je     13eb <bmp_draw+0x25b>
cmpl   $0x0,0xc(%rsp)
je     12de <bmp_draw+0x14e>
mov    %r14,%rdi
xor    %esi,%esi
mov    0x10(%rsp),%rdx
call   1040 <memset@plt>
shl    $0x2,%r15d
movslq %r15d,%r15
add    %r14,%r15
movslq 0x8(%rsp),%r13
lea    (%r12,%rbp,1),%rbx
add    $0xfffffffffffffe00,%rbx
xor    %r12d,%r12d
nopl   0x0(%rax,%rax,1)
lea    (%r12,%r13,1),%rdi
imul   0x30(%rsp),%rdi
add    %r15,%rdi
add    $0x1,%r12
mov    %rbx,%rsi
mov    $0x200,%edx
call   1080 <memmove@plt>
add    $0xfffffffffffffe00,%rbx
cmp    $0x80,%r12
jne    1300 <bmp_draw+0x170>
test   %r14,%r14
mov    0x2c70(%rip),%r13
je     134d <bmp_draw+0x1bd>
cmp    0x0(%r13),%r14
je     134d <bmp_draw+0x1bd>
mov    %r14,%rdi
mov    0x10(%rsp),%rsi
call   1070 <munmap@plt>
mov    (%rsp),%edi
test   %edi,%edi
mov    0x4(%rsp),%ebx
mov    0x18(%rsp),%r12
js     1362 <bmp_draw+0x1d2>
call   1060 <close@plt>
test   %rbp,%rbp
je     1378 <bmp_draw+0x1e8>
cmp    0x0(%r13),%rbp
je     1378 <bmp_draw+0x1e8>
mov    %rbp,%rdi
mov    %r12,%rsi
call   1070 <munmap@plt>
test   %ebx,%ebx
js     1383 <bmp_draw+0x1f3>
mov    %ebx,%edi
call   1060 <close@plt>
xor    %eax,%eax
add    $0x48,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
lea    0xc9b(%rip),%rdi
call   10a0 <perror@plt>
mov    %r14d,%edi
jmp    135d <bmp_draw+0x1cd>
lea    0xc7e(%rip),%rdi
call   10a0 <perror@plt>
jmp    1383 <bmp_draw+0x1f3>
lea    0xc46(%rip),%rdi
call   10a0 <perror@plt>
test   %ebx,%ebx
jns    137c <bmp_draw+0x1ec>
jmp    1383 <bmp_draw+0x1f3>
mov    %ebx,%edi
call   1060 <close@plt>
lea    0xc3a(%rip),%rdi
call   10a0 <perror@plt>
jmp    1362 <bmp_draw+0x1d2>
lea    0xc46(%rip),%rdi
call   10a0 <perror@plt>
jmp    1362 <bmp_draw+0x1d2>
lea    0xc53(%rip),%rdi
call   10a0 <perror@plt>
jmp    132e <bmp_draw+0x19e>

LLVM IR (-O0):
%struct.fb_var_screeninfo = type { i64, i64 }
%struct.fb_fix_screeninfo = type { i64, i64 }
%struct.stat = type { i64 }
@O_RDONLY = global i32 0
@.str = [12 x i8] c"open failed\00"
@.str.1 = [13 x i8] c"fstat failed\00"
@PROT_READ = global i32 0
@MAP_SHARED = global i32 0
@MAP_FAILED = global i8* null
@.str.2 = [17 x i8] c"file mmap failed\00"
@.str.3 = [9 x i8] c"/dev/fb0\00"
@O_RDWR = global i32 0
@.str.4 = [15 x i8] c"fb open failed\00"
@FBIOGET_VSCREENINFO = global i32 0
@FBIOGET_FSCREENINFO = global i32 0
@.str.5 = [15 x i8] c"fb info failed\00"
@PROT_WRITE = global i32 0
@.str.6 = [15 x i8] c"fb mmap failed\00"
define i32 @bmp_draw(i8* %0, i32 %1, i32 %2, i32 %3) {
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i8*
%12 = alloca i8*
%13 = alloca i64
%14 = alloca %struct.fb_var_screeninfo
%15 = alloca %struct.fb_fix_screeninfo
%16 = alloca %struct.stat
%17 = alloca i32
store i8* %0, i8** %5
store i32 %1, i32* %6
store i32 %2, i32* %7
store i32 %3, i32* %8
store i32 -1, i32* %9
store i32 -1, i32* %10
store i8* null, i8** %11
store i8* null, i8** %12
%18 = load i8*, i8** %5
%19 = load i32, i32* @O_RDONLY
%20 = call i32 @open(i8* %18, i32 %19)
store i32 %20, i32* %9
%21 = load i32, i32* %9
%22 = icmp eq i32 %21, -1
br i1 %22, label %23, label %25
23: ; preds = %4
%24 = call i32 @perror(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i64 0, i64 0))
br label %123
25: ; preds = %4
%26 = load i32, i32* %9
%27 = call i64 @fstat(i32 %26, %struct.stat* %16)
%28 = icmp slt i64 %27, 0
br i1 %28, label %29, label %31
29: ; preds = %25
%30 = call i32 @perror(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i64 0, i64 0))
br label %123
31: ; preds = %25
%32 = getelementptr inbounds %struct.stat, %struct.stat* %16, i32 0, i32 0
%33 = load i64, i64* %32
%34 = load i32, i32* @PROT_READ
%35 = load i32, i32* @MAP_SHARED
%36 = load i32, i32* %9
%37 = call i8* @mmap(i32* null, i64 %33, i32 %34, i32 %35, i32 %36, i32 0)
store i8* %37, i8** %11
%38 = load i8*, i8** %11
%39 = load i8*, i8** @MAP_FAILED
%40 = icmp eq i8* %38, %39
br i1 %40, label %41, label %45
41: ; preds = %31
%42 = load i32, i32* %9
%43 = call i32 @close(i32 %42)
%44 = call i32 @perror(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.2, i64 0, i64 0))
br label %123
45: ; preds = %31
%46 = load i32, i32* @O_RDWR
%47 = call i32 @open(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.3, i64 0, i64 0), i32 %46)
store i32 %47, i32* %10
%48 = load i32, i32* %10
%49 = icmp slt i32 %48, 0
br i1 %49, label %50, label %52
50: ; preds = %45
%51 = call i32 @perror(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.4, i64 0, i64 0))
br label %123
52: ; preds = %45
%53 = load i32, i32* %10
%54 = load i32, i32* @FBIOGET_VSCREENINFO
%55 = call i64 @ioctl(i32 %53, i32 %54, %struct.fb_var_screeninfo* %14)
%56 = icmp ne i64 %55, 0
br i1 %56, label %63, label %57
57: ; preds = %52
%58 = load i32, i32* %10
%59 = load i32, i32* @FBIOGET_FSCREENINFO
%60 = bitcast %struct.fb_fix_screeninfo* %15 to %struct.fb_var_screeninfo*
%61 = call i64 @ioctl(i32 %58, i32 %59, %struct.fb_var_screeninfo* %60)
%62 = icmp ne i64 %61, 0
br i1 %62, label %63, label %65
63: ; preds = %57, %52
%64 = call i32 @perror(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.5, i64 0, i64 0))
br label %123
65: ; preds = %57
%66 = getelementptr inbounds %struct.fb_var_screeninfo, %struct.fb_var_screeninfo* %14, i32 0, i32 0
%67 = load i64, i64* %66
%68 = getelementptr inbounds %struct.fb_fix_screeninfo, %struct.fb_fix_screeninfo* %15, i32 0, i32 1
%69 = load i64, i64* %68
%70 = mul i64 %67, %69
store i64 %70, i64* %13
%71 = load i64, i64* %13
%72 = load i32, i32* @PROT_READ
%73 = load i32, i32* @PROT_WRITE
%74 = or i32 %72, %73
%75 = load i32, i32* @MAP_SHARED
%76 = load i32, i32* %10
%77 = call i8* @mmap(i32* null, i64 %71, i32 %74, i32 %75, i32 %76, i32 0)
store i8* %77, i8** %12
%78 = load i8*, i8** %12
%79 = load i8*, i8** @MAP_FAILED
%80 = icmp eq i8* %78, %79
br i1 %80, label %81, label %83
81: ; preds = %65
%82 = call i32 @perror(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.6, i64 0, i64 0))
br label %123
83: ; preds = %65
%84 = load i32, i32* %8
%85 = icmp ne i32 %84, 0
br i1 %85, label %86, label %90
86: ; preds = %83
%87 = load i8*, i8** %12
%88 = load i64, i64* %13
%89 = call i32 @memset(i8* %87, i32 0, i64 %88)
br label %90
90: ; preds = %86, %83
store i32 0, i32* %17
br label %91
91: ; preds = %119, %90
%92 = load i32, i32* %17
%93 = icmp slt i32 %92, 128
br i1 %93, label %94, label %122
94: ; preds = %91
%95 = load i8*, i8** %12
%96 = load i32, i32* %6
%97 = mul nsw i32 %96, 4
%98 = sext i32 %97 to i64
%99 = getelementptr inbounds i8, i8* %95, i64 %98
%100 = load i32, i32* %7
%101 = load i32, i32* %17
%102 = add nsw i32 %100, %101
%103 = sext i32 %102 to i64
%104 = getelementptr inbounds %struct.fb_fix_screeninfo, %struct.fb_fix_screeninfo* %15, i32 0, i32 1
%105 = load i64, i64* %104
%106 = mul i64 %103, %105
%107 = getelementptr inbounds i8, i8* %99, i64 %106
%108 = load i8*, i8** %11
%109 = getelementptr inbounds %struct.stat, %struct.stat* %16, i32 0, i32 0
%110 = load i64, i64* %109
%111 = getelementptr inbounds i8, i8* %108, i64 %110
%112 = load i32, i32* %17
%113 = add nsw i32 %112, 1
%114 = mul nsw i32 %113, 512
%115 = sext i32 %114 to i64
%116 = sub i64 0, %115
%117 = getelementptr inbounds i8, i8* %111, i64 %116
%118 = call i32 @memmove(i8* %107, i8* %117, i32 512)
br label %119
119: ; preds = %94
%120 = load i32, i32* %17
%121 = add nsw i32 %120, 1
store i32 %121, i32* %17
br label %91
122: ; preds = %91
br label %123
123: ; preds = %122, %81, %63, %50, %41, %29, %23
%124 = load i8*, i8** %12
%125 = icmp ne i8* %124, null
br i1 %125, label %126, label %134
126: ; preds = %123
%127 = load i8*, i8** %12
%128 = load i8*, i8** @MAP_FAILED
%129 = icmp ne i8* %127, %128
br i1 %129, label %130, label %134
130: ; preds = %126
%131 = load i8*, i8** %12
%132 = load i64, i64* %13
%133 = call i32 @munmap(i8* %131, i64 %132)
br label %134
134: ; preds = %130, %126, %123
%135 = load i32, i32* %10
%136 = icmp sge i32 %135, 0
br i1 %136, label %137, label %140
137: ; preds = %134
%138 = load i32, i32* %10
%139 = call i32 @close(i32 %138)
br label %140
140: ; preds = %137, %134
%141 = load i8*, i8** %11
%142 = icmp ne i8* %141, null
br i1 %142, label %143, label %152
143: ; preds = %140
%144 = load i8*, i8** %11
%145 = load i8*, i8** @MAP_FAILED
%146 = icmp ne i8* %144, %145
br i1 %146, label %147, label %152
147: ; preds = %143
%148 = load i8*, i8** %11
%149 = getelementptr inbounds %struct.stat, %struct.stat* %16, i32 0, i32 0
%150 = load i64, i64* %149
%151 = call i32 @munmap(i8* %148, i64 %150)
br label %152
152: ; preds = %147, %143, %140
%153 = load i32, i32* %9
%154 = icmp sge i32 %153, 0
br i1 %154, label %155, label %158
155: ; preds = %152
%156 = load i32, i32* %9
%157 = call i32 @close(i32 %156)
br label %158
158: ; preds = %155, %152
ret i32 0
}

LLVM IR (-O2):
%struct.fb_var_screeninfo = type { i64, i64 }
%struct.fb_fix_screeninfo = type { i64, i64 }
%struct.stat = type { i64 }
@O_RDONLY = global i32 0
@.str = [12 x i8] c"open failed\00"
@.str.1 = [13 x i8] c"fstat failed\00"
@PROT_READ = global i32 0
@MAP_SHARED = global i32 0
@MAP_FAILED = global i8* null
@.str.2 = [17 x i8] c"file mmap failed\00"
@.str.3 = [9 x i8] c"/dev/fb0\00"
@O_RDWR = global i32 0
@.str.4 = [15 x i8] c"fb open failed\00"
@FBIOGET_VSCREENINFO = global i32 0
@FBIOGET_FSCREENINFO = global i32 0
@.str.5 = [15 x i8] c"fb info failed\00"
@PROT_WRITE = global i32 0
@.str.6 = [15 x i8] c"fb mmap failed\00"
define i32 @bmp_draw(i8* nocapture %0, i32 %1, i32 %2, i32 %3) {
%5 = alloca %struct.fb_var_screeninfo
%6 = alloca %struct.fb_fix_screeninfo
%7 = alloca %struct.stat
%8 = bitcast %struct.fb_var_screeninfo* %5 to i8*
%9 = bitcast %struct.fb_fix_screeninfo* %6 to i8*
%10 = bitcast %struct.stat* %7 to i8*
%11 = load i32, i32* @O_RDONLY
%12 = tail call i32 @open(i8* %0, i32 %11)
%13 = icmp eq i32 %12, -1
br i1 %13, label %14, label %16
14: ; preds = %4
%15 = tail call i32 @perror(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i64 0, i64 0))
br label %108
16: ; preds = %4
%17 = call i64 @fstat(i32 %12, %struct.stat* %7)
%18 = icmp slt i64 %17, 0
br i1 %18, label %19, label %21
19: ; preds = %16
%20 = tail call i32 @perror(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i64 0, i64 0))
br label %104
21: ; preds = %16
%22 = getelementptr inbounds %struct.stat, %struct.stat* %7, i64 0, i32 0
%23 = load i64, i64* %22
%24 = load i32, i32* @PROT_READ
%25 = load i32, i32* @MAP_SHARED
%26 = tail call i8* @mmap(i32* null, i64 %23, i32 %24, i32 %25, i32 %12, i32 0)
%27 = load i8*, i8** @MAP_FAILED
%28 = icmp eq i8* %26, %27
br i1 %28, label %29, label %32
29: ; preds = %21
%30 = tail call i32 @close(i32 %12)
%31 = tail call i32 @perror(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.2, i64 0, i64 0))
br label %97
32: ; preds = %21
%33 = load i32, i32* @O_RDWR
%34 = tail call i32 @open(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.3, i64 0, i64 0), i32 %33)
%35 = icmp slt i32 %34, 0
br i1 %35, label %36, label %38
36: ; preds = %32
%37 = tail call i32 @perror(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.4, i64 0, i64 0))
br label %97
38: ; preds = %32
%39 = load i32, i32* @FBIOGET_VSCREENINFO
%40 = call i64 @ioctl(i32 %34, i32 %39, %struct.fb_var_screeninfo* %5)
%41 = icmp eq i64 %40, 0
br i1 %41, label %42, label %47
42: ; preds = %38
%43 = load i32, i32* @FBIOGET_FSCREENINFO
%44 = bitcast %struct.fb_fix_screeninfo* %6 to %struct.fb_var_screeninfo*
%45 = call i64 @ioctl(i32 %34, i32 %43, %struct.fb_var_screeninfo* %44)
%46 = icmp eq i64 %45, 0
br i1 %46, label %49, label %47
47: ; preds = %38, %42
%48 = call i32 @perror(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.5, i64 0, i64 0))
br label %95
49: ; preds = %42
%50 = getelementptr inbounds %struct.fb_var_screeninfo, %struct.fb_var_screeninfo* %5, i64 0, i32 0
%51 = load i64, i64* %50
%52 = getelementptr inbounds %struct.fb_fix_screeninfo, %struct.fb_fix_screeninfo* %6, i64 0, i32 1
%53 = load i64, i64* %52
%54 = mul i64 %53, %51
%55 = load i32, i32* @PROT_READ
%56 = load i32, i32* @PROT_WRITE
%57 = or i32 %56, %55
%58 = load i32, i32* @MAP_SHARED
%59 = call i8* @mmap(i32* null, i64 %54, i32 %57, i32 %58, i32 %34, i32 0)
%60 = load i8*, i8** @MAP_FAILED
%61 = icmp eq i8* %59, %60
br i1 %61, label %62, label %64
62: ; preds = %49
%63 = call i32 @perror(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.6, i64 0, i64 0))
br label %86
64: ; preds = %49
%65 = icmp eq i32 %3, 0
br i1 %65, label %68, label %66
66: ; preds = %64
%67 = call i32 @memset(i8* %59, i32 0, i64 %54)
br label %68
68: ; preds = %66, %64
%69 = shl nsw i32 %1, 2
%70 = sext i32 %69 to i64
%71 = getelementptr inbounds i8, i8* %59, i64 %70
%72 = getelementptr inbounds i8, i8* %26, i64 %23
%73 = sext i32 %2 to i64
br label %74
74: ; preds = %68, %74
%75 = phi i64 [ 0, %68 ], [ %81, %74 ]
%76 = add nsw i64 %75, %73
%77 = load i64, i64* %52
%78 = mul i64 %77, %76
%79 = getelementptr inbounds i8, i8* %71, i64 %78
%80 = xor i64 %75, -1
%81 = add nuw nsw i64 %75, 1
%82 = shl i64 %80, 9
%83 = getelementptr inbounds i8, i8* %72, i64 %82
%84 = call i32 @memmove(i8* %79, i8* %83, i32 512)
%85 = icmp eq i64 %81, 128
br i1 %85, label %86, label %74
86: ; preds = %74, %62
%87 = icmp eq i8* %59, null
%88 = load i8*, i8** @MAP_FAILED
%89 = icmp eq i8* %59, %88
%90 = select i1 %87, i1 true, i1 %89
br i1 %90, label %93, label %91
91: ; preds = %86
%92 = call i32 @munmap(i8* %59, i64 %54)
br label %93
93: ; preds = %91, %86
%94 = icmp sgt i32 %34, -1
br i1 %94, label %95, label %97
95: ; preds = %47, %93
%96 = call i32 @close(i32 %34)
br label %97
97: ; preds = %29, %36, %95, %93
%98 = icmp eq i8* %26, null
%99 = load i8*, i8** @MAP_FAILED
%100 = icmp eq i8* %26, %99
%101 = select i1 %98, i1 true, i1 %100
br i1 %101, label %104, label %102
102: ; preds = %97
%103 = call i32 @munmap(i8* %26, i64 %23)
br label %104
104: ; preds = %19, %102, %97
%105 = icmp sgt i32 %12, -1
br i1 %105, label %106, label %108
106: ; preds = %104
%107 = call i32 @close(i32 %12)
br label %108
108: ; preds = %14, %106, %104
ret i32 0
}