#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 evbuffer {
  int dummy;
};
struct bufferevent {
  int dummy;
};
typedef int /*<<< orphan*/ buf;

/* Variables and functions */
struct evbuffer *bufferevent_get_input(struct bufferevent *);
struct evbuffer *bufferevent_get_output(struct bufferevent *);
int /*<<< orphan*/ evbuffer_add(struct evbuffer *, char *, int);
int evbuffer_remove(struct evbuffer *, unsigned char *, int);
void readcb(struct bufferevent *bev, void *ptr) {
  int *i = ptr;
  struct evbuffer *input = bufferevent_get_input(bev);
  struct evbuffer *output = bufferevent_get_output(bev);
  unsigned char buf[10];
  int len = evbuffer_remove(input, buf, sizeof(buf) - 1);
  if (len < 0)
    return;
  buf[len] = '\0';
  evbuffer_add(output, "loop", 4);
}


x86 assembly (clang, -O0):
<readcb>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
call   1050 <bufferevent_get_input@plt>
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%rdi
call   1040 <bufferevent_get_output@plt>
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rdi
lea    -0x32(%rbp),%rsi
mov    $0x9,%edx
call   1030 <evbuffer_remove@plt>
mov    %eax,-0x38(%rbp)
cmpl   $0x0,-0x38(%rbp)
jge    1196 <readcb+0x56>
jmp    11b4 <readcb+0x74>
movslq -0x38(%rbp),%rax
movb   $0x0,-0x32(%rbp,%rax,1)
mov    -0x28(%rbp),%rdi
lea    0xe56(%rip),%rsi
mov    $0x4,%edx
call   1060 <evbuffer_add@plt>
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<readcb>:
push   %r14
push   %rbx
sub    $0x18,%rsp
mov    %rdi,%rbx
call   1050 <bufferevent_get_input@plt>
mov    %rax,%r14
mov    %rbx,%rdi
call   1040 <bufferevent_get_output@plt>
mov    %rax,%rbx
lea    0xe(%rsp),%rsi
mov    %r14,%rdi
mov    $0x9,%edx
call   1030 <evbuffer_remove@plt>
test   %eax,%eax
js     118e <readcb+0x4e>
mov    %eax,%eax
movb   $0x0,0xe(%rsp,%rax,1)
lea    0xe7f(%rip),%rsi
mov    %rbx,%rdi
mov    $0x4,%edx
call   1060 <evbuffer_add@plt>
add    $0x18,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
%struct.bufferevent = type { i32 }
%struct.evbuffer = type { i32 }
@.str = [5 x i8] c"loop\00"
define void @readcb(%struct.bufferevent* %0, i8* %1) {
%3 = alloca %struct.bufferevent*
%4 = alloca i8*
%5 = alloca i32*
%6 = alloca %struct.evbuffer*
%7 = alloca %struct.evbuffer*
%8 = alloca [10 x i8]
%9 = alloca i32
store %struct.bufferevent* %0, %struct.bufferevent** %3
store i8* %1, i8** %4
%10 = load i8*, i8** %4
%11 = bitcast i8* %10 to i32*
store i32* %11, i32** %5
%12 = load %struct.bufferevent*, %struct.bufferevent** %3
%13 = call %struct.evbuffer* @bufferevent_get_input(%struct.bufferevent* %12)
store %struct.evbuffer* %13, %struct.evbuffer** %6
%14 = load %struct.bufferevent*, %struct.bufferevent** %3
%15 = call %struct.evbuffer* @bufferevent_get_output(%struct.bufferevent* %14)
store %struct.evbuffer* %15, %struct.evbuffer** %7
%16 = load %struct.evbuffer*, %struct.evbuffer** %6
%17 = getelementptr inbounds [10 x i8], [10 x i8]* %8, i64 0, i64 0
%18 = call i32 @evbuffer_remove(%struct.evbuffer* %16, i8* %17, i32 9)
store i32 %18, i32* %9
%19 = load i32, i32* %9
%20 = icmp slt i32 %19, 0
br i1 %20, label %21, label %22
21: ; preds = %2
br label %28
22: ; preds = %2
%23 = load i32, i32* %9
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds [10 x i8], [10 x i8]* %8, i64 0, i64 %24
store i8 0, i8* %25
%26 = load %struct.evbuffer*, %struct.evbuffer** %7
%27 = call i32 @evbuffer_add(%struct.evbuffer* %26, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i32 4)
br label %28
28: ; preds = %22, %21
ret void
}

LLVM IR (-O2):
%struct.bufferevent = type { i32 }
%struct.evbuffer = type { i32 }
@.str = [5 x i8] c"loop\00"
define void @readcb(%struct.bufferevent* %0, i8* nocapture readnone %1) {
%3 = alloca [10 x i8]
%4 = tail call %struct.evbuffer* @bufferevent_get_input(%struct.bufferevent* %0)
%5 = tail call %struct.evbuffer* @bufferevent_get_output(%struct.bufferevent* %0)
%6 = getelementptr inbounds [10 x i8], [10 x i8]* %3, i64 0, i64 0
%7 = call i32 @evbuffer_remove(%struct.evbuffer* %4, i8* %6, i32 9)
%8 = icmp slt i32 %7, 0
br i1 %8, label %13, label %9
9: ; preds = %2
%10 = zext i32 %7 to i64
%11 = getelementptr inbounds [10 x i8], [10 x i8]* %3, i64 0, i64 %10
store i8 0, i8* %11
%12 = call i32 @evbuffer_add(%struct.evbuffer* %5, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i32 4)
br label %13
13: ; preds = %2, %9
ret void
}