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

/* Variables and functions */
int /*<<< orphan*/ exit(int);
int /*<<< orphan*/ fclose(int /*<<< orphan*/ *);
int /*<<< orphan*/ *fopen(char *, char *);
int /*<<< orphan*/ fputs(char *, int /*<<< orphan*/ *);
int /*<<< orphan*/ fputws(char *, int /*<<< orphan*/ *);
int /*<<< orphan*/ *freopen(char *, char *, int /*<<< orphan*/ *);
int /*<<< orphan*/ mtrace();
int /*<<< orphan*/ puts(char *);
int main(int argc, char *argv[]) {
  FILE *fp;
  mtrace();
  if (argc < 2)
    exit(1);
  fp = fopen(argv[1], "w");
  if (fp == NULL) {
    puts("fopen failed: %m");
    exit(1);
  }
  fputs("Hello world (mb)\n", fp);
  fp = freopen(argv[1], "a+", fp);
  if (fp == NULL) {
    puts("freopen failed: %m");
    exit(1);
  }
  fputws(L"Hello world (wc)\n", fp);
  fclose(fp);
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    $0x0,%al
call   1090 <mtrace@plt>
cmpl   $0x2,-0x8(%rbp)
jge    11b1 <main+0x31>
mov    $0x1,%edi
call   10a0 <exit@plt>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
lea    0xe40(%rip),%rsi
call   1080 <fopen@plt>
mov    %rax,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    11ea <main+0x6a>
lea    0xe27(%rip),%rdi
call   1030 <puts@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
mov    -0x18(%rbp),%rsi
lea    0xe1e(%rip),%rdi
call   1050 <fputs@plt>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
mov    -0x18(%rbp),%rdx
lea    0xe18(%rip),%rsi
call   1060 <freopen@plt>
mov    %rax,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    1237 <main+0xb7>
lea    0xe00(%rip),%rdi
call   1030 <puts@plt>
mov    $0x1,%edi
call   10a0 <exit@plt>
mov    -0x18(%rbp),%rsi
lea    0xdfa(%rip),%rdi
call   1070 <fputws@plt>
mov    -0x18(%rbp),%rdi
call   1040 <fclose@plt>
xor    %eax,%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %r14
push   %rbx
push   %rax
mov    %rsi,%r14
mov    %edi,%ebx
xor    %eax,%eax
call   1080 <mtrace@plt>
cmp    $0x1,%ebx
jle    1202 <main+0x82>
mov    0x8(%r14),%rdi
lea    0xe60(%rip),%rsi
call   1070 <fopen@plt>
test   %rax,%rax
je     120c <main+0x8c>
mov    %rax,%rbx
lea    0xe5f(%rip),%rdi
mov    $0x11,%esi
mov    $0x1,%edx
mov    %rax,%rcx
call   10a0 <fwrite@plt>
mov    0x8(%r14),%rdi
lea    0xe54(%rip),%rsi
mov    %rbx,%rdx
call   1050 <freopen@plt>
test   %rax,%rax
je     1215 <main+0x95>
mov    %rax,%rbx
lea    0xe54(%rip),%rdi
mov    %rax,%rsi
call   1060 <fputws@plt>
mov    %rbx,%rdi
call   1040 <fclose@plt>
xor    %eax,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret
mov    $0x1,%edi
call   1090 <exit@plt>
lea    0xdef(%rip),%rdi
jmp    121c <main+0x9c>
lea    0xe0c(%rip),%rdi
call   1030 <puts@plt>
mov    $0x1,%edi
call   1090 <exit@plt>

LLVM IR (-O0):
@.str = [2 x i8] c"w\00"
@.str.1 = [17 x i8] c"fopen failed: %m\00"
@.str.2 = [18 x i8] c"Hello world (mb)\0A\00"
@.str.3 = [3 x i8] c"a+\00"
@.str.4 = [19 x i8] c"freopen failed: %m\00"
@.str.5 = [18 x i32] [i32 72, i32 101, i32 108, i32 108, i32 111, i32 32, i32 119, i32 111, i32 114, i32 108, i32 100, i32 32, i32 40, i32 119, i32 99, i32 41, i32 10, i32 0]
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca i32*
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%7 = call i32 (...) @mtrace()
%8 = load i32, i32* %4
%9 = icmp slt i32 %8, 2
br i1 %9, label %10, label %12
10: ; preds = %2
%11 = call i32 @exit(i32 1)
unreachable
12: ; preds = %2
%13 = load i8**, i8*** %5
%14 = getelementptr inbounds i8*, i8** %13, i64 1
%15 = load i8*, i8** %14
%16 = call i32* @fopen(i8* %15, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
store i32* %16, i32** %6
%17 = load i32*, i32** %6
%18 = icmp eq i32* %17, null
br i1 %18, label %19, label %22
19: ; preds = %12
%20 = call i32 @puts(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i64 0, i64 0))
%21 = call i32 @exit(i32 1)
unreachable
22: ; preds = %12
%23 = load i32*, i32** %6
%24 = call i32 @fputs(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.2, i64 0, i64 0), i32* %23)
%25 = load i8**, i8*** %5
%26 = getelementptr inbounds i8*, i8** %25, i64 1
%27 = load i8*, i8** %26
%28 = load i32*, i32** %6
%29 = call i32* @freopen(i8* %27, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i32* %28)
store i32* %29, i32** %6
%30 = load i32*, i32** %6
%31 = icmp eq i32* %30, null
br i1 %31, label %32, label %35
32: ; preds = %22
%33 = call i32 @puts(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.4, i64 0, i64 0))
%34 = call i32 @exit(i32 1)
unreachable
35: ; preds = %22
%36 = load i32*, i32** %6
%37 = call i32 @fputws(i8* bitcast ([18 x i32]* @.str.5 to i8*), i32* %36)
%38 = load i32*, i32** %6
%39 = call i32 @fclose(i32* %38)
ret i32 0
}

