#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 /*<<< orphan*/ ENOMEM;
int /*<<< orphan*/ errno;
char *_sbrk(int adj) {
  extern char end;
  static char *heap = &end;
  char *rv = heap;
  char *heaptop = (char *)&adj;
  heap += adj;
  if (rv < heaptop && heap > heaptop || heap < rv) {
    errno = ENOMEM;
    return (char *)-1;
  }
  return rv;
}


x86 assembly (clang, -O0):
<_sbrk>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0xc(%rbp)
mov    0x2f12(%rip),%rax
mov    %rax,-0x18(%rbp)
lea    -0xc(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0xc(%rbp),%ecx
mov    0x2efc(%rip),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,0x2eef(%rip)
mov    -0x18(%rbp),%rax
cmp    -0x20(%rbp),%rax
jae    1150 <_sbrk+0x50>
mov    0x2eda(%rip),%rax
cmp    -0x20(%rbp),%rax
ja     1161 <_sbrk+0x61>
mov    0x2ec9(%rip),%rax
cmp    -0x18(%rbp),%rax
jae    1183 <_sbrk+0x83>
mov    0x2e78(%rip),%rax
mov    (%rax),%ecx
mov    0x2e67(%rip),%rax
mov    %ecx,(%rax)
mov    $0xffffffffffffffff,%rax
mov    %rax,-0x8(%rbp)
jmp    118b <_sbrk+0x8b>
mov    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<_sbrk>:
mov    %edi,-0x4(%rsp)
mov    0x2f15(%rip),%rax
movslq %edi,%rsi
lea    (%rax,%rsi,1),%rdx
mov    %rdx,0x2f07(%rip)
lea    -0x4(%rsp),%rdi
cmp    %rdi,%rax
setb   %cl
cmp    %rdi,%rdx
seta   %dl
test   %esi,%esi
js     1133 <_sbrk+0x33>
and    %dl,%cl
jne    1133 <_sbrk+0x33>
ret
mov    0x2ea6(%rip),%rax
mov    (%rax),%eax
mov    0x2e95(%rip),%rcx
mov    %eax,(%rcx)
mov    $0xffffffffffffffff,%rax
ret

LLVM IR (-O0):
@_sbrk.heap = internal global i8* @end
@end = external global i8
@ENOMEM = global i32 0
@errno = global i32 0
define i8* @_sbrk(i32 %0) {
%2 = alloca i8*
%3 = alloca i32
%4 = alloca i8*
%5 = alloca i8*
store i32 %0, i32* %3
%6 = load i8*, i8** @_sbrk.heap
store i8* %6, i8** %4
%7 = bitcast i32* %3 to i8*
store i8* %7, i8** %5
%8 = load i32, i32* %3
%9 = load i8*, i8** @_sbrk.heap
%10 = sext i32 %8 to i64
%11 = getelementptr inbounds i8, i8* %9, i64 %10
store i8* %11, i8** @_sbrk.heap
%12 = load i8*, i8** %4
%13 = load i8*, i8** %5
%14 = icmp ult i8* %12, %13
br i1 %14, label %15, label %19
15: ; preds = %1
%16 = load i8*, i8** @_sbrk.heap
%17 = load i8*, i8** %5
%18 = icmp ugt i8* %16, %17
br i1 %18, label %23, label %19
19: ; preds = %15, %1
%20 = load i8*, i8** @_sbrk.heap
%21 = load i8*, i8** %4
%22 = icmp ult i8* %20, %21
br i1 %22, label %23, label %25
23: ; preds = %19, %15
%24 = load i32, i32* @ENOMEM
store i32 %24, i32* @errno
store i8* inttoptr (i64 -1 to i8*), i8** %2
br label %27
25: ; preds = %19
%26 = load i8*, i8** %4
store i8* %26, i8** %2
br label %27
27: ; preds = %25, %23
%28 = load i8*, i8** %2
ret i8* %28
}

LLVM IR (-O2):
@_sbrk.heap = internal unnamed_addr global i8* @end
@end = external global i8
@ENOMEM = global i32 0
@errno = global i32 0
define i8* @_sbrk(i32 %0) {
%2 = alloca i32
store i32 %0, i32* %2
%3 = load i8*, i8** @_sbrk.heap
%4 = bitcast i32* %2 to i8*
%5 = sext i32 %0 to i64
%6 = getelementptr inbounds i8, i8* %3, i64 %5
store i8* %6, i8** @_sbrk.heap
%7 = icmp ult i8* %3, %4
%8 = icmp ugt i8* %6, %4
%9 = select i1 %7, i1 %8, i1 false
%10 = icmp slt i32 %0, 0
%11 = or i1 %10, %9
br i1 %11, label %12, label %14
12: ; preds = %1
%13 = load i32, i32* @ENOMEM
store i32 %13, i32* @errno
br label %14
14: ; preds = %1, %12
%15 = phi i8* [ inttoptr (i64 -1 to i8*), %12 ], [ %3, %1 ]
ret i8* %15
}