void shell(unsigned long n, float a[]) {
  unsigned long i, j, inc;
  float v;
  inc = 1;
  do {
    inc *= 3;
    inc++;
  } while (inc <= n);
  do {
    inc /= 3;
    for (i = inc + 1; i <= n; i++) {
      v = a[i];
      j = i;
      while (a[j - inc] > v) {
        a[j] = a[j - inc];
        j -= inc;
        if (j <= inc)
          break;
      }
      a[j] = v;
    }
  } while (inc > 1);
}


x86 assembly (clang, -O0):
<shell>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movq   $0x1,-0x28(%rbp)
imul   $0x3,-0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x8(%rbp),%rax
jbe    1114 <shell+0x14>
jmp    113c <shell+0x3c>
mov    -0x28(%rbp),%rax
mov    $0x3,%ecx
xor    %edx,%edx
div    %rcx
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x8(%rbp),%rax
ja     1205 <shell+0x105>
mov    -0x10(%rbp),%rax
mov    -0x18(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x2c(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
sub    -0x28(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
ucomiss -0x2c(%rbp),%xmm0
jbe    11e2 <shell+0xe2>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
sub    -0x28(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rax
sub    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x28(%rbp),%rax
ja     11dd <shell+0xdd>
jmp    11e2 <shell+0xe2>
jmp    1182 <shell+0x82>
movss  -0x2c(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    115a <shell+0x5a>
jmp    120a <shell+0x10a>
cmpq   $0x1,-0x28(%rbp)
ja     113c <shell+0x3c>
pop    %rbp
ret

x86 assembly (clang, -O2):
<shell>:
mov    $0x1,%r10d
cs nopw 0x0(%rax,%rax,1)
lea    (%r10,%r10,2),%r10
add    $0x1,%r10
cmp    %rdi,%r10
jbe    1110 <shell+0x10>
push   %r14
push   %rbx
lea    0x4(%rsi),%r8
movabs $0xaaaaaaaaaaaaaaab,%r9
aa aa aa
jmp    1139 <shell+0x39>
cmp    $0x5,%r10
mov    %rdx,%r10
jbe    11af <shell+0xaf>
mov    %r10,%rax
mul    %r9
shr    %rdx
cmp    %rdi,%rdx
jae    1130 <shell+0x30>
lea    0x1(%rdx),%rax
lea    (%r8,%rdx,4),%r11
mov    %r8,%r14
jmp    117c <shell+0x7c>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
add    %rax,%rbx
mov    %rbx,%rcx
movss  %xmm0,(%rsi,%rcx,4)
add    $0x1,%rax
add    $0x4,%r11
add    $0x4,%r14
cmp    %rdi,%rax
ja     1130 <shell+0x30>
movss  (%rsi,%rax,4),%xmm0
xor    %ebx,%ebx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movss  (%r14,%rbx,4),%xmm1
ucomiss %xmm0,%xmm1
jbe    1160 <shell+0x60>
movss  %xmm1,(%r11,%rbx,4)
sub    %rdx,%rbx
lea    (%rax,%rbx,1),%rcx
cmp    %rdx,%rcx
ja     1190 <shell+0x90>
jmp    1166 <shell+0x66>
pop    %rbx
pop    %r14
ret

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

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