LLVM IR (-O2):
@.str = [2 x i8] c"w\00"
@.str.1 = [17 x i8] c"fopen failed: %m\00"
@.str.2 = [18 x i8] c"Hello world (mb)\0A\00"
@.str.3 = [3 x i8] c"a+\00"
@.str.4 = [19 x i8] c"freopen failed: %m\00"
@.str.5 = [18 x i32] [i32 72, i32 101, i32 108, i32 108, i32 111, i32 32, i32 119, i32 111, i32 114, i32 108, i32 100, i32 32, i32 40, i32 119, i32 99, i32 41, i32 10, i32 0]
define i32 @main(i32 %0, i8** nocapture %1) {
%3 = tail call i32 (...) @mtrace()
%4 = icmp slt i32 %0, 2
br i1 %4, label %5, label %7
5: ; preds = %2
%6 = tail call i32 @exit(i32 1)
unreachable
7: ; preds = %2
%8 = getelementptr inbounds i8*, i8** %1, i64 1
%9 = load i8*, i8** %8
%10 = tail call i32* @fopen(i8* %9, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%11 = icmp eq i32* %10, null
br i1 %11, label %12, label %15
12: ; preds = %7
%13 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i64 0, i64 0))
%14 = tail call i32 @exit(i32 1)
unreachable
15: ; preds = %7
%16 = tail call i64 @fwrite(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.2, i64 0, i64 0), i64 17, i64 1, i32* %10)
%17 = load i8*, i8** %8
%18 = tail call i32* @freopen(i8* %17, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i32* %10)
%19 = icmp eq i32* %18, null
br i1 %19, label %20, label %23
20: ; preds = %15
%21 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @.str.4, i64 0, i64 0))
%22 = tail call i32 @exit(i32 1)
unreachable
23: ; preds = %15
%24 = tail call i32 @fputws(i8* bitcast ([18 x i32]* @.str.5 to i8*), i32* %18)
%25 = tail call i32 @fclose(i32* %18)
ret i32 0
}