void crank(unsigned long n, float w[]) {
  unsigned long j = 1, ji, jt;
  float rank;
  while (j < n) {
    if (w[j + 1] != w[j]) {
      w[j] = j;
      ++j;
    } else {
      for (jt = j + 1; jt <= n && w[jt] == w[j]; jt++)
        ;
      rank = 0.5 * (j + jt - 1);
      for (ji = j; ji <= (jt - 1); ji++)
        w[ji] = rank;
    }
  }
  if (j == n)
    w[n] = n;
}


x86 assembly (clang, -O0):
<crank>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movq   $0x1,-0x18(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x8(%rbp),%rax
jae    12a9 <crank+0x1a9>
mov    -0x10(%rbp),%rax
mov    -0x18(%rbp),%rcx
movss  0x4(%rax,%rcx,4),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x18(%rbp),%rcx
ucomiss (%rax,%rcx,4),%xmm0
jne    114d <crank+0x4d>
jp     114d <crank+0x4d>
jmp    11ad <crank+0xad>
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
shr    %rdx
mov    %eax,%ecx
and    $0x1,%ecx
or     %rdx,%rcx
cvtsi2ss %rcx,%xmm0
addss  %xmm0,%xmm0
cvtsi2ss %rax,%xmm1
movss  %xmm1,-0x34(%rbp)
test   %rax,%rax
movss  %xmm0,-0x30(%rbp)
js     118a <crank+0x8a>
movss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
movss  -0x30(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x18(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    12a4 <crank+0x1a4>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rcx
xor    %eax,%eax
cmp    -0x8(%rbp),%rcx
mov    %al,-0x35(%rbp)
ja     11f0 <crank+0xf0>
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x18(%rbp),%rcx
ucomiss (%rax,%rcx,4),%xmm0
sete   %al
setnp  %cl
and    %cl,%al
mov    %al,-0x35(%rbp)
mov    -0x35(%rbp),%al
test   $0x1,%al
jne    1200 <crank+0x100>
jmp    1216 <crank+0x116>
jmp    1205 <crank+0x105>
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    11b9 <crank+0xb9>
mov    -0x18(%rbp),%rax
mov    -0x28(%rbp),%rcx
lea    -0x1(%rax,%rcx,1),%rax
movq   %rax,%xmm1
movaps 0xde1(%rip),%xmm0
punpckldq %xmm0,%xmm1
movapd 0xde5(%rip),%xmm0
subpd  %xmm0,%xmm1
movaps %xmm1,%xmm0
unpckhpd %xmm1,%xmm1
addsd  %xmm0,%xmm1
movsd  0xdae(%rip),%xmm0
mulsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x2c(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%rcx
sub    $0x1,%rcx
cmp    %rcx,%rax
ja     129f <crank+0x19f>
movss  -0x2c(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    1267 <crank+0x167>
jmp    12a4 <crank+0x1a4>
jmp    1114 <crank+0x14>
mov    -0x18(%rbp),%rax
cmp    -0x8(%rbp),%rax
jne    1306 <crank+0x206>
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
shr    %rdx
mov    %eax,%ecx
and    $0x1,%ecx
or     %rdx,%rcx
cvtsi2ss %rcx,%xmm0
addss  %xmm0,%xmm0
cvtsi2ss %rax,%xmm1
movss  %xmm1,-0x40(%rbp)
test   %rax,%rax
movss  %xmm0,-0x3c(%rbp)
js     12f4 <crank+0x1f4>
movss  -0x40(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x3c(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x8(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
pop    %rbp
ret

x86 assembly (clang, -O2):
<crank>:
push   %r15
push   %r14
push   %rbx
mov    $0x1,%r10d
cmp    $0x2,%rdi
jb     12f3 <crank+0x1f3>
lea    0x70(%rsi),%r8
lea    0x10(%rsi),%r9
mov    $0x1,%r15d
movdqa 0xed5(%rip),%xmm0
movapd 0xedd(%rip),%xmm1
movsd  0xee5(%rip),%xmm2
jmp    114f <crank+0x4f>
nopl   (%rax)
mov    %r15,%r10
mov    %r10,%r15
cmp    %rdi,%r10
jae    12f3 <crank+0x1f3>
lea    0x1(%r15),%r10
movss  (%rsi,%r15,4),%xmm3
movss  0x4(%rsi,%r15,4),%xmm4
ucomiss %xmm3,%xmm4
jne    1167 <crank+0x67>
jnp    1180 <crank+0x80>
test   %r15,%r15
js     1240 <crank+0x140>
xorps  %xmm3,%xmm3
cvtsi2ss %r15,%xmm3
movss  %xmm3,(%rsi,%r15,4)
jmp    1143 <crank+0x43>
mov    %r10,%rdx
cmp    %rdi,%r15
jae    11b8 <crank+0xb8>
ucomiss %xmm3,%xmm4
mov    %r10,%rdx
jne    11b8 <crank+0xb8>
jp     11b8 <crank+0xb8>
lea    0x2(%r15),%rax
cs nopw 0x0(%rax,%rax,1)
mov    %rax,%rdx
cmp    %rdi,%rax
ja     11b8 <crank+0xb8>
movss  (%rsi,%rdx,4),%xmm4
lea    0x1(%rdx),%rax
ucomiss %xmm3,%xmm4
jne    11b8 <crank+0xb8>
jnp    11a0 <crank+0xa0>
lea    -0x1(%rdx),%r14
lea    (%rdx,%r15,1),%rax
add    $0xffffffffffffffff,%rax
movq   %rax,%xmm4
punpckldq %xmm0,%xmm4
subpd  %xmm1,%xmm4
movapd %xmm4,%xmm3
unpckhpd %xmm4,%xmm3
addsd  %xmm4,%xmm3
mulsd  %xmm2,%xmm3
cmp    %r14,%r15
ja     1140 <crank+0x40>
cmp    %r10,%rdx
cmova  %rdx,%r10
cvtsd2ss %xmm3,%xmm3
sub    %r15,%r10
mov    %r15,%rdx
cmp    $0x8,%r10
jb     12e0 <crank+0x1e0>
mov    %r10,%rdx
and    $0xfffffffffffffff8,%rdx
movaps %xmm3,%xmm4
shufps $0x0,%xmm3,%xmm4
lea    -0x8(%rdx),%rax
mov    %rax,%rbx
shr    $0x3,%rbx
add    $0x1,%rbx
mov    %ebx,%r11d
and    $0x3,%r11d
cmp    $0x18,%rax
jae    1266 <crank+0x166>
xor    %ecx,%ecx
jmp    12a1 <crank+0x1a1>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %r15,%rax
shr    %rax
mov    %r15d,%ecx
and    $0x1,%ecx
or     %rax,%rcx
xorps  %xmm3,%xmm3
cvtsi2ss %rcx,%xmm3
addss  %xmm3,%xmm3
movss  %xmm3,(%rsi,%r15,4)
jmp    1143 <crank+0x43>
and    $0xfffffffffffffffc,%rbx
lea    (%r8,%r15,4),%rax
xor    %ecx,%ecx
movups %xmm4,-0x70(%rax,%rcx,4)
movups %xmm4,-0x60(%rax,%rcx,4)
movups %xmm4,-0x50(%rax,%rcx,4)
movups %xmm4,-0x40(%rax,%rcx,4)
movups %xmm4,-0x30(%rax,%rcx,4)
movups %xmm4,-0x20(%rax,%rcx,4)
movups %xmm4,-0x10(%rax,%rcx,4)
movups %xmm4,(%rax,%rcx,4)
add    $0x20,%rcx
add    $0xfffffffffffffffc,%rbx
jne    1270 <crank+0x170>
test   %r11,%r11
je     12d2 <crank+0x1d2>
add    %r15,%rcx
lea    (%r9,%rcx,4),%rax
shl    $0x5,%r11
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movups %xmm4,-0x10(%rax,%rcx,1)
movups %xmm4,(%rax,%rcx,1)
add    $0x20,%rcx
cmp    %rcx,%r11
jne    12c0 <crank+0x1c0>
cmp    %rdx,%r10
je     1140 <crank+0x40>
add    %r15,%rdx
xchg   %ax,%ax
movss  %xmm3,(%rsi,%rdx,4)
add    $0x1,%rdx
cmp    %r14,%rdx
jbe    12e0 <crank+0x1e0>
jmp    1140 <crank+0x40>
cmp    %rdi,%r10
jne    1326 <crank+0x226>
test   %rdi,%rdi
js     1307 <crank+0x207>
xorps  %xmm0,%xmm0
cvtsi2ss %rdi,%xmm0
jmp    1321 <crank+0x221>
mov    %rdi,%rax
shr    %rax
mov    %edi,%ecx
and    $0x1,%ecx
or     %rax,%rcx
xorps  %xmm0,%xmm0
cvtsi2ss %rcx,%xmm0
addss  %xmm0,%xmm0
movss  %xmm0,(%rsi,%rdi,4)
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @crank(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* %5
br label %9
9: ; preds = %78, %2
%10 = load i64, i64* %5
%11 = load i64, i64* %3
%12 = icmp ult i64 %10, %11
br i1 %12, label %13, label %79
13: ; preds = %9
%14 = load float*, float** %4
%15 = load i64, i64* %5
%16 = add i64 %15, 1
%17 = getelementptr inbounds float, float* %14, i64 %16
%18 = load float, float* %17
%19 = load float*, float** %4
%20 = load i64, i64* %5
%21 = getelementptr inbounds float, float* %19, i64 %20
%22 = load float, float* %21
%23 = fcmp une float %18, %22
br i1 %23, label %24, label %32
24: ; preds = %13
%25 = load i64, i64* %5
%26 = uitofp i64 %25 to float
%27 = load float*, float** %4
%28 = load i64, i64* %5
%29 = getelementptr inbounds float, float* %27, i64 %28
store float %26, float* %29
%30 = load i64, i64* %5
%31 = add i64 %30, 1
store i64 %31, i64* %5
br label %78
32: ; preds = %13
%33 = load i64, i64* %5
%34 = add i64 %33, 1
store i64 %34, i64* %7
br label %35
35: ; preds = %52, %32
%36 = load i64, i64* %7
%37 = load i64, i64* %3
%38 = icmp ule i64 %36, %37
br i1 %38, label %39, label %49
39: ; preds = %35
%40 = load float*, float** %4
%41 = load i64, i64* %7
%42 = getelementptr inbounds float, float* %40, i64 %41
%43 = load float, float* %42
%44 = load float*, float** %4
%45 = load i64, i64* %5
%46 = getelementptr inbounds float, float* %44, i64 %45
%47 = load float, float* %46
%48 = fcmp oeq float %43, %47
br label %49
49: ; preds = %39, %35
%50 = phi i1 [ false, %35 ], [ %48, %39 ]
br i1 %50, label %51, label %55
51: ; preds = %49
br label %52
52: ; preds = %51
%53 = load i64, i64* %7
%54 = add i64 %53, 1
store i64 %54, i64* %7
br label %35
55: ; preds = %49
%56 = load i64, i64* %5
%57 = load i64, i64* %7
%58 = add i64 %56, %57
%59 = sub i64 %58, 1
%60 = uitofp i64 %59 to double
%61 = fmul double 5.000000e-01, %60
%62 = fptrunc double %61 to float
store float %62, float* %8
%63 = load i64, i64* %5
store i64 %63, i64* %6
br label %64
64: ; preds = %74, %55
%65 = load i64, i64* %6
%66 = load i64, i64* %7
%67 = sub i64 %66, 1
%68 = icmp ule i64 %65, %67
br i1 %68, label %69, label %77
69: ; preds = %64
%70 = load float, float* %8
%71 = load float*, float** %4
%72 = load i64, i64* %6
%73 = getelementptr inbounds float, float* %71, i64 %72
store float %70, float* %73
br label %74
74: ; preds = %69
%75 = load i64, i64* %6
%76 = add i64 %75, 1
store i64 %76, i64* %6
br label %64
77: ; preds = %64
br label %78
78: ; preds = %77, %24
br label %9
79: ; preds = %9
%80 = load i64, i64* %5
%81 = load i64, i64* %3
%82 = icmp eq i64 %80, %81
br i1 %82, label %83, label %89
83: ; preds = %79
%84 = load i64, i64* %3
%85 = uitofp i64 %84 to float
%86 = load float*, float** %4
%87 = load i64, i64* %3
%88 = getelementptr inbounds float, float* %86, i64 %87
store float %85, float* %88
br label %89
89: ; preds = %83, %79
ret void
}

LLVM IR (-O2):
define void @crank(i64 %0, float* nocapture %1) {
%3 = icmp ugt i64 %0, 1
br i1 %3, label %4, label %107
4: ; preds = %2, %104
%5 = phi i64 [ %105, %104 ], [ 1, %2 ]
%6 = add nuw i64 %5, 1
%7 = getelementptr inbounds float, float* %1, i64 %6
%8 = load float, float* %7
%9 = getelementptr inbounds float, float* %1, i64 %5
%10 = load float, float* %9
%11 = fcmp une float %8, %10
br i1 %11, label %16, label %12
12: ; preds = %4
%13 = icmp ult i64 %5, %0
%14 = fcmp oeq float %8, %10
%15 = select i1 %13, i1 %14, i1 false
br i1 %15, label %18, label %26
16: ; preds = %4
%17 = uitofp i64 %5 to float
store float %17, float* %9
br label %104
18: ; preds = %12, %22
%19 = phi i64 [ %20, %22 ], [ %6, %12 ]
%20 = add i64 %19, 1
%21 = icmp ugt i64 %20, %0
br i1 %21, label %26, label %22
22: ; preds = %18
%23 = getelementptr inbounds float, float* %1, i64 %20
%24 = load float, float* %23
%25 = fcmp oeq float %24, %10
br i1 %25, label %18, label %26
26: ; preds = %18, %22, %12
%27 = phi i64 [ %6, %12 ], [ %20, %22 ], [ %20, %18 ]
%28 = add i64 %27, -1
%29 = add i64 %28, %5
%30 = uitofp i64 %29 to double
%31 = fmul double %30, 5.000000e-01
%32 = fptrunc double %31 to float
%33 = icmp ugt i64 %5, %28
br i1 %33, label %104, label %34
34: ; preds = %26
%35 = call i64 @llvm.umax.i64(i64 %27, i64 %6)
%36 = sub i64 %35, %5
%37 = icmp ult i64 %36, 8
br i1 %37, label %97, label %38
38: ; preds = %34
%39 = and i64 %36, -8
%40 = add i64 %5, %39
%41 = insertelement <4 x float> poison, float %32, i64 0
%42 = shufflevector <4 x float> %41, <4 x float> poison, <4 x i32> zeroinitializer
%43 = insertelement <4 x float> poison, float %32, i64 0
%44 = shufflevector <4 x float> %43, <4 x float> poison, <4 x i32> zeroinitializer
%45 = add i64 %39, -8
%46 = lshr exact i64 %45, 3
%47 = add nuw nsw i64 %46, 1
%48 = and i64 %47, 3
%49 = icmp ult i64 %45, 24
br i1 %49, label %81, label %50
50: ; preds = %38
%51 = and i64 %47, 4611686018427387900
br label %52
52: ; preds = %52, %50
%53 = phi i64 [ 0, %50 ], [ %78, %52 ]
%54 = phi i64 [ 0, %50 ], [ %79, %52 ]
%55 = add i64 %5, %53
%56 = getelementptr inbounds float, float* %1, i64 %55
%57 = bitcast float* %56 to <4 x float>*
store <4 x float> %42, <4 x float>* %57
%58 = getelementptr inbounds float, float* %56, i64 4
%59 = bitcast float* %58 to <4 x float>*
store <4 x float> %44, <4 x float>* %59
%60 = or i64 %53, 8
%61 = add i64 %5, %60
%62 = getelementptr inbounds float, float* %1, i64 %61
%63 = bitcast float* %62 to <4 x float>*
store <4 x float> %42, <4 x float>* %63
%64 = getelementptr inbounds float, float* %62, i64 4
%65 = bitcast float* %64 to <4 x float>*
store <4 x float> %44, <4 x float>* %65
%66 = or i64 %53, 16
%67 = add i64 %5, %66
%68 = getelementptr inbounds float, float* %1, i64 %67
%69 = bitcast float* %68 to <4 x float>*
store <4 x float> %42, <4 x float>* %69
%70 = getelementptr inbounds float, float* %68, i64 4
%71 = bitcast float* %70 to <4 x float>*
store <4 x float> %44, <4 x float>* %71
%72 = or i64 %53, 24
%73 = add i64 %5, %72
%74 = getelementptr inbounds float, float* %1, i64 %73
%75 = bitcast float* %74 to <4 x float>*
store <4 x float> %42, <4 x float>* %75
%76 = getelementptr inbounds float, float* %74, i64 4
%77 = bitcast float* %76 to <4 x float>*
store <4 x float> %44, <4 x float>* %77
%78 = add nuw i64 %53, 32
%79 = add i64 %54, 4
%80 = icmp eq i64 %79, %51
br i1 %80, label %81, label %52
81: ; preds = %52, %38
%82 = phi i64 [ 0, %38 ], [ %78, %52 ]
%83 = icmp eq i64 %48, 0
br i1 %83, label %95, label %84
84: ; preds = %81, %84
%85 = phi i64 [ %92, %84 ], [ %82, %81 ]
%86 = phi i64 [ %93, %84 ], [ 0, %81 ]
%87 = add i64 %5, %85
%88 = getelementptr inbounds float, float* %1, i64 %87
%89 = bitcast float* %88 to <4 x float>*
store <4 x float> %42, <4 x float>* %89
%90 = getelementptr inbounds float, float* %88, i64 4
%91 = bitcast float* %90 to <4 x float>*
store <4 x float> %44, <4 x float>* %91
%92 = add nuw i64 %85, 8
%93 = add i64 %86, 1
%94 = icmp eq i64 %93, %48
br i1 %94, label %95, label %84
95: ; preds = %84, %81
%96 = icmp eq i64 %36, %39
br i1 %96, label %104, label %97
97: ; preds = %34, %95
%98 = phi i64 [ %5, %34 ], [ %40, %95 ]
br label %99
99: ; preds = %97, %99
%100 = phi i64 [ %102, %99 ], [ %98, %97 ]
%101 = getelementptr inbounds float, float* %1, i64 %100
store float %32, float* %101
%102 = add i64 %100, 1
%103 = icmp ugt i64 %102, %28
br i1 %103, label %104, label %99
104: ; preds = %99, %95, %26, %16
%105 = phi i64 [ %6, %16 ], [ %5, %26 ], [ %5, %95 ], [ %5, %99 ]
%106 = icmp ult i64 %105, %0
br i1 %106, label %4, label %107
107: ; preds = %104, %2
%108 = phi i64 [ 1, %2 ], [ %105, %104 ]
%109 = icmp eq i64 %108, %0
br i1 %109, label %110, label %113
110: ; preds = %107
%111 = uitofp i64 %0 to float
%112 = getelementptr inbounds float, float* %1, i64 %0
store float %111, float* %112
br label %113
113: ; preds = %110, %107
ret void
}