#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 obstack {
  int dummy;
};

/* Variables and functions */
int EOF;
int /*<<< orphan*/ flockfile(int /*<<< orphan*/);
int /*<<< orphan*/ funlockfile(int /*<<< orphan*/);
int getchar_unlocked();
int /*<<< orphan*/ obstack_1grow(struct obstack *, char);
char *obstack_finish(struct obstack *);
int obstack_object_size(struct obstack *);
int /*<<< orphan*/ stdin;
void dump_input(struct obstack *buffer, char **str, char **str_end) {
  int c;
  int size;
  flockfile(stdin);
  while (1) {
    c = getchar_unlocked();
    if (c == EOF)
      break;
    obstack_1grow(buffer, c);
  }
  funlockfile(stdin);
  obstack_1grow(buffer, '\0');
  size = obstack_object_size(buffer);
  *str = obstack_finish(buffer);
  *str_end = *str + size;
}


x86 assembly (clang, -O0):
<dump_input>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    0x2e6d(%rip),%rax
mov    (%rax),%edi
call   1060 <flockfile@plt>
mov    $0x0,%al
call   1050 <getchar_unlocked@plt>
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    0x2e4a(%rip),%rcx
cmp    (%rcx),%eax
jne    11a3 <dump_input+0x43>
jmp    11b7 <dump_input+0x57>
mov    -0x8(%rbp),%rdi
mov    -0x1c(%rbp),%eax
movsbl %al,%esi
call   1080 <obstack_1grow@plt>
jmp    1182 <dump_input+0x22>
mov    0x2e2a(%rip),%rax
mov    (%rax),%edi
call   1040 <funlockfile@plt>
mov    -0x8(%rbp),%rdi
xor    %esi,%esi
call   1080 <obstack_1grow@plt>
mov    -0x8(%rbp),%rdi
call   1030 <obstack_object_size@plt>
mov    %eax,-0x20(%rbp)
mov    -0x8(%rbp),%rdi
call   1070 <obstack_finish@plt>
mov    %rax,%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x10(%rbp),%rax
mov    (%rax),%rcx
movslq -0x20(%rbp),%rax
add    %rax,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<dump_input>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %rdx,%r14
mov    %rsi,%r15
mov    %rdi,%rbx
mov    0x2e70(%rip),%r12
mov    (%r12),%edi
call   1060 <flockfile@plt>
xor    %eax,%eax
call   1050 <getchar_unlocked@plt>
mov    0x2e51(%rip),%rbp
cmp    0x0(%rbp),%eax
je     11b7 <dump_input+0x57>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movsbl %al,%esi
mov    %rbx,%rdi
call   1080 <obstack_1grow@plt>
xor    %eax,%eax
call   1050 <getchar_unlocked@plt>
cmp    0x0(%rbp),%eax
jne    11a0 <dump_input+0x40>
mov    (%r12),%edi
call   1040 <funlockfile@plt>
mov    %rbx,%rdi
xor    %esi,%esi
call   1080 <obstack_1grow@plt>
mov    %rbx,%rdi
call   1030 <obstack_object_size@plt>
mov    %eax,%ebp
mov    %rbx,%rdi
call   1070 <obstack_finish@plt>
mov    %rax,(%r15)
movslq %ebp,%rcx
add    %rax,%rcx
mov    %rcx,(%r14)
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.obstack = type { i32 }
@stdin = global i32 0
@EOF = global i32 0
define void @dump_input(%struct.obstack* %0, i8** %1, i8** %2) {
%4 = alloca %struct.obstack*
%5 = alloca i8**
%6 = alloca i8**
%7 = alloca i32
%8 = alloca i32
store %struct.obstack* %0, %struct.obstack** %4
store i8** %1, i8*** %5
store i8** %2, i8*** %6
%9 = load i32, i32* @stdin
%10 = call i32 @flockfile(i32 %9)
br label %11
11: ; preds = %3, %17
%12 = call i32 (...) @getchar_unlocked()
store i32 %12, i32* %7
%13 = load i32, i32* %7
%14 = load i32, i32* @EOF
%15 = icmp eq i32 %13, %14
br i1 %15, label %16, label %17
16: ; preds = %11
br label %22
17: ; preds = %11
%18 = load %struct.obstack*, %struct.obstack** %4
%19 = load i32, i32* %7
%20 = trunc i32 %19 to i8
%21 = call i32 @obstack_1grow(%struct.obstack* %18, i8 signext %20)
br label %11
22: ; preds = %16
%23 = load i32, i32* @stdin
%24 = call i32 @funlockfile(i32 %23)
%25 = load %struct.obstack*, %struct.obstack** %4
%26 = call i32 @obstack_1grow(%struct.obstack* %25, i8 signext 0)
%27 = load %struct.obstack*, %struct.obstack** %4
%28 = call i32 @obstack_object_size(%struct.obstack* %27)
store i32 %28, i32* %8
%29 = load %struct.obstack*, %struct.obstack** %4
%30 = call i8* @obstack_finish(%struct.obstack* %29)
%31 = load i8**, i8*** %5
store i8* %30, i8** %31
%32 = load i8**, i8*** %5
%33 = load i8*, i8** %32
%34 = load i32, i32* %8
%35 = sext i32 %34 to i64
%36 = getelementptr inbounds i8, i8* %33, i64 %35
%37 = load i8**, i8*** %6
store i8* %36, i8** %37
ret void
}

LLVM IR (-O2):
%struct.obstack = type { i32 }
@stdin = global i32 0
@EOF = global i32 0
define void @dump_input(%struct.obstack* %0, i8** nocapture writeonly %1, i8** nocapture writeonly %2) {
%4 = load i32, i32* @stdin
%5 = tail call i32 @flockfile(i32 %4)
%6 = tail call i32 (...) @getchar_unlocked()
%7 = load i32, i32* @EOF
%8 = icmp eq i32 %6, %7
br i1 %8, label %16, label %9
9: ; preds = %3, %9
%10 = phi i32 [ %13, %9 ], [ %6, %3 ]
%11 = trunc i32 %10 to i8
%12 = tail call i32 @obstack_1grow(%struct.obstack* %0, i8 signext %11)
%13 = tail call i32 (...) @getchar_unlocked()
%14 = load i32, i32* @EOF
%15 = icmp eq i32 %13, %14
br i1 %15, label %16, label %9
16: ; preds = %9, %3
%17 = load i32, i32* @stdin
%18 = tail call i32 @funlockfile(i32 %17)
%19 = tail call i32 @obstack_1grow(%struct.obstack* %0, i8 signext 0)
%20 = tail call i32 @obstack_object_size(%struct.obstack* %0)
%21 = tail call i8* @obstack_finish(%struct.obstack* %0)
store i8* %21, i8** %1
%22 = sext i32 %20 to i64
%23 = getelementptr inbounds i8, i8* %21, i64 %22
store i8* %23, i8** %2
ret void
}