void airHalton(double *out, unsigned int indx, const unsigned int *base,
               unsigned int num) {
  unsigned int nn, bb;
  for (nn = 0; nn < num; nn++) {
    double ff, result = 0.0;
    unsigned int ii;
    bb = base[nn];
    ff = 1.0 / bb;
    ii = indx;
    while (ii) {
      result += ff * (ii % bb);
      ii /= bb;
      ff /= bb;
    }
    out[nn] = result;
  }
  return;
}


x86 assembly (clang, -O0):
<airHalton>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
movl   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jae    11d6 <airHalton+0xd6>
movq   $0x0,-0x38(%rbp)
mov    -0x18(%rbp),%rax
mov    -0x20(%rbp),%ecx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cvtsi2sd %rax,%xmm1
movsd  0xeb6(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,-0x3c(%rbp)
cmpl   $0x0,-0x3c(%rbp)
je     11b7 <airHalton+0xb7>
movsd  -0x30(%rbp),%xmm0
mov    -0x3c(%rbp),%eax
mov    -0x24(%rbp),%ecx
xor    %edx,%edx
mov    %edx,-0x40(%rbp)
div    %ecx
mov    %edx,%eax
mov    -0x40(%rbp),%edx
cvtsi2sd %rax,%xmm2
movsd  -0x38(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x24(%rbp),%ecx
mov    -0x3c(%rbp),%eax
div    %ecx
mov    %eax,-0x3c(%rbp)
mov    -0x24(%rbp),%eax
cvtsi2sd %rax,%xmm1
movsd  -0x30(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    1159 <airHalton+0x59>
movsd  -0x38(%rbp),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1119 <airHalton+0x19>
pop    %rbp
ret

x86 assembly (clang, -O2):
<airHalton>:
test   %ecx,%ecx
je     1174 <airHalton+0x74>
mov    %rdx,%r8
mov    %ecx,%r9d
xor    %r10d,%r10d
movsd  0xeeb(%rip),%xmm0
jmp    1133 <airHalton+0x33>
nopw   0x0(%rax,%rax,1)
xorpd  %xmm1,%xmm1
movsd  %xmm1,(%rdi,%r10,8)
add    $0x1,%r10
cmp    %r9,%r10
je     1174 <airHalton+0x74>
test   %esi,%esi
je     1120 <airHalton+0x20>
mov    (%r8,%r10,4),%r11d
xorps  %xmm2,%xmm2
cvtsi2sd %r11,%xmm2
xorpd  %xmm1,%xmm1
movapd %xmm0,%xmm3
mov    %esi,%ecx
nopl   (%rax)
mov    %ecx,%eax
xor    %edx,%edx
div    %r11d
xorps  %xmm4,%xmm4
cvtsi2sd %rdx,%xmm4
divsd  %xmm2,%xmm3
mulsd  %xmm3,%xmm4
addsd  %xmm4,%xmm1
cmp    %ecx,%r11d
mov    %eax,%ecx
jbe    1150 <airHalton+0x50>
jmp    1124 <airHalton+0x24>
ret

LLVM IR (-O0):
define void @airHalton(double* %0, i32 %1, i32* %2, i32 %3) {
%5 = alloca double*
%6 = alloca i32
%7 = alloca i32*
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca double
%12 = alloca double
%13 = alloca i32
store double* %0, double** %5
store i32 %1, i32* %6
store i32* %2, i32** %7
store i32 %3, i32* %8
store i32 0, i32* %9
br label %14
14: ; preds = %52, %4
%15 = load i32, i32* %9
%16 = load i32, i32* %8
%17 = icmp ult i32 %15, %16
br i1 %17, label %18, label %55
18: ; preds = %14
store double 0.000000e+00, double* %12
%19 = load i32*, i32** %7
%20 = load i32, i32* %9
%21 = zext i32 %20 to i64
%22 = getelementptr inbounds i32, i32* %19, i64 %21
%23 = load i32, i32* %22
store i32 %23, i32* %10
%24 = load i32, i32* %10
%25 = uitofp i32 %24 to double
%26 = fdiv double 1.000000e+00, %25
store double %26, double* %11
%27 = load i32, i32* %6
store i32 %27, i32* %13
br label %28
28: ; preds = %31, %18
%29 = load i32, i32* %13
%30 = icmp ne i32 %29, 0
br i1 %30, label %31, label %46
31: ; preds = %28
%32 = load double, double* %11
%33 = load i32, i32* %13
%34 = load i32, i32* %10
%35 = urem i32 %33, %34
%36 = uitofp i32 %35 to double
%37 = load double, double* %12
%38 = call double @llvm.fmuladd.f64(double %32, double %36, double %37)
store double %38, double* %12
%39 = load i32, i32* %10
%40 = load i32, i32* %13
%41 = udiv i32 %40, %39
store i32 %41, i32* %13
%42 = load i32, i32* %10
%43 = uitofp i32 %42 to double
%44 = load double, double* %11
%45 = fdiv double %44, %43
store double %45, double* %11
br label %28
46: ; preds = %28
%47 = load double, double* %12
%48 = load double*, double** %5
%49 = load i32, i32* %9
%50 = zext i32 %49 to i64
%51 = getelementptr inbounds double, double* %48, i64 %50
store double %47, double* %51
br label %52
52: ; preds = %46
%53 = load i32, i32* %9
%54 = add i32 %53, 1
store i32 %54, i32* %9
br label %14
55: ; preds = %14
ret void
}

LLVM IR (-O2):
define void @airHalton(double* nocapture writeonly %0, i32 %1, i32* nocapture %2, i32 %3) {
%5 = icmp eq i32 %3, 0
br i1 %5, label %29, label %6
6: ; preds = %4
%7 = icmp eq i32 %1, 0
%8 = zext i32 %3 to i64
br label %9
9: ; preds = %6, %24
%10 = phi i64 [ 0, %6 ], [ %27, %24 ]
%11 = getelementptr inbounds i32, i32* %2, i64 %10
%12 = load i32, i32* %11
%13 = uitofp i32 %12 to double
br i1 %7, label %24, label %14
14: ; preds = %9, %14
%15 = phi double [ %18, %14 ], [ 1.000000e+00, %9 ]
%16 = phi i32 [ %22, %14 ], [ %1, %9 ]
%17 = phi double [ %21, %14 ], [ 0.000000e+00, %9 ]
%18 = fdiv double %15, %13
%19 = urem i32 %16, %12
%20 = uitofp i32 %19 to double
%21 = tail call double @llvm.fmuladd.f64(double %18, double %20, double %17)
%22 = udiv i32 %16, %12
%23 = icmp ugt i32 %12, %16
br i1 %23, label %24, label %14
24: ; preds = %14, %9
%25 = phi double [ 0.000000e+00, %9 ], [ %21, %14 ]
%26 = getelementptr inbounds double, double* %0, i64 %10
store double %25, double* %26
%27 = add nuw nsw i64 %10, 1
%28 = icmp eq i64 %27, %8
br i1 %28, label %29, label %9
29: ; preds = %24, %4
ret void
}