long long nqueen_solver1(int size, int idx) {
  unsigned int masks[32];
  unsigned int left_masks[32];
  unsigned int right_masks[32];
  unsigned int ms[32];
  unsigned int ns;
  long long solutions = 0;
  int i = 0;
  masks[0] = 1 | 1 << idx;
  left_masks[0] = (1 << 2) | (1 << (idx + 1));
  right_masks[0] = (1 << idx) >> 1;
  ms[0] = masks[0] | left_masks[0] | right_masks[0];
  unsigned int board_mask = (1 << size) - 1;
  while (i >= 0) {
    unsigned int m = ms[i] | ((i + 2) < idx ? 2 : 0);
    ns = (m + 1) & ~m;
    if ((ns & board_mask) != 0) {
      if (i == size - 3) {
        solutions++;
        i--;
      } else {
        ms[i] |= ns;
        masks[i + 1] = masks[i] | ns;
        left_masks[i + 1] = (left_masks[i] | ns) << 1;
        right_masks[i + 1] = (right_masks[i] | ns) >> 1;
        ms[i + 1] = masks[i + 1] | left_masks[i + 1] | right_masks[i + 1];
        i++;
      }
    } else {
      i--;
    }
  }
  return solutions;
}


x86 assembly (clang, -O0):
<nqueen_solver1>:
push   %rbp
mov    %rsp,%rbp
sub    $0x1b0,%rsp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
movq   $0x0,-0x220(%rbp)
movl   $0x0,-0x224(%rbp)
mov    -0x8(%rbp),%ecx
mov    $0x1,%eax
shl    %cl,%eax
or     $0x1,%eax
mov    %eax,-0x90(%rbp)
mov    -0x8(%rbp),%ecx
add    $0x1,%ecx
mov    $0x1,%eax
shl    %cl,%eax
or     $0x4,%eax
mov    %eax,-0x110(%rbp)
mov    -0x8(%rbp),%ecx
mov    $0x1,%eax
shl    %cl,%eax
sar    $0x1,%eax
mov    %eax,-0x190(%rbp)
mov    -0x90(%rbp),%eax
or     -0x110(%rbp),%eax
or     -0x190(%rbp),%eax
mov    %eax,-0x210(%rbp)
mov    -0x4(%rbp),%ecx
mov    $0x1,%eax
shl    %cl,%eax
sub    $0x1,%eax
mov    %eax,-0x228(%rbp)
cmpl   $0x0,-0x224(%rbp)
jl     1334 <nqueen_solver1+0x234>
movslq -0x224(%rbp),%rax
mov    -0x210(%rbp,%rax,4),%eax
mov    -0x224(%rbp),%esi
add    $0x2,%esi
mov    -0x8(%rbp),%edi
xor    %ecx,%ecx
mov    $0x2,%edx
cmp    %edi,%esi
cmovl  %edx,%ecx
or     %ecx,%eax
mov    %eax,-0x22c(%rbp)
mov    -0x22c(%rbp),%eax
add    $0x1,%eax
mov    -0x22c(%rbp),%ecx
xor    $0xffffffff,%ecx
and    %ecx,%eax
mov    %eax,-0x214(%rbp)
mov    -0x214(%rbp),%eax
and    -0x228(%rbp),%eax
cmp    $0x0,%eax
je     1320 <nqueen_solver1+0x220>
mov    -0x224(%rbp),%eax
mov    -0x4(%rbp),%ecx
sub    $0x3,%ecx
cmp    %ecx,%eax
jne    1231 <nqueen_solver1+0x131>
mov    -0x220(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x220(%rbp)
mov    -0x224(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x224(%rbp)
jmp    131b <nqueen_solver1+0x21b>
mov    -0x214(%rbp),%ecx
movslq -0x224(%rbp),%rax
or     -0x210(%rbp,%rax,4),%ecx
mov    %ecx,-0x210(%rbp,%rax,4)
movslq -0x224(%rbp),%rax
mov    -0x90(%rbp,%rax,4),%ecx
or     -0x214(%rbp),%ecx
mov    -0x224(%rbp),%eax
add    $0x1,%eax
cltq
mov    %ecx,-0x90(%rbp,%rax,4)
movslq -0x224(%rbp),%rax
mov    -0x110(%rbp,%rax,4),%ecx
or     -0x214(%rbp),%ecx
shl    $0x1,%ecx
mov    -0x224(%rbp),%eax
add    $0x1,%eax
cltq
mov    %ecx,-0x110(%rbp,%rax,4)
movslq -0x224(%rbp),%rax
mov    -0x190(%rbp,%rax,4),%ecx
or     -0x214(%rbp),%ecx
shr    $0x1,%ecx
mov    -0x224(%rbp),%eax
add    $0x1,%eax
cltq
mov    %ecx,-0x190(%rbp,%rax,4)
mov    -0x224(%rbp),%eax
add    $0x1,%eax
cltq
mov    -0x90(%rbp,%rax,4),%ecx
mov    -0x224(%rbp),%eax
add    $0x1,%eax
cltq
or     -0x110(%rbp,%rax,4),%ecx
mov    -0x224(%rbp),%eax
add    $0x1,%eax
cltq
or     -0x190(%rbp,%rax,4),%ecx
mov    -0x224(%rbp),%eax
add    $0x1,%eax
cltq
mov    %ecx,-0x210(%rbp,%rax,4)
mov    -0x224(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x224(%rbp)
jmp    132f <nqueen_solver1+0x22f>
mov    -0x224(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x224(%rbp)
jmp    118d <nqueen_solver1+0x8d>
mov    -0x220(%rbp),%rax
add    $0x1b0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<nqueen_solver1>:
push   %rbx
sub    $0x180,%rsp
mov    %esi,%r10d
mov    %edi,%r8d
mov    $0x1,%eax
mov    $0x1,%edx
mov    %r10d,%ecx
shl    %cl,%edx
bts    %esi,%eax
mov    %eax,0x100(%rsp)
lea    0x1(%r10),%ecx
mov    $0x4,%edi
bts    %ecx,%edi
mov    %edi,0x80(%rsp)
sar    %edx
mov    %edx,(%rsp)
or     %eax,%edi
or     %edx,%edi
mov    %edi,-0x80(%rsp)
mov    $0xffffffff,%r11d
mov    %r8d,%ecx
shl    %cl,%r11d
not    %r11d
lea    -0x3(%r8),%r9d
add    $0xfffffffc,%r8d
xor    %eax,%eax
xor    %esi,%esi
jmp    11b2 <nqueen_solver1+0xb2>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
or     %edx,%edi
mov    %edi,-0x80(%rsp,%rcx,4)
mov    0x100(%rsp,%rcx,4),%edi
or     %edx,%edi
lea    0x1(%rcx),%esi
mov    %edi,0x104(%rsp,%rcx,4)
mov    0x80(%rsp,%rcx,4),%ebx
or     %edx,%ebx
add    %ebx,%ebx
mov    %ebx,0x84(%rsp,%rcx,4)
or     (%rsp,%rcx,4),%edx
shr    %edx
mov    %edx,0x4(%rsp,%rcx,4)
or     %edi,%ebx
or     %edx,%ebx
mov    %ebx,-0x7c(%rsp,%rcx,4)
mov    %esi,%ecx
mov    -0x80(%rsp,%rcx,4),%edi
mov    %esi,%ecx
add    $0x2,%esi
xor    %edx,%edx
cmp    %r10d,%esi
setl   %dl
add    %edx,%edx
or     %edi,%edx
lea    0x1(%rdx),%esi
not    %edx
and    %esi,%edx
test   %r11d,%edx
je     11f0 <nqueen_solver1+0xf0>
cmp    %r9d,%ecx
jne    1170 <nqueen_solver1+0x70>
add    $0x1,%rax
mov    %r8d,%esi
test   %esi,%esi
jns    11ac <nqueen_solver1+0xac>
jmp    11f9 <nqueen_solver1+0xf9>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
add    $0xffffffff,%ecx
mov    %ecx,%esi
test   %esi,%esi
jns    11ac <nqueen_solver1+0xac>
add    $0x180,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define i64 @nqueen_solver1(i32 %0, i32 %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca [32 x i32]
%6 = alloca [32 x i32]
%7 = alloca [32 x i32]
%8 = alloca [32 x i32]
%9 = alloca i32
%10 = alloca i64
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
store i32 %0, i32* %3
store i32 %1, i32* %4
store i64 0, i64* %10
store i32 0, i32* %11
%14 = load i32, i32* %4
%15 = shl i32 1, %14
%16 = or i32 1, %15
%17 = getelementptr inbounds [32 x i32], [32 x i32]* %5, i64 0, i64 0
store i32 %16, i32* %17
%18 = load i32, i32* %4
%19 = add nsw i32 %18, 1
%20 = shl i32 1, %19
%21 = or i32 4, %20
%22 = getelementptr inbounds [32 x i32], [32 x i32]* %6, i64 0, i64 0
store i32 %21, i32* %22
%23 = load i32, i32* %4
%24 = shl i32 1, %23
%25 = ashr i32 %24, 1
%26 = getelementptr inbounds [32 x i32], [32 x i32]* %7, i64 0, i64 0
store i32 %25, i32* %26
%27 = getelementptr inbounds [32 x i32], [32 x i32]* %5, i64 0, i64 0
%28 = load i32, i32* %27
%29 = getelementptr inbounds [32 x i32], [32 x i32]* %6, i64 0, i64 0
%30 = load i32, i32* %29
%31 = or i32 %28, %30
%32 = getelementptr inbounds [32 x i32], [32 x i32]* %7, i64 0, i64 0
%33 = load i32, i32* %32
%34 = or i32 %31, %33
%35 = getelementptr inbounds [32 x i32], [32 x i32]* %8, i64 0, i64 0
store i32 %34, i32* %35
%36 = load i32, i32* %3
%37 = shl i32 1, %36
%38 = sub nsw i32 %37, 1
store i32 %38, i32* %12
br label %39
39: ; preds = %139, %2
%40 = load i32, i32* %11
%41 = icmp sge i32 %40, 0
br i1 %41, label %42, label %140
42: ; preds = %39
%43 = load i32, i32* %11
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds [32 x i32], [32 x i32]* %8, i64 0, i64 %44
%46 = load i32, i32* %45
%47 = load i32, i32* %11
%48 = add nsw i32 %47, 2
%49 = load i32, i32* %4
%50 = icmp slt i32 %48, %49
%51 = zext i1 %50 to i64
%52 = select i1 %50, i32 2, i32 0
%53 = or i32 %46, %52
store i32 %53, i32* %13
%54 = load i32, i32* %13
%55 = add i32 %54, 1
%56 = load i32, i32* %13
%57 = xor i32 %56, -1
%58 = and i32 %55, %57
store i32 %58, i32* %9
%59 = load i32, i32* %9
%60 = load i32, i32* %12
%61 = and i32 %59, %60
%62 = icmp ne i32 %61, 0
br i1 %62, label %63, label %136
63: ; preds = %42
%64 = load i32, i32* %11
%65 = load i32, i32* %3
%66 = sub nsw i32 %65, 3
%67 = icmp eq i32 %64, %66
br i1 %67, label %68, label %73
68: ; preds = %63
%69 = load i64, i64* %10
%70 = add nsw i64 %69, 1
store i64 %70, i64* %10
%71 = load i32, i32* %11
%72 = add nsw i32 %71, -1
store i32 %72, i32* %11
br label %135
73: ; preds = %63
%74 = load i32, i32* %9
%75 = load i32, i32* %11
%76 = sext i32 %75 to i64
%77 = getelementptr inbounds [32 x i32], [32 x i32]* %8, i64 0, i64 %76
%78 = load i32, i32* %77
%79 = or i32 %78, %74
store i32 %79, i32* %77
%80 = load i32, i32* %11
%81 = sext i32 %80 to i64
%82 = getelementptr inbounds [32 x i32], [32 x i32]* %5, i64 0, i64 %81
%83 = load i32, i32* %82
%84 = load i32, i32* %9
%85 = or i32 %83, %84
%86 = load i32, i32* %11
%87 = add nsw i32 %86, 1
%88 = sext i32 %87 to i64
%89 = getelementptr inbounds [32 x i32], [32 x i32]* %5, i64 0, i64 %88
store i32 %85, i32* %89
%90 = load i32, i32* %11
%91 = sext i32 %90 to i64
%92 = getelementptr inbounds [32 x i32], [32 x i32]* %6, i64 0, i64 %91
%93 = load i32, i32* %92
%94 = load i32, i32* %9
%95 = or i32 %93, %94
%96 = shl i32 %95, 1
%97 = load i32, i32* %11
%98 = add nsw i32 %97, 1
%99 = sext i32 %98 to i64
%100 = getelementptr inbounds [32 x i32], [32 x i32]* %6, i64 0, i64 %99
store i32 %96, i32* %100
%101 = load i32, i32* %11
%102 = sext i32 %101 to i64
%103 = getelementptr inbounds [32 x i32], [32 x i32]* %7, i64 0, i64 %102
%104 = load i32, i32* %103
%105 = load i32, i32* %9
%106 = or i32 %104, %105
%107 = lshr i32 %106, 1
%108 = load i32, i32* %11
%109 = add nsw i32 %108, 1
%110 = sext i32 %109 to i64
%111 = getelementptr inbounds [32 x i32], [32 x i32]* %7, i64 0, i64 %110
store i32 %107, i32* %111
%112 = load i32, i32* %11
%113 = add nsw i32 %112, 1
%114 = sext i32 %113 to i64
%115 = getelementptr inbounds [32 x i32], [32 x i32]* %5, i64 0, i64 %114
%116 = load i32, i32* %115
%117 = load i32, i32* %11
%118 = add nsw i32 %117, 1
%119 = sext i32 %118 to i64
%120 = getelementptr inbounds [32 x i32], [32 x i32]* %6, i64 0, i64 %119
%121 = load i32, i32* %120
%122 = or i32 %116, %121
%123 = load i32, i32* %11
%124 = add nsw i32 %123, 1
%125 = sext i32 %124 to i64
%126 = getelementptr inbounds [32 x i32], [32 x i32]* %7, i64 0, i64 %125
%127 = load i32, i32* %126
%128 = or i32 %122, %127
%129 = load i32, i32* %11
%130 = add nsw i32 %129, 1
%131 = sext i32 %130 to i64
%132 = getelementptr inbounds [32 x i32], [32 x i32]* %8, i64 0, i64 %131
store i32 %128, i32* %132
%133 = load i32, i32* %11
%134 = add nsw i32 %133, 1
store i32 %134, i32* %11
br label %135
135: ; preds = %73, %68
br label %139
136: ; preds = %42
%137 = load i32, i32* %11
%138 = add nsw i32 %137, -1
store i32 %138, i32* %11
br label %139
139: ; preds = %136, %135
br label %39
140: ; preds = %39
%141 = load i64, i64* %10
ret i64 %141
}

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