void bit_reverse(float *x, long N) {
  float rtemp, itemp;
  long i, j, m;
  for (i = j = 0; i < N; i += 2, j += m) {
    if (j > i) {
      rtemp = x[j];
      itemp = x[j + 1];
      x[j] = x[i];
      x[j + 1] = x[i + 1];
      x[i] = rtemp;
      x[i + 1] = itemp;
    }
    for (m = N >> 1; m >= 2 && j >= m; m >>= 1)
      j -= m;
  }
}


x86 assembly (clang, -O0):
<bit_reverse>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movq   $0x0,-0x28(%rbp)
movq   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x10(%rbp),%rax
jge    1234 <bit_reverse+0x134>
mov    -0x28(%rbp),%rax
cmp    -0x20(%rbp),%rax
jle    11b8 <bit_reverse+0xb8>
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x14(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
movss  0x4(%rax,%rcx,4),%xmm0
movss  %xmm0,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
movss  0x4(%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
movss  %xmm0,0x4(%rax,%rcx,4)
movss  -0x14(%rbp),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
movss  -0x18(%rbp),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
movss  %xmm0,0x4(%rax,%rcx,4)
mov    -0x10(%rbp),%rax
sar    $0x1,%rax
mov    %rax,-0x30(%rbp)
xor    %eax,%eax
cmpq   $0x2,-0x30(%rbp)
mov    %al,-0x31(%rbp)
jl     11e2 <bit_reverse+0xe2>
mov    -0x28(%rbp),%rax
cmp    -0x30(%rbp),%rax
setge  %al
mov    %al,-0x31(%rbp)
mov    -0x31(%rbp),%al
test   $0x1,%al
jne    11f2 <bit_reverse+0xf2>
jmp    1212 <bit_reverse+0x112>
mov    -0x30(%rbp),%rcx
mov    -0x28(%rbp),%rax
sub    %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x30(%rbp),%rax
sar    $0x1,%rax
mov    %rax,-0x30(%rbp)
jmp    11c4 <bit_reverse+0xc4>
jmp    1217 <bit_reverse+0x117>
mov    -0x20(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x20(%rbp)
mov    -0x30(%rbp),%rax
add    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
jmp    111c <bit_reverse+0x1c>
pop    %rbp
ret

x86 assembly (clang, -O2):
<bit_reverse>:
test   %rsi,%rsi
jle    1179 <bit_reverse+0x79>
xor    %ecx,%ecx
xor    %r8d,%r8d
jmp    111f <bit_reverse+0x1f>
nopl   0x0(%rax)
add    $0x2,%r8
add    %rax,%rdx
mov    %rdx,%rcx
cmp    %rsi,%r8
jge    1179 <bit_reverse+0x79>
cmp    %r8,%rcx
jle    115c <bit_reverse+0x5c>
movss  (%rdi,%rcx,4),%xmm0
movss  0x4(%rdi,%rcx,4),%xmm1
lea    0x0(,%r8,4),%rax
movss  (%rdi,%r8,4),%xmm2
movss  %xmm2,(%rdi,%rcx,4)
or     $0x4,%rax
movss  (%rdi,%rax,1),%xmm2
movss  %xmm2,0x4(%rdi,%rcx,4)
movss  %xmm0,(%rdi,%r8,4)
movss  %xmm1,(%rdi,%rax,1)
mov    %rsi,%rdx
nop
mov    %rdx,%r9
mov    %rcx,%rax
sar    %rdx
cmp    $0x4,%r9
jl     1110 <bit_reverse+0x10>
mov    %rax,%rcx
sub    %rdx,%rcx
jge    1160 <bit_reverse+0x60>
jmp    1110 <bit_reverse+0x10>
ret

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

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