#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 */
scalar_t__ strcmp(char *, char *);
void hh_extensions_sort(char **array, int N) {
  int i, j, k, h;
  char *v;
  int incs[16] = {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968,
                  861,     336,    112,    48,    21,    7,     3,    1};
  for (k = 0; k < 16; k++) {
    for (h = incs[k], i = h; i <= N - 1; i++) {
      v = array[i];
      j = i;
      while (j >= h && strcmp(array[j - h], v) > 0) {
        array[j] = array[j - h];
        j -= h;
      }
      array[j] = v;
    }
  }
}


x86 assembly (clang, -O0):
<hh_extensions_sort>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
lea    -0x70(%rbp),%rdi
lea    0xec3(%rip),%rsi
mov    $0x40,%edx
call   1040 <memcpy@plt>
movl   $0x0,-0x18(%rbp)
cmpl   $0x10,-0x18(%rbp)
jge    1233 <hh_extensions_sort+0x113>
movslq -0x18(%rbp),%rax
mov    -0x70(%rbp,%rax,4),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
mov    -0xc(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jg     1220 <hh_extensions_sort+0x100>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%ecx
xor    %eax,%eax
cmp    -0x1c(%rbp),%ecx
mov    %al,-0x71(%rbp)
jl     11c5 <hh_extensions_sort+0xa5>
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
sub    -0x1c(%rbp),%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,8),%rdi
mov    -0x28(%rbp),%rsi
call   1030 <strcmp@plt>
cmp    $0x0,%rax
setg   %al
mov    %al,-0x71(%rbp)
mov    -0x71(%rbp),%al
test   $0x1,%al
jne    11d5 <hh_extensions_sort+0xb5>
jmp    1202 <hh_extensions_sort+0xe2>
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
sub    -0x1c(%rbp),%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,8),%rdx
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x1c(%rbp),%ecx
mov    -0x14(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0x14(%rbp)
jmp    1190 <hh_extensions_sort+0x70>
mov    -0x28(%rbp),%rdx
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    1169 <hh_extensions_sort+0x49>
jmp    1225 <hh_extensions_sort+0x105>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    114e <hh_extensions_sort+0x2e>
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<hh_extensions_sort>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %rdi,%rbx
xor    %eax,%eax
mov    %esi,0x8(%rsp)
jmp    1143 <hh_extensions_sort+0x33>
nopl   0x0(%rax)
mov    0x10(%rsp),%rax
add    $0x1,%rax
cmp    $0x10,%rax
je     11c9 <hh_extensions_sort+0xb9>
mov    %rax,0x10(%rsp)
lea    0xeb1(%rip),%rcx
movslq (%rcx,%rax,4),%rbp
cmp    %esi,%ebp
jge    1130 <hh_extensions_sort+0x20>
xor    %ecx,%ecx
mov    %rbp,%r15
jmp    117e <hh_extensions_sort+0x6e>
xchg   %ax,%ax
add    %ebp,%r12d
mov    0x8(%rsp),%esi
mov    0xc(%rsp),%ecx
movslq %r12d,%rax
mov    %r13,(%rbx,%rax,8)
add    $0x1,%r15
add    $0x1,%ecx
cmp    %esi,%r15d
je     1130 <hh_extensions_sort+0x20>
mov    (%rbx,%r15,8),%r13
mov    %r15d,%r12d
cmp    %rbp,%r15
jl     116b <hh_extensions_sort+0x5b>
mov    %ecx,0xc(%rsp)
mov    %ecx,%r12d
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movslq %r12d,%r14
mov    (%rbx,%r14,8),%rdi
mov    %r13,%rsi
call   1030 <strcmp@plt>
test   %rax,%rax
jle    1160 <hh_extensions_sort+0x50>
lea    (%r14,%rbp,1),%eax
mov    (%rbx,%r14,8),%rcx
cltq
mov    %rcx,(%rbx,%rax,8)
sub    %ebp,%r12d
jge    11a0 <hh_extensions_sort+0x90>
jmp    1160 <hh_extensions_sort+0x50>
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@__const.hh_extensions_sort.incs = [16 x i32] [i32 1391376, i32 463792, i32 198768, i32 86961, i32 33936, i32 13776, i32 4592, i32 1968, i32 861, i32 336, i32 112, i32 48, i32 21, i32 7, i32 3, i32 1]
define void @hh_extensions_sort(i8** %0, i32 %1) {
%3 = alloca i8**
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i8*
%10 = alloca [16 x i32]
store i8** %0, i8*** %3
store i32 %1, i32* %4
%11 = bitcast [16 x i32]* %10 to i8*
store i32 0, i32* %7
br label %12
12: ; preds = %75, %2
%13 = load i32, i32* %7
%14 = icmp slt i32 %13, 16
br i1 %14, label %15, label %78
15: ; preds = %12
%16 = load i32, i32* %7
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds [16 x i32], [16 x i32]* %10, i64 0, i64 %17
%19 = load i32, i32* %18
store i32 %19, i32* %8
%20 = load i32, i32* %8
store i32 %20, i32* %5
br label %21
21: ; preds = %71, %15
%22 = load i32, i32* %5
%23 = load i32, i32* %4
%24 = sub nsw i32 %23, 1
%25 = icmp sle i32 %22, %24
br i1 %25, label %26, label %74
26: ; preds = %21
%27 = load i8**, i8*** %3
%28 = load i32, i32* %5
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds i8*, i8** %27, i64 %29
%31 = load i8*, i8** %30
store i8* %31, i8** %9
%32 = load i32, i32* %5
store i32 %32, i32* %6
br label %33
33: ; preds = %50, %26
%34 = load i32, i32* %6
%35 = load i32, i32* %8
%36 = icmp sge i32 %34, %35
br i1 %36, label %37, label %48
37: ; preds = %33
%38 = load i8**, i8*** %3
%39 = load i32, i32* %6
%40 = load i32, i32* %8
%41 = sub nsw i32 %39, %40
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds i8*, i8** %38, i64 %42
%44 = load i8*, i8** %43
%45 = load i8*, i8** %9
%46 = call i64 @strcmp(i8* %44, i8* %45)
%47 = icmp sgt i64 %46, 0
br label %48
48: ; preds = %37, %33
%49 = phi i1 [ false, %33 ], [ %47, %37 ]
br i1 %49, label %50, label %65
50: ; preds = %48
%51 = load i8**, i8*** %3
%52 = load i32, i32* %6
%53 = load i32, i32* %8
%54 = sub nsw i32 %52, %53
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds i8*, i8** %51, i64 %55
%57 = load i8*, i8** %56
%58 = load i8**, i8*** %3
%59 = load i32, i32* %6
%60 = sext i32 %59 to i64
%61 = getelementptr inbounds i8*, i8** %58, i64 %60
store i8* %57, i8** %61
%62 = load i32, i32* %8
%63 = load i32, i32* %6
%64 = sub nsw i32 %63, %62
store i32 %64, i32* %6
br label %33
65: ; preds = %48
%66 = load i8*, i8** %9
%67 = load i8**, i8*** %3
%68 = load i32, i32* %6
%69 = sext i32 %68 to i64
%70 = getelementptr inbounds i8*, i8** %67, i64 %69
store i8* %66, i8** %70
br label %71
71: ; preds = %65
%72 = load i32, i32* %5
%73 = add nsw i32 %72, 1
store i32 %73, i32* %5
br label %21
74: ; preds = %21
br label %75
75: ; preds = %74
%76 = load i32, i32* %7
%77 = add nsw i32 %76, 1
store i32 %77, i32* %7
br label %12
78: ; preds = %12
ret void
}

LLVM IR (-O2):
@__const.hh_extensions_sort.incs = [16 x i32] [i32 1391376, i32 463792, i32 198768, i32 86961, i32 33936, i32 13776, i32 4592, i32 1968, i32 861, i32 336, i32 112, i32 48, i32 21, i32 7, i32 3, i32 1]
define void @hh_extensions_sort(i8** nocapture %0, i32 %1) {
br label %3
3: ; preds = %2, %36
%4 = phi i64 [ 0, %2 ], [ %37, %36 ]
%5 = getelementptr inbounds [16 x i32], [16 x i32]* @__const.hh_extensions_sort.incs, i64 0, i64 %4
%6 = load i32, i32* %5
%7 = icmp slt i32 %6, %1
br i1 %7, label %8, label %36
8: ; preds = %3
%9 = sext i32 %6 to i64
br label %10
10: ; preds = %8, %29
%11 = phi i64 [ %9, %8 ], [ %33, %29 ]
%12 = getelementptr inbounds i8*, i8** %0, i64 %11
%13 = load i8*, i8** %12
%14 = icmp slt i64 %11, %9
%15 = trunc i64 %11 to i32
br i1 %14, label %29, label %16
16: ; preds = %10, %24
%17 = phi i32 [ %18, %24 ], [ %15, %10 ]
%18 = sub nsw i32 %17, %6
%19 = sext i32 %18 to i64
%20 = getelementptr inbounds i8*, i8** %0, i64 %19
%21 = load i8*, i8** %20
%22 = tail call i64 @strcmp(i8* %21, i8* %13)
%23 = icmp sgt i64 %22, 0
br i1 %23, label %24, label %29
24: ; preds = %16
%25 = load i8*, i8** %20
%26 = sext i32 %17 to i64
%27 = getelementptr inbounds i8*, i8** %0, i64 %26
store i8* %25, i8** %27
%28 = icmp slt i32 %18, %6
br i1 %28, label %29, label %16
29: ; preds = %16, %24, %10
%30 = phi i32 [ %15, %10 ], [ %18, %24 ], [ %17, %16 ]
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds i8*, i8** %0, i64 %31
store i8* %13, i8** %32
%33 = add nsw i64 %11, 1
%34 = trunc i64 %33 to i32
%35 = icmp eq i32 %34, %1
br i1 %35, label %36, label %10
36: ; preds = %29, %3
%37 = add nuw nsw i64 %4, 1
%38 = icmp eq i64 %37, 16
br i1 %38, label %39, label %3
39: ; preds = %36
ret void
}