#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 */
void sht_sift(short *array, size_t l, size_t r) {
  size_t i;
  short t;
  t = array[l];
  i = l + l + 1;
  do {
    if ((i < r) && (array[i] < array[i + 1]))
      i++;
    if (t >= array[i])
      break;
    array[l] = array[i];
    l = i;
    i += i + 1;
  } while (i <= r);
  array[l] = t;
}


x86 assembly (clang, -O0):
<sht_sift>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rcx
mov    (%rax,%rcx,2),%ax
mov    %ax,-0x22(%rbp)
mov    -0x10(%rbp),%rax
add    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    116b <sht_sift+0x6b>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
movswl (%rax,%rcx,2),%eax
mov    -0x8(%rbp),%rcx
mov    -0x20(%rbp),%rdx
movswl 0x2(%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jge    116b <sht_sift+0x6b>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
movswl -0x22(%rbp),%eax
mov    -0x8(%rbp),%rcx
mov    -0x20(%rbp),%rdx
movswl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jl     1188 <sht_sift+0x88>
jmp    11c6 <sht_sift+0xc6>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    (%rax,%rcx,2),%dx
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
mov    -0x20(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
add    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x18(%rbp),%rax
jbe    1130 <sht_sift+0x30>
mov    -0x22(%rbp),%dx
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
pop    %rbp
ret

x86 assembly (clang, -O2):
<sht_sift>:
movzwl (%rdi,%rsi,2),%r8d
lea    (%rsi,%rsi,1),%rcx
add    $0x1,%rcx
nopl   (%rax)
cmp    %rdx,%rcx
jae    1124 <sht_sift+0x24>
movzwl (%rdi,%rcx,2),%eax
cmp    0x2(%rdi,%rcx,2),%ax
jge    1124 <sht_sift+0x24>
add    $0x1,%rcx
mov    %rcx,%rax
movzwl (%rdi,%rcx,2),%ecx
cmp    %cx,%r8w
jge    114b <sht_sift+0x4b>
mov    %cx,(%rdi,%rsi,2)
lea    (%rax,%rax,1),%rcx
add    $0x1,%rcx
mov    %rax,%rsi
cmp    %rdx,%rcx
jbe    1110 <sht_sift+0x10>
mov    %r8w,(%rdi,%rax,2)
ret
mov    %r8w,(%rdi,%rsi,2)
ret

LLVM IR (-O0):
define void @sht_sift(i16* %0, i64 %1, i64 %2) {
%4 = alloca i16*
%5 = alloca i64
%6 = alloca i64
%7 = alloca i64
%8 = alloca i16
store i16* %0, i16** %4
store i64 %1, i64* %5
store i64 %2, i64* %6
%9 = load i16*, i16** %4
%10 = load i64, i64* %5
%11 = getelementptr inbounds i16, i16* %9, i64 %10
%12 = load i16, i16* %11
store i16 %12, i16* %8
%13 = load i64, i64* %5
%14 = load i64, i64* %5
%15 = add i64 %13, %14
%16 = add i64 %15, 1
store i64 %16, i64* %7
br label %17
17: ; preds = %60, %3
%18 = load i64, i64* %7
%19 = load i64, i64* %6
%20 = icmp ult i64 %18, %19
br i1 %20, label %21, label %37
21: ; preds = %17
%22 = load i16*, i16** %4
%23 = load i64, i64* %7
%24 = getelementptr inbounds i16, i16* %22, i64 %23
%25 = load i16, i16* %24
%26 = sext i16 %25 to i32
%27 = load i16*, i16** %4
%28 = load i64, i64* %7
%29 = add i64 %28, 1
%30 = getelementptr inbounds i16, i16* %27, i64 %29
%31 = load i16, i16* %30
%32 = sext i16 %31 to i32
%33 = icmp slt i32 %26, %32
br i1 %33, label %34, label %37
34: ; preds = %21
%35 = load i64, i64* %7
%36 = add i64 %35, 1
store i64 %36, i64* %7
br label %37
37: ; preds = %34, %21, %17
%38 = load i16, i16* %8
%39 = sext i16 %38 to i32
%40 = load i16*, i16** %4
%41 = load i64, i64* %7
%42 = getelementptr inbounds i16, i16* %40, i64 %41
%43 = load i16, i16* %42
%44 = sext i16 %43 to i32
%45 = icmp sge i32 %39, %44
br i1 %45, label %46, label %47
46: ; preds = %37
br label %64
47: ; preds = %37
%48 = load i16*, i16** %4
%49 = load i64, i64* %7
%50 = getelementptr inbounds i16, i16* %48, i64 %49
%51 = load i16, i16* %50
%52 = load i16*, i16** %4
%53 = load i64, i64* %5
%54 = getelementptr inbounds i16, i16* %52, i64 %53
store i16 %51, i16* %54
%55 = load i64, i64* %7
store i64 %55, i64* %5
%56 = load i64, i64* %7
%57 = add i64 %56, 1
%58 = load i64, i64* %7
%59 = add i64 %58, %57
store i64 %59, i64* %7
br label %60
60: ; preds = %47
%61 = load i64, i64* %7
%62 = load i64, i64* %6
%63 = icmp ule i64 %61, %62
br i1 %63, label %17, label %64
64: ; preds = %60, %46
%65 = load i16, i16* %8
%66 = load i16*, i16** %4
%67 = load i64, i64* %5
%68 = getelementptr inbounds i16, i16* %66, i64 %67
store i16 %65, i16* %68
ret void
}

LLVM IR (-O2):
define void @sht_sift(i16* nocapture %0, i64 %1, i64 %2) {
%4 = getelementptr inbounds i16, i16* %0, i64 %1
%5 = load i16, i16* %4
%6 = shl i64 %1, 1
%7 = or i64 %6, 1
br label %8
8: ; preds = %25, %3
%9 = phi i64 [ %7, %3 ], [ %28, %25 ]
%10 = phi i64 [ %1, %3 ], [ %21, %25 ]
%11 = icmp ult i64 %9, %2
br i1 %11, label %12, label %20
12: ; preds = %8
%13 = getelementptr inbounds i16, i16* %0, i64 %9
%14 = load i16, i16* %13
%15 = add nuw i64 %9, 1
%16 = getelementptr inbounds i16, i16* %0, i64 %15
%17 = load i16, i16* %16
%18 = icmp slt i16 %14, %17
%19 = select i1 %18, i64 %15, i64 %9
br label %20
20: ; preds = %12, %8
%21 = phi i64 [ %9, %8 ], [ %19, %12 ]
%22 = getelementptr inbounds i16, i16* %0, i64 %21
%23 = load i16, i16* %22
%24 = icmp slt i16 %5, %23
br i1 %24, label %25, label %30
25: ; preds = %20
%26 = getelementptr inbounds i16, i16* %0, i64 %10
store i16 %23, i16* %26
%27 = shl i64 %21, 1
%28 = or i64 %27, 1
%29 = icmp ugt i64 %28, %2
br i1 %29, label %30, label %8
30: ; preds = %20, %25
%31 = phi i64 [ %10, %20 ], [ %21, %25 ]
%32 = getelementptr inbounds i16, i16* %0, i64 %31
store i16 %5, i16* %32
ret void
}