int shift_up(char *array[], int array_size, int buffer_element) {
  char *place_holder = array[array_size - 1];
  int element;
  for (element = array_size - 1; element > 0; --element)
    array[element] = array[element - 1];
  array[element] = place_holder;
  return (buffer_element < array_size - 1) ? ++buffer_element : 0;
}


x86 assembly (clang, -O0):
<shift_up>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    -0x8(%rbp),%rax
mov    -0xc(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,8),%rax
mov    %rax,-0x18(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jle    1161 <shift_up+0x61>
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,8),%rdx
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
jmp    112c <shift_up+0x2c>
mov    -0x18(%rbp),%rdx
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x10(%rbp),%eax
mov    -0xc(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1193 <shift_up+0x93>
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
mov    %eax,-0x20(%rbp)
jmp    119d <shift_up+0x9d>
xor    %eax,%eax
mov    %eax,-0x20(%rbp)
jmp    119d <shift_up+0x9d>
mov    -0x20(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<shift_up>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %edx,%r8d
lea    -0x1(%rsi),%r9d
movslq %esi,%rcx
mov    -0x8(%rdi,%rcx,8),%r10
mov    %r9d,%eax
cmp    $0x2,%ecx
jl     1158 <shift_up+0x58>
mov    %r9d,%ecx
cmp    $0x1,%r9d
mov    %rcx,%r12
adc    $0xffffffffffffffff,%r12
add    $0x1,%r12
cmp    $0x4,%r12
jae    1175 <shift_up+0x75>
add    $0x1,%rcx
nopl   (%rax)
lea    -0x2(%rcx),%eax
mov    (%rdi,%rax,8),%rax
mov    %rax,-0x8(%rdi,%rcx,8)
add    $0xffffffffffffffff,%rcx
cmp    $0x1,%rcx
ja     1140 <shift_up+0x40>
xor    %eax,%eax
cltq
mov    %r10,(%rdi,%rax,8)
lea    0x1(%r8),%ecx
xor    %eax,%eax
cmp    %r8d,%r9d
cmovg  %ecx,%eax
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
cmp    $0x1,%r9d
mov    %rcx,%r11
adc    $0xffffffffffffffff,%r11
add    $0xfffffffe,%esi
mov    $0x8,%edx
mov    %r11,%rax
mul    %rdx
seto   %bpl
cmp    %r11d,%esi
jb     1139 <shift_up+0x39>
shr    $0x20,%r11
jne    1139 <shift_up+0x39>
lea    (%rdi,%rcx,8),%rdx
mov    %rdx,%rbx
sub    %rax,%rbx
cmp    %rdx,%rbx
ja     1139 <shift_up+0x39>
test   %bpl,%bpl
jne    1139 <shift_up+0x39>
lea    (%rdi,%rsi,8),%rbx
mov    %rbx,%rdx
sub    %rax,%rdx
cmp    %rbx,%rdx
ja     1139 <shift_up+0x39>
test   %bpl,%bpl
jne    1139 <shift_up+0x39>
xor    %eax,%eax
test   %r9d,%r9d
setne  %al
lea    (%rdi,%rax,8),%rdx
lea    (%rdi,%rsi,8),%rbp
add    $0x8,%rbp
cmp    %rbp,%rdx
jae    1201 <shift_up+0x101>
lea    (%rdi,%rcx,8),%rdx
add    $0x8,%rdx
add    %rsi,%rax
sub    %rcx,%rax
lea    (%rdi,%rax,8),%rax
cmp    %rdx,%rax
jb     1139 <shift_up+0x39>
mov    $0xffffffff,%r11d
mov    %r12,%r14
and    $0xfffffffffffffffc,%r14
lea    -0x4(%r14),%rax
mov    %rax,%r15
shr    $0x2,%r15
add    $0x1,%r15
test   %rax,%rax
je     12c4 <shift_up+0x1c4>
mov    %r15,%rsi
and    $0xfffffffffffffffe,%rsi
lea    (%rdi,%rcx,8),%rax
add    $0xfffffffffffffff8,%rax
lea    (%rcx,%r11,1),%r13
add    $0xfffffffffffffffc,%r13
lea    (%rcx,%r11,1),%rbx
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
lea    (%rbx,%rdx,1),%ebp
movups -0x18(%rdi,%rbp,8),%xmm0
movups -0x8(%rdi,%rbp,8),%xmm1
movups %xmm1,(%rax,%rdx,8)
movups %xmm0,-0x10(%rax,%rdx,8)
lea    0x0(%r13,%rdx,1),%ebp
movups -0x18(%rdi,%rbp,8),%xmm0
movups -0x8(%rdi,%rbp,8),%xmm1
movups %xmm1,-0x20(%rax,%rdx,8)
movups %xmm0,-0x30(%rax,%rdx,8)
add    $0xfffffffffffffff8,%rdx
add    $0xfffffffffffffffe,%rsi
jne    1250 <shift_up+0x150>
neg    %rdx
test   $0x1,%r15b
je     12b1 <shift_up+0x1b1>
mov    %rcx,%rax
sub    %rdx,%rax
add    %eax,%r11d
movups -0x18(%rdi,%r11,8),%xmm0
movups -0x8(%rdi,%r11,8),%xmm1
movups %xmm1,-0x8(%rdi,%rax,8)
movups %xmm0,-0x18(%rdi,%rax,8)
xor    %eax,%eax
cmp    %r14,%r12
je     1158 <shift_up+0x58>
sub    %r14,%rcx
jmp    1139 <shift_up+0x39>
xor    %edx,%edx
test   $0x1,%r15b
jne    1292 <shift_up+0x192>
jmp    12b1 <shift_up+0x1b1>

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

LLVM IR (-O2):
define i32 @shift_up(i8** nocapture %0, i32 %1, i32 %2) {
%4 = add nsw i32 %1, -1
%5 = sext i32 %4 to i64
%6 = getelementptr inbounds i8*, i8** %0, i64 %5
%7 = load i8*, i8** %6
%8 = icmp sgt i32 %1, 1
br i1 %8, label %9, label %146
9: ; preds = %3
%10 = zext i32 %4 to i64
%11 = add nuw nsw i64 %10, 1
%12 = icmp ne i32 %4, 0
%13 = sext i1 %12 to i64
%14 = add nsw i64 %11, %13
%15 = icmp ult i64 %14, 4
br i1 %15, label %136, label %16
16: ; preds = %9
%17 = icmp ne i32 %4, 0
%18 = sext i1 %17 to i64
%19 = add nsw i64 %18, %10
%20 = add i32 %1, -2
%21 = trunc i64 %19 to i32
%22 = icmp ult i32 %20, %21
%23 = icmp ugt i64 %19, 4294967295
%24 = or i1 %22, %23
%25 = getelementptr i8*, i8** %0, i64 %10
%26 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %19, i64 8)
%27 = extractvalue { i64, i1 } %26, 0
%28 = extractvalue { i64, i1 } %26, 1
%29 = bitcast i8** %25 to i8*
%30 = sub i64 0, %27
%31 = getelementptr i8, i8* %29, i64 %30
%32 = icmp ugt i8* %31, %29
%33 = or i1 %32, %28
%34 = zext i32 %20 to i64
%35 = getelementptr i8*, i8** %0, i64 %34
%36 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %19, i64 8)
%37 = extractvalue { i64, i1 } %36, 0
%38 = extractvalue { i64, i1 } %36, 1
%39 = bitcast i8** %35 to i8*
%40 = sub i64 0, %37
%41 = getelementptr i8, i8* %39, i64 %40
%42 = icmp ugt i8* %41, %39
%43 = or i1 %42, %38
%44 = or i1 %24, %33
%45 = or i1 %44, %43
br i1 %45, label %136, label %46
46: ; preds = %16
%47 = icmp ne i32 %4, 0
%48 = zext i1 %47 to i64
%49 = getelementptr i8*, i8** %0, i64 %48
%50 = add nuw nsw i64 %10, 1
%51 = getelementptr i8*, i8** %0, i64 %50
%52 = add i32 %1, -2
%53 = zext i32 %52 to i64
%54 = add nuw nsw i64 %48, %53
%55 = sub nsw i64 %54, %10
%56 = getelementptr i8*, i8** %0, i64 %55
%57 = add nuw nsw i64 %53, 1
%58 = getelementptr i8*, i8** %0, i64 %57
%59 = icmp ult i8** %49, %58
%60 = icmp ult i8** %56, %51
%61 = and i1 %59, %60
br i1 %61, label %136, label %62
62: ; preds = %46
%63 = and i64 %14, -4
%64 = sub nsw i64 %10, %63
%65 = add nsw i64 %63, -4
%66 = lshr exact i64 %65, 2
%67 = add nuw nsw i64 %66, 1
%68 = and i64 %67, 1
%69 = icmp eq i64 %65, 0
br i1 %69, label %113, label %70
70: ; preds = %62
%71 = and i64 %67, 9223372036854775806
br label %72
72: ; preds = %72, %70
%73 = phi i64 [ 0, %70 ], [ %110, %72 ]
%74 = phi i64 [ 0, %70 ], [ %111, %72 ]
%75 = sub i64 %10, %73
%76 = add i64 %75, 4294967295
%77 = and i64 %76, 4294967295
%78 = getelementptr inbounds i8*, i8** %0, i64 %77
%79 = getelementptr inbounds i8*, i8** %78, i64 -1
%80 = bitcast i8** %79 to <2 x i8*>*
%81 = load <2 x i8*>, <2 x i8*>* %80
%82 = getelementptr inbounds i8*, i8** %78, i64 -2
%83 = getelementptr inbounds i8*, i8** %82, i64 -1
%84 = bitcast i8** %83 to <2 x i8*>*
%85 = load <2 x i8*>, <2 x i8*>* %84
%86 = getelementptr inbounds i8*, i8** %0, i64 %75
%87 = getelementptr inbounds i8*, i8** %86, i64 -1
%88 = bitcast i8** %87 to <2 x i8*>*
store <2 x i8*> %81, <2 x i8*>* %88
%89 = getelementptr inbounds i8*, i8** %86, i64 -2
%90 = getelementptr inbounds i8*, i8** %89, i64 -1
%91 = bitcast i8** %90 to <2 x i8*>*
store <2 x i8*> %85, <2 x i8*>* %91
%92 = or i64 %73, 4
%93 = sub i64 %10, %92
%94 = add i64 %93, 4294967295
%95 = and i64 %94, 4294967295
%96 = getelementptr inbounds i8*, i8** %0, i64 %95
%97 = getelementptr inbounds i8*, i8** %96, i64 -1
%98 = bitcast i8** %97 to <2 x i8*>*
%99 = load <2 x i8*>, <2 x i8*>* %98
%100 = getelementptr inbounds i8*, i8** %96, i64 -2
%101 = getelementptr inbounds i8*, i8** %100, i64 -1
%102 = bitcast i8** %101 to <2 x i8*>*
%103 = load <2 x i8*>, <2 x i8*>* %102
%104 = getelementptr inbounds i8*, i8** %0, i64 %93
%105 = getelementptr inbounds i8*, i8** %104, i64 -1
%106 = bitcast i8** %105 to <2 x i8*>*
store <2 x i8*> %99, <2 x i8*>* %106
%107 = getelementptr inbounds i8*, i8** %104, i64 -2
%108 = getelementptr inbounds i8*, i8** %107, i64 -1
%109 = bitcast i8** %108 to <2 x i8*>*
store <2 x i8*> %103, <2 x i8*>* %109
%110 = add nuw i64 %73, 8
%111 = add i64 %74, 2
%112 = icmp eq i64 %111, %71
br i1 %112, label %113, label %72
113: ; preds = %72, %62
%114 = phi i64 [ 0, %62 ], [ %110, %72 ]
%115 = icmp eq i64 %68, 0
br i1 %115, label %134, label %116
116: ; preds = %113
%117 = sub i64 %10, %114
%118 = add i64 %117, 4294967295
%119 = and i64 %118, 4294967295
%120 = getelementptr inbounds i8*, i8** %0, i64 %119
%121 = getelementptr inbounds i8*, i8** %120, i64 -1
%122 = bitcast i8** %121 to <2 x i8*>*
%123 = load <2 x i8*>, <2 x i8*>* %122
%124 = getelementptr inbounds i8*, i8** %120, i64 -2
%125 = getelementptr inbounds i8*, i8** %124, i64 -1
%126 = bitcast i8** %125 to <2 x i8*>*
%127 = load <2 x i8*>, <2 x i8*>* %126
%128 = getelementptr inbounds i8*, i8** %0, i64 %117
%129 = getelementptr inbounds i8*, i8** %128, i64 -1
%130 = bitcast i8** %129 to <2 x i8*>*
store <2 x i8*> %123, <2 x i8*>* %130
%131 = getelementptr inbounds i8*, i8** %128, i64 -2
%132 = getelementptr inbounds i8*, i8** %131, i64 -1
%133 = bitcast i8** %132 to <2 x i8*>*
store <2 x i8*> %127, <2 x i8*>* %133
br label %134
134: ; preds = %113, %116
%135 = icmp eq i64 %14, %63
br i1 %135, label %146, label %136
136: ; preds = %46, %16, %9, %134
%137 = phi i64 [ %10, %46 ], [ %10, %16 ], [ %10, %9 ], [ %64, %134 ]
br label %138
138: ; preds = %136, %138
%139 = phi i64 [ %140, %138 ], [ %137, %136 ]
%140 = add nsw i64 %139, -1
%141 = and i64 %140, 4294967295
%142 = getelementptr inbounds i8*, i8** %0, i64 %141
%143 = load i8*, i8** %142
%144 = getelementptr inbounds i8*, i8** %0, i64 %139
store i8* %143, i8** %144
%145 = icmp ugt i64 %139, 1
br i1 %145, label %138, label %146
146: ; preds = %138, %134, %3
%147 = phi i32 [ %4, %3 ], [ 0, %134 ], [ 0, %138 ]
%148 = sext i32 %147 to i64
%149 = getelementptr inbounds i8*, i8** %0, i64 %148
store i8* %7, i8** %149
%150 = icmp sgt i32 %4, %2
%151 = add nsw i32 %2, 1
%152 = select i1 %150, i32 %151, i32 0
ret i32 %152
}