double halton2(int i) {
  unsigned long h, f;
  h = i & 1;
  f = 2;
  i >>= 1;
  while (i) {
    h <<= 1;
    h += (i & 1);
    i >>= 1;
    f <<= 1;
    h <<= 1;
    h += (i & 1);
    i >>= 1;
    f <<= 1;
    h <<= 1;
    h += (i & 1);
    i >>= 1;
    f <<= 1;
    h <<= 1;
    h += (i & 1);
    i >>= 1;
    f <<= 1;
  }
  return (double)h / (double)f;
}


x86 assembly (clang, -O0):
<halton2>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    -0x4(%rbp),%eax
and    $0x1,%eax
cltq
mov    %rax,-0x10(%rbp)
movq   $0x2,-0x18(%rbp)
mov    -0x4(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x4(%rbp)
cmpl   $0x0,-0x4(%rbp)
je     11f7 <halton2+0xf7>
mov    -0x10(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x4(%rbp),%eax
and    $0x1,%eax
cltq
add    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x4(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x4(%rbp)
mov    -0x18(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x4(%rbp),%eax
and    $0x1,%eax
cltq
add    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x4(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x4(%rbp)
mov    -0x18(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x4(%rbp),%eax
and    $0x1,%eax
cltq
add    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x4(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x4(%rbp)
mov    -0x18(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x4(%rbp),%eax
and    $0x1,%eax
cltq
add    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x4(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x4(%rbp)
mov    -0x18(%rbp),%rax
shl    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    1124 <halton2+0x24>
movq   -0x10(%rbp),%xmm0
movaps 0xdfd(%rip),%xmm3
punpckldq %xmm3,%xmm0
movapd 0xe01(%rip),%xmm2
subpd  %xmm2,%xmm0
movaps %xmm0,%xmm1
unpckhpd %xmm0,%xmm0
addsd  %xmm1,%xmm0
movq   -0x18(%rbp),%xmm1
punpckldq %xmm3,%xmm1
subpd  %xmm2,%xmm1
movaps %xmm1,%xmm2
unpckhpd %xmm1,%xmm1
addsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<halton2>:
mov    %edi,%eax
and    $0x1,%eax
cmp    $0x2,%edi
jae    1114 <halton2+0x14>
movsd  0xeee(%rip),%xmm1
jmp    1174 <halton2+0x74>
mov    $0x2,%r8d
mov    %edi,%edx
nopl   0x0(%rax)
mov    %edi,%esi
and    $0x2,%esi
mov    %edi,%ecx
shr    $0x2,%ecx
shl    $0x4,%r8
lea    (%rsi,%rax,4),%rax
mov    %ecx,%esi
and    $0x1,%esi
or     %rax,%rsi
sar    $0x4,%edx
and    $0x2,%ecx
lea    (%rcx,%rsi,4),%rcx
mov    %edx,%eax
and    $0x1,%eax
or     %rcx,%rax
cmp    $0x1f,%edi
mov    %edx,%edi
ja     1120 <halton2+0x20>
movq   %r8,%xmm0
punpckldq 0xeb0(%rip),%xmm0
subpd  0xeb8(%rip),%xmm0
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
addsd  %xmm0,%xmm1
movq   %rax,%xmm2
punpckldq 0xe8f(%rip),%xmm2
subpd  0xe97(%rip),%xmm2
movapd %xmm2,%xmm0
unpckhpd %xmm2,%xmm0
addsd  %xmm2,%xmm0
divsd  %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @halton2(i32 %0) {
%2 = alloca i32
%3 = alloca i64
%4 = alloca i64
store i32 %0, i32* %2
%5 = load i32, i32* %2
%6 = and i32 %5, 1
%7 = sext i32 %6 to i64
store i64 %7, i64* %3
store i64 2, i64* %4
%8 = load i32, i32* %2
%9 = ashr i32 %8, 1
store i32 %9, i32* %2
br label %10
10: ; preds = %13, %1
%11 = load i32, i32* %2
%12 = icmp ne i32 %11, 0
br i1 %12, label %13, label %58
13: ; preds = %10
%14 = load i64, i64* %3
%15 = shl i64 %14, 1
store i64 %15, i64* %3
%16 = load i32, i32* %2
%17 = and i32 %16, 1
%18 = sext i32 %17 to i64
%19 = load i64, i64* %3
%20 = add i64 %19, %18
store i64 %20, i64* %3
%21 = load i32, i32* %2
%22 = ashr i32 %21, 1
store i32 %22, i32* %2
%23 = load i64, i64* %4
%24 = shl i64 %23, 1
store i64 %24, i64* %4
%25 = load i64, i64* %3
%26 = shl i64 %25, 1
store i64 %26, i64* %3
%27 = load i32, i32* %2
%28 = and i32 %27, 1
%29 = sext i32 %28 to i64
%30 = load i64, i64* %3
%31 = add i64 %30, %29
store i64 %31, i64* %3
%32 = load i32, i32* %2
%33 = ashr i32 %32, 1
store i32 %33, i32* %2
%34 = load i64, i64* %4
%35 = shl i64 %34, 1
store i64 %35, i64* %4
%36 = load i64, i64* %3
%37 = shl i64 %36, 1
store i64 %37, i64* %3
%38 = load i32, i32* %2
%39 = and i32 %38, 1
%40 = sext i32 %39 to i64
%41 = load i64, i64* %3
%42 = add i64 %41, %40
store i64 %42, i64* %3
%43 = load i32, i32* %2
%44 = ashr i32 %43, 1
store i32 %44, i32* %2
%45 = load i64, i64* %4
%46 = shl i64 %45, 1
store i64 %46, i64* %4
%47 = load i64, i64* %3
%48 = shl i64 %47, 1
store i64 %48, i64* %3
%49 = load i32, i32* %2
%50 = and i32 %49, 1
%51 = sext i32 %50 to i64
%52 = load i64, i64* %3
%53 = add i64 %52, %51
store i64 %53, i64* %3
%54 = load i32, i32* %2
%55 = ashr i32 %54, 1
store i32 %55, i32* %2
%56 = load i64, i64* %4
%57 = shl i64 %56, 1
store i64 %57, i64* %4
br label %10
58: ; preds = %10
%59 = load i64, i64* %3
%60 = uitofp i64 %59 to double
%61 = load i64, i64* %4
%62 = uitofp i64 %61 to double
%63 = fdiv double %60, %62
ret double %63
}

LLVM IR (-O2):
define double @halton2(i32 %0) {
%2 = and i32 %0, 1
%3 = zext i32 %2 to i64
%4 = icmp ult i32 %0, 2
br i1 %4, label %29, label %5
5: ; preds = %1, %5
%6 = phi i64 [ %11, %5 ], [ 2, %1 ]
%7 = phi i64 [ %25, %5 ], [ %3, %1 ]
%8 = phi i32 [ %18, %5 ], [ %0, %1 ]
%9 = and i32 %8, 2
%10 = lshr i32 %8, 2
%11 = shl i64 %6, 4
%12 = shl i64 %7, 2
%13 = zext i32 %9 to i64
%14 = or i64 %12, %13
%15 = and i32 %10, 1
%16 = zext i32 %15 to i64
%17 = or i64 %14, %16
%18 = ashr i32 %8, 4
%19 = shl i64 %17, 2
%20 = and i32 %10, 2
%21 = zext i32 %20 to i64
%22 = or i64 %19, %21
%23 = and i32 %18, 1
%24 = zext i32 %23 to i64
%25 = or i64 %22, %24
%26 = icmp ult i32 %8, 32
br i1 %26, label %27, label %5
27: ; preds = %5
%28 = uitofp i64 %11 to double
br label %29
29: ; preds = %27, %1
%30 = phi i64 [ %3, %1 ], [ %25, %27 ]
%31 = phi double [ 2.000000e+00, %1 ], [ %28, %27 ]
%32 = uitofp i64 %30 to double
%33 = fdiv double %32, %31
ret double %33
}