#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 introsort(void *, int /*<<< orphan*/, size_t, size_t,
               int (*)(void const *, void const *), unsigned int);
void qsort(void *elems, size_t elem_count, size_t elem_size,
           int (*cmp)(const void *, const void *)) {
  unsigned depth, bit;
  size_t mask;
  if (elem_count == 0)
    return;
  depth = 0;
  for (bit = 0, mask = 1; bit < sizeof(size_t) * 8; bit++, mask <<= 1) {
    if ((elem_count & mask) != 0)
      depth = bit;
  }
  depth <<= 1;
  return introsort(elems, 0, elem_count - 1, elem_size, cmp, depth);
}


x86 assembly (clang, -O0):
<qsort>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1138 <qsort+0x28>
jmp    11ba <qsort+0xaa>
movl   $0x0,-0x24(%rbp)
movl   $0x0,-0x28(%rbp)
movq   $0x1,-0x30(%rbp)
mov    -0x28(%rbp),%eax
cmp    $0x40,%rax
jae    1192 <qsort+0x82>
mov    -0x10(%rbp),%rax
and    -0x30(%rbp),%rax
cmp    $0x0,%rax
je     1173 <qsort+0x63>
mov    -0x28(%rbp),%eax
mov    %eax,-0x24(%rbp)
jmp    1178 <qsort+0x68>
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
mov    -0x30(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x30(%rbp)
jmp    114e <qsort+0x3e>
mov    -0x24(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rdx
sub    $0x1,%rdx
mov    -0x18(%rbp),%rcx
mov    -0x20(%rbp),%r8
mov    -0x24(%rbp),%r9d
xor    %esi,%esi
call   1030 <introsort@plt>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<qsort>:
test   %rsi,%rsi
je     118a <qsort+0x7a>
push   %rbx
mov    %rcx,%r8
mov    %rdx,%r10
mov    %rsi,%r11
xor    %eax,%eax
mov    $0x1,%esi
xor    %r9d,%r9d
nopl   0x0(%rax)
test   %r11,%rsi
cmovne %eax,%r9d
lea    (%rsi,%rsi,1),%rcx
lea    0x1(%rax),%edx
test   %r11,%rcx
cmove  %r9d,%edx
lea    0x0(,%rsi,4),%rcx
lea    0x2(%rax),%ebx
test   %r11,%rcx
cmove  %edx,%ebx
lea    0x0(,%rsi,8),%rcx
lea    0x3(%rax),%r9d
test   %r11,%rcx
cmove  %ebx,%r9d
shl    $0x4,%rsi
add    $0x4,%eax
cmp    $0x40,%eax
jne    1130 <qsort+0x20>
add    %r9d,%r9d
add    $0xffffffffffffffff,%r11
xor    %esi,%esi
mov    %r11,%rdx
mov    %r10,%rcx
pop    %rbx
jmp    1030 <introsort@plt>
ret

LLVM IR (-O0):
define void @qsort(i8* %0, i64 %1, i64 %2, i32 (i8*, i8*)* %3) {
%5 = alloca i8*
%6 = alloca i64
%7 = alloca i64
%8 = alloca i32 (i8*, i8*)*
%9 = alloca i32
%10 = alloca i32
%11 = alloca i64
store i8* %0, i8** %5
store i64 %1, i64* %6
store i64 %2, i64* %7
store i32 (i8*, i8*)* %3, i32 (i8*, i8*)** %8
%12 = load i64, i64* %6
%13 = icmp eq i64 %12, 0
br i1 %13, label %14, label %15
14: ; preds = %4
br label %42
15: ; preds = %4
store i32 0, i32* %9
store i32 0, i32* %10
store i64 1, i64* %11
br label %16
16: ; preds = %28, %15
%17 = load i32, i32* %10
%18 = zext i32 %17 to i64
%19 = icmp ult i64 %18, 64
br i1 %19, label %20, label %33
20: ; preds = %16
%21 = load i64, i64* %6
%22 = load i64, i64* %11
%23 = and i64 %21, %22
%24 = icmp ne i64 %23, 0
br i1 %24, label %25, label %27
25: ; preds = %20
%26 = load i32, i32* %10
store i32 %26, i32* %9
br label %27
27: ; preds = %25, %20
br label %28
28: ; preds = %27
%29 = load i32, i32* %10
%30 = add i32 %29, 1
store i32 %30, i32* %10
%31 = load i64, i64* %11
%32 = shl i64 %31, 1
store i64 %32, i64* %11
br label %16
33: ; preds = %16
%34 = load i32, i32* %9
%35 = shl i32 %34, 1
store i32 %35, i32* %9
%36 = load i8*, i8** %5
%37 = load i64, i64* %6
%38 = sub i64 %37, 1
%39 = load i64, i64* %7
%40 = load i32 (i8*, i8*)*, i32 (i8*, i8*)** %8
%41 = load i32, i32* %9
br label %42
42: ; preds = %33, %14
ret void
}

LLVM IR (-O2):
define void @qsort(i8* %0, i64 %1, i64 %2, i32 (i8*, i8*)* %3) {
%5 = icmp eq i64 %1, 0
br i1 %5, label %34, label %6
6: ; preds = %4, %6
%7 = phi i64 [ %29, %6 ], [ 1, %4 ]
%8 = phi i32 [ %28, %6 ], [ 0, %4 ]
%9 = phi i32 [ %27, %6 ], [ 0, %4 ]
%10 = and i64 %7, %1
%11 = icmp eq i64 %10, 0
%12 = select i1 %11, i32 %9, i32 %8
%13 = or i32 %8, 1
%14 = shl i64 %7, 1
%15 = and i64 %14, %1
%16 = icmp eq i64 %15, 0
%17 = select i1 %16, i32 %12, i32 %13
%18 = or i32 %8, 2
%19 = shl i64 %7, 2
%20 = and i64 %19, %1
%21 = icmp eq i64 %20, 0
%22 = select i1 %21, i32 %17, i32 %18
%23 = or i32 %8, 3
%24 = shl i64 %7, 3
%25 = and i64 %24, %1
%26 = icmp eq i64 %25, 0
%27 = select i1 %26, i32 %22, i32 %23
%28 = add nuw nsw i32 %8, 4
%29 = shl i64 %7, 4
%30 = icmp eq i32 %28, 64
br i1 %30, label %31, label %6
31: ; preds = %6
%32 = shl i32 %27, 1
%33 = add i64 %1, -1
tail call void @introsort(i8* %0, i32 0, i64 %33, i64 %2, i32 (i8*, i8*)* %3, i32 %32)
br label %34
34: ; preds = %4, %31
ret void
}