#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 char *off_t;

/* Variables and functions */
void copy(char **out, off_t offset, int length) {
  char *in = *out - offset;
  while (length-- >= 0) {
    *(++(*out)) = *(in++);
  }
}


x86 assembly (clang, -O0):
<copy>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%rax
mov    -0x10(%rbp),%rcx
sub    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x14(%rbp)
cmp    $0x0,%eax
jl     115f <copy+0x5f>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x20(%rbp)
mov    (%rax),%cl
mov    -0x8(%rbp),%rdx
mov    (%rdx),%rax
mov    %rax,%rsi
add    $0x1,%rsi
mov    %rsi,(%rdx)
mov    %cl,0x1(%rax)
jmp    1121 <copy+0x21>
pop    %rbp
ret

x86 assembly (clang, -O2):
<copy>:
test   %edx,%edx
js     114e <copy+0x4e>
mov    (%rdi),%rcx
mov    %rcx,%rax
sub    %rsi,%rax
mov    (%rax),%r8b
lea    0x1(%rcx),%rsi
mov    %rsi,(%rdi)
mov    %r8b,0x1(%rcx)
test   %edx,%edx
je     114e <copy+0x4e>
add    $0x1,%edx
add    $0x1,%rax
cs nopw 0x0(%rax,%rax,1)
mov    (%rdi),%rcx
movzbl (%rax),%r8d
lea    0x1(%rcx),%rsi
mov    %rsi,(%rdi)
mov    %r8b,0x1(%rcx)
add    $0xffffffff,%edx
add    $0x1,%rax
cmp    $0x1,%edx
jg     1130 <copy+0x30>
ret

LLVM IR (-O0):
define void @copy(i8** %0, i8* %1, i32 %2) {
%4 = alloca i8**
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i8*
store i8** %0, i8*** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
%8 = load i8**, i8*** %4
%9 = load i8*, i8** %8
%10 = load i8*, i8** %5
%11 = ptrtoint i8* %9 to i64
%12 = ptrtoint i8* %10 to i64
%13 = sub i64 %11, %12
%14 = inttoptr i64 %13 to i8*
store i8* %14, i8** %7
br label %15
15: ; preds = %19, %3
%16 = load i32, i32* %6
%17 = add nsw i32 %16, -1
store i32 %17, i32* %6
%18 = icmp sge i32 %16, 0
br i1 %18, label %19, label %26
19: ; preds = %15
%20 = load i8*, i8** %7
%21 = getelementptr inbounds i8, i8* %20, i32 1
store i8* %21, i8** %7
%22 = load i8, i8* %20
%23 = load i8**, i8*** %4
%24 = load i8*, i8** %23
%25 = getelementptr inbounds i8, i8* %24, i32 1
store i8* %25, i8** %23
store i8 %22, i8* %25
br label %15
26: ; preds = %15
ret void
}

LLVM IR (-O2):
define void @copy(i8** nocapture %0, i8* %1, i32 %2) {
%4 = load i8*, i8** %0
%5 = icmp sgt i32 %2, -1
br i1 %5, label %6, label %23
6: ; preds = %3
%7 = ptrtoint i8* %4 to i64
%8 = ptrtoint i8* %1 to i64
%9 = sub i64 %7, %8
%10 = inttoptr i64 %9 to i8*
%11 = load i8, i8* %10
%12 = getelementptr inbounds i8, i8* %4, i64 1
store i8* %12, i8** %0
store i8 %11, i8* %12
%13 = icmp eq i32 %2, 0
br i1 %13, label %23, label %14
14: ; preds = %6, %14
%15 = phi i32 [ %18, %14 ], [ %2, %6 ]
%16 = phi i8* [ %17, %14 ], [ %10, %6 ]
%17 = getelementptr inbounds i8, i8* %16, i64 1
%18 = add nsw i32 %15, -1
%19 = load i8*, i8** %0
%20 = load i8, i8* %17
%21 = getelementptr inbounds i8, i8* %19, i64 1
store i8* %21, i8** %0
store i8 %20, i8* %21
%22 = icmp sgt i32 %15, 1
br i1 %22, label %14, label %23
23: ; preds = %14, %6, %3
ret void
}