#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 *realloc(int *, int);
void arrayInsert(int elem, int **list, int length) {
  *list = realloc(*list, sizeof(int) * (length + 1));
  int i;
  for (i = 0; i < length; i++) {
    (*list)[length - i] = (*list)[length - i - 1];
  }
  *((*list)) = elem;
}


x86 assembly (clang, -O0):
<arrayInsert>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%rdi
mov    -0x14(%rbp),%eax
add    $0x1,%eax
cltq
shl    $0x2,%rax
mov    %eax,%esi
call   1030 <realloc@plt>
mov    %rax,%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    1190 <arrayInsert+0x80>
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    -0x14(%rbp),%ecx
sub    -0x18(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    -0x14(%rbp),%ecx
sub    -0x18(%rbp),%ecx
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    114d <arrayInsert+0x3d>
mov    -0x4(%rbp),%ecx
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    %ecx,(%rax)
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<arrayInsert>:
push   %rbp
push   %r14
push   %rbx
mov    %edx,%ebx
mov    %rsi,%rbp
mov    %edi,%r14d
mov    (%rsi),%rdi
lea    0x4(,%rbx,4),%esi
call   1030 <realloc@plt>
mov    %rax,0x0(%rbp)
test   %ebx,%ebx
jle    11a0 <arrayInsert+0x90>
mov    %ebx,%ebp
lea    -0x1(%rbp),%rdx
mov    %ebp,%ecx
and    $0x3,%ecx
cmp    $0x3,%rdx
jae    114d <arrayInsert+0x3d>
xor    %esi,%esi
test   %rcx,%rcx
jne    117b <arrayInsert+0x6b>
jmp    11a0 <arrayInsert+0x90>
lea    (%rax,%rbp,4),%rdi
mov    %ebp,%edx
and    $0xfffffffc,%edx
neg    %rdx
xor    %esi,%esi
nopl   0x0(%rax,%rax,1)
movups -0x10(%rdi,%rsi,4),%xmm0
movups %xmm0,-0xc(%rdi,%rsi,4)
add    $0xfffffffffffffffc,%rsi
cmp    %rsi,%rdx
jne    1160 <arrayInsert+0x50>
neg    %rsi
test   %rcx,%rcx
je     11a0 <arrayInsert+0x90>
sub    %rsi,%rbp
lea    (%rax,%rbp,4),%rdx
neg    %rcx
xor    %esi,%esi
nopw   0x0(%rax,%rax,1)
mov    -0x4(%rdx,%rsi,4),%edi
mov    %edi,(%rdx,%rsi,4)
add    $0xffffffffffffffff,%rsi
cmp    %rsi,%rcx
jne    1190 <arrayInsert+0x80>
mov    %r14d,(%rax)
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define void @arrayInsert(i32 %0, i32** %1, i32 %2) {
%4 = alloca i32
%5 = alloca i32**
%6 = alloca i32
%7 = alloca i32
store i32 %0, i32* %4
store i32** %1, i32*** %5
store i32 %2, i32* %6
%8 = load i32**, i32*** %5
%9 = load i32*, i32** %8
%10 = load i32, i32* %6
%11 = add nsw i32 %10, 1
%12 = sext i32 %11 to i64
%13 = mul i64 4, %12
%14 = trunc i64 %13 to i32
%15 = call i32* @realloc(i32* %9, i32 %14)
%16 = load i32**, i32*** %5
store i32* %15, i32** %16
store i32 0, i32* %7
br label %17
17: ; preds = %38, %3
%18 = load i32, i32* %7
%19 = load i32, i32* %6
%20 = icmp slt i32 %18, %19
br i1 %20, label %21, label %41
21: ; preds = %17
%22 = load i32**, i32*** %5
%23 = load i32*, i32** %22
%24 = load i32, i32* %6
%25 = load i32, i32* %7
%26 = sub nsw i32 %24, %25
%27 = sub nsw i32 %26, 1
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds i32, i32* %23, i64 %28
%30 = load i32, i32* %29
%31 = load i32**, i32*** %5
%32 = load i32*, i32** %31
%33 = load i32, i32* %6
%34 = load i32, i32* %7
%35 = sub nsw i32 %33, %34
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds i32, i32* %32, i64 %36
store i32 %30, i32* %37
br label %38
38: ; preds = %21
%39 = load i32, i32* %7
%40 = add nsw i32 %39, 1
store i32 %40, i32* %7
br label %17
41: ; preds = %17
%42 = load i32, i32* %4
%43 = load i32**, i32*** %5
%44 = load i32*, i32** %43
store i32 %42, i32* %44
ret void
}

LLVM IR (-O2):
define void @arrayInsert(i32 %0, i32** nocapture %1, i32 %2) {
%4 = load i32*, i32** %1
%5 = shl i32 %2, 2
%6 = add i32 %5, 4
%7 = tail call i32* @realloc(i32* %4, i32 %6)
store i32* %7, i32** %1
%8 = icmp sgt i32 %2, 0
br i1 %8, label %9, label %59
9: ; preds = %3
%10 = zext i32 %2 to i64
%11 = add nsw i64 %10, -1
%12 = and i64 %10, 3
%13 = icmp ult i64 %11, 3
br i1 %13, label %45, label %14
14: ; preds = %9
%15 = and i64 %10, 4294967292
br label %16
16: ; preds = %16, %14
%17 = phi i64 [ 0, %14 ], [ %42, %16 ]
%18 = phi i64 [ 0, %14 ], [ %43, %16 ]
%19 = sub nsw i64 %10, %17
%20 = add nsw i64 %19, -1
%21 = getelementptr inbounds i32, i32* %7, i64 %20
%22 = load i32, i32* %21
%23 = getelementptr inbounds i32, i32* %7, i64 %19
store i32 %22, i32* %23
%24 = xor i64 %17, -1
%25 = add nsw i64 %24, %10
%26 = add nsw i64 %25, -1
%27 = getelementptr inbounds i32, i32* %7, i64 %26
%28 = load i32, i32* %27
%29 = getelementptr inbounds i32, i32* %7, i64 %25
store i32 %28, i32* %29
%30 = or i64 %17, 2
%31 = sub nsw i64 %10, %30
%32 = add nsw i64 %31, -1
%33 = getelementptr inbounds i32, i32* %7, i64 %32
%34 = load i32, i32* %33
%35 = getelementptr inbounds i32, i32* %7, i64 %31
store i32 %34, i32* %35
%36 = or i64 %17, 3
%37 = sub nsw i64 %10, %36
%38 = add nsw i64 %37, -1
%39 = getelementptr inbounds i32, i32* %7, i64 %38
%40 = load i32, i32* %39
%41 = getelementptr inbounds i32, i32* %7, i64 %37
store i32 %40, i32* %41
%42 = add nuw nsw i64 %17, 4
%43 = add i64 %18, 4
%44 = icmp eq i64 %43, %15
br i1 %44, label %45, label %16
45: ; preds = %16, %9
%46 = phi i64 [ 0, %9 ], [ %42, %16 ]
%47 = icmp eq i64 %12, 0
br i1 %47, label %59, label %48
48: ; preds = %45, %48
%49 = phi i64 [ %56, %48 ], [ %46, %45 ]
%50 = phi i64 [ %57, %48 ], [ 0, %45 ]
%51 = sub nsw i64 %10, %49
%52 = add nsw i64 %51, -1
%53 = getelementptr inbounds i32, i32* %7, i64 %52
%54 = load i32, i32* %53
%55 = getelementptr inbounds i32, i32* %7, i64 %51
store i32 %54, i32* %55
%56 = add nuw nsw i64 %49, 1
%57 = add i64 %50, 1
%58 = icmp eq i64 %57, %12
br i1 %58, label %59, label %48
59: ; preds = %45, %48, %3
store i32 %0, i32* %7
ret void
}