#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 OS_file_write(unsigned long, unsigned char *, int);
int write_file_header(unsigned long file_handle, unsigned long width,
                      unsigned long height) {
  unsigned char buf[(14 + 40)];
  unsigned long size_image;
  size_image = (((width * 3) + 3) & ~3) * height;
  *(unsigned short *)(buf) = 0x4D42;
  *(unsigned long *)(buf + 2) = (14 + 40) + size_image;
  *(unsigned short *)(buf + 6) = 0;
  *(unsigned short *)(buf + 8) = 0;
  *(unsigned long *)(buf + 10) = (14 + 40);
  *(unsigned long *)(buf + 14) = 40;
  *(long *)(buf + 18) = width;
  *(long *)(buf + 22) = height;
  *(unsigned short *)(buf + 26) = 1;
  *(unsigned short *)(buf + 28) = 24;
  *(unsigned long *)(buf + 30) = 0;
  *(unsigned long *)(buf + 34) = size_image;
  *(long *)(buf + 38) = 0;
  *(long *)(buf + 42) = 0;
  *(unsigned long *)(buf + 46) = 0;
  *(unsigned long *)(buf + 50) = 0;
  return OS_file_write(file_handle, buf, (14 + 40));
}


x86 assembly (clang, -O0):
<write_file_header>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
imul   $0x3,-0x10(%rbp),%rax
add    $0x3,%rax
and    $0xfffffffffffffffc,%rax
imul   -0x18(%rbp),%rax
mov    %rax,-0x58(%rbp)
movw   $0x4d42,-0x50(%rbp)
mov    -0x58(%rbp),%rax
add    $0x36,%rax
mov    %rax,-0x4e(%rbp)
movw   $0x0,-0x4a(%rbp)
movw   $0x0,-0x48(%rbp)
movq   $0x36,-0x46(%rbp)
movq   $0x28,-0x42(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x3e(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x3a(%rbp)
movw   $0x1,-0x36(%rbp)
movw   $0x18,-0x34(%rbp)
movq   $0x0,-0x32(%rbp)
mov    -0x58(%rbp),%rax
mov    %rax,-0x2e(%rbp)
movq   $0x0,-0x2a(%rbp)
movq   $0x0,-0x26(%rbp)
movq   $0x0,-0x22(%rbp)
movq   $0x0,-0x1e(%rbp)
mov    -0x8(%rbp),%rdi
lea    -0x50(%rbp),%rsi
mov    $0x36,%edx
call   1030 <OS_file_write@plt>
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<write_file_header>:
sub    $0x38,%rsp
lea    (%rsi,%rsi,2),%rax
add    $0x3,%rax
and    $0xfffffffffffffffc,%rax
imul   %rdx,%rax
movw   $0x4d42,(%rsp)
lea    0x36(%rax),%rcx
mov    %rcx,0x2(%rsp)
movl   $0x0,0x6(%rsp)
movq   $0x36,0xa(%rsp)
movq   $0x28,0xe(%rsp)
mov    %rsi,0x12(%rsp)
mov    %rdx,0x16(%rsp)
movl   $0x180001,0x1a(%rsp)
movq   $0x0,0x1e(%rsp)
mov    %rax,0x22(%rsp)
xorps  %xmm0,%xmm0
movups %xmm0,0x26(%rsp)
movl   $0x0,0x36(%rsp)
mov    %rsp,%rsi
mov    $0x36,%edx
call   1030 <OS_file_write@plt>
add    $0x38,%rsp
ret

LLVM IR (-O0):
define i32 @write_file_header(i64 %0, i64 %1, i64 %2) {
%4 = alloca i64
%5 = alloca i64
%6 = alloca i64
%7 = alloca [54 x i8]
%8 = alloca i64
store i64 %0, i64* %4
store i64 %1, i64* %5
store i64 %2, i64* %6
%9 = load i64, i64* %5
%10 = mul i64 %9, 3
%11 = add i64 %10, 3
%12 = and i64 %11, -4
%13 = load i64, i64* %6
%14 = mul i64 %12, %13
store i64 %14, i64* %8
%15 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%16 = bitcast i8* %15 to i16*
store i16 19778, i16* %16
%17 = load i64, i64* %8
%18 = add i64 54, %17
%19 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%20 = getelementptr inbounds i8, i8* %19, i64 2
%21 = bitcast i8* %20 to i64*
store i64 %18, i64* %21
%22 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%23 = getelementptr inbounds i8, i8* %22, i64 6
%24 = bitcast i8* %23 to i16*
store i16 0, i16* %24
%25 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%26 = getelementptr inbounds i8, i8* %25, i64 8
%27 = bitcast i8* %26 to i16*
store i16 0, i16* %27
%28 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%29 = getelementptr inbounds i8, i8* %28, i64 10
%30 = bitcast i8* %29 to i64*
store i64 54, i64* %30
%31 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%32 = getelementptr inbounds i8, i8* %31, i64 14
%33 = bitcast i8* %32 to i64*
store i64 40, i64* %33
%34 = load i64, i64* %5
%35 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%36 = getelementptr inbounds i8, i8* %35, i64 18
%37 = bitcast i8* %36 to i64*
store i64 %34, i64* %37
%38 = load i64, i64* %6
%39 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%40 = getelementptr inbounds i8, i8* %39, i64 22
%41 = bitcast i8* %40 to i64*
store i64 %38, i64* %41
%42 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%43 = getelementptr inbounds i8, i8* %42, i64 26
%44 = bitcast i8* %43 to i16*
store i16 1, i16* %44
%45 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%46 = getelementptr inbounds i8, i8* %45, i64 28
%47 = bitcast i8* %46 to i16*
store i16 24, i16* %47
%48 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%49 = getelementptr inbounds i8, i8* %48, i64 30
%50 = bitcast i8* %49 to i64*
store i64 0, i64* %50
%51 = load i64, i64* %8
%52 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%53 = getelementptr inbounds i8, i8* %52, i64 34
%54 = bitcast i8* %53 to i64*
store i64 %51, i64* %54
%55 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%56 = getelementptr inbounds i8, i8* %55, i64 38
%57 = bitcast i8* %56 to i64*
store i64 0, i64* %57
%58 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%59 = getelementptr inbounds i8, i8* %58, i64 42
%60 = bitcast i8* %59 to i64*
store i64 0, i64* %60
%61 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%62 = getelementptr inbounds i8, i8* %61, i64 46
%63 = bitcast i8* %62 to i64*
store i64 0, i64* %63
%64 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%65 = getelementptr inbounds i8, i8* %64, i64 50
%66 = bitcast i8* %65 to i64*
store i64 0, i64* %66
%67 = load i64, i64* %4
%68 = getelementptr inbounds [54 x i8], [54 x i8]* %7, i64 0, i64 0
%69 = call i32 @OS_file_write(i64 %67, i8* %68, i32 54)
ret i32 %69
}

LLVM IR (-O2):
define i32 @write_file_header(i64 %0, i64 %1, i64 %2) {
%4 = alloca [54 x i8]
%5 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 0
%6 = mul i64 %1, 3
%7 = add i64 %6, 3
%8 = and i64 %7, -4
%9 = mul i64 %8, %2
%10 = bitcast [54 x i8]* %4 to i16*
store i16 19778, i16* %10
%11 = add i64 %9, 54
%12 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 2
%13 = bitcast i8* %12 to i64*
store i64 %11, i64* %13
%14 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 6
%15 = bitcast i8* %14 to i16*
store i16 0, i16* %15
%16 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 8
%17 = bitcast i8* %16 to i16*
store i16 0, i16* %17
%18 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 10
%19 = bitcast i8* %18 to i64*
store i64 54, i64* %19
%20 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 14
%21 = bitcast i8* %20 to i64*
store i64 40, i64* %21
%22 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 18
%23 = bitcast i8* %22 to i64*
store i64 %1, i64* %23
%24 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 22
%25 = bitcast i8* %24 to i64*
store i64 %2, i64* %25
%26 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 26
%27 = bitcast i8* %26 to i16*
store i16 1, i16* %27
%28 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 28
%29 = bitcast i8* %28 to i16*
store i16 24, i16* %29
%30 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 30
%31 = bitcast i8* %30 to i64*
store i64 0, i64* %31
%32 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 34
%33 = bitcast i8* %32 to i64*
store i64 %9, i64* %33
%34 = getelementptr inbounds [54 x i8], [54 x i8]* %4, i64 0, i64 38
%35 = call i32 @OS_file_write(i64 %0, i8* %5, i32 54)
ret i32 %35
}