#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int last_bit(unsigned long long);
unsigned long long flip_D6(const unsigned long long discs_player,
                           const unsigned long long discs_opponent) {
  unsigned long long my_discs, opp_discs, r;
  unsigned long long flipped =
      (discs_opponent & 0X0000000000000800ULL) & (discs_player << 9);
  flipped |= (discs_opponent & 0X0000000000001000ULL) & (discs_player << 8);
  flipped |= (discs_opponent & 0X0000000000002000ULL) & (discs_player << 7);
  my_discs = discs_player & 0X0000000000070000ULL;
  r = ((my_discs << 1) + discs_opponent) & 0X0000000000100000ULL;
  if (r != 0) {
    flipped |= 0X0000000000100000ULL - (0X2ULL << last_bit(my_discs));
  }
  my_discs = discs_player & 0X0001020400000000ULL;
  opp_discs = (discs_opponent & 0X0000020408000000ULL) | 0X0000FDFBF0000000ULL;
  r = (opp_discs + 0X0000000008000000ULL) & my_discs;
  if (r != 0) {
    flipped |= (r - 1) & 0X0000020408000000ULL;
  }
  my_discs = discs_player & 0X1010101000000000ULL;
  opp_discs = (discs_opponent & 0X0010101010000000ULL) | 0X0FEFEFEFE0000000ULL;
  r = (opp_discs + 0X0000000010000000ULL) & my_discs;
  if (r != 0) {
    flipped |= (r - 1) & 0X0010101010000000ULL;
  }
  my_discs = discs_player & 0X0000804000000000ULL;
  opp_discs = (discs_opponent & 0X0000004020000000ULL) | 0X00007FBFC0000000ULL;
  r = (opp_discs + 0X0000000020000000ULL) & my_discs;
  if (r != 0) {
    flipped |= (r - 1) & 0X0000004020000000ULL;
  }
  my_discs = discs_player & 0X0000000000C00000ULL;
  r = (discs_opponent + 0X0000000000200000ULL) & my_discs;
  if (r != 0) {
    flipped |= (r - 1) & 0X0000000000E00000ULL;
  }
  return flipped;
}


x86 assembly (clang, -O0):
<flip_D6>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
and    $0x800,%rax
mov    -0x8(%rbp),%rcx
shl    $0x9,%rcx
and    %rcx,%rax
mov    %rax,-0x30(%rbp)
mov    -0x10(%rbp),%rax
and    $0x1000,%rax
mov    -0x8(%rbp),%rcx
shl    $0x8,%rcx
and    %rcx,%rax
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x10(%rbp),%rax
and    $0x2000,%rax
mov    -0x8(%rbp),%rcx
shl    $0x7,%rcx
and    %rcx,%rax
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%rax
and    $0x70000,%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
shl    $0x1,%rax
add    -0x10(%rbp),%rax
and    $0x100000,%rax
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
je     11ca <flip_D6+0xba>
mov    -0x18(%rbp),%rdi
call   1030 <last_bit@plt>
mov    %eax,%eax
mov    %eax,%ecx
mov    $0x2,%eax
shl    %cl,%rax
mov    %rax,%rcx
mov    $0x100000,%eax
sub    %rcx,%rax
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
movabs $0x1020400000000,%rax
and    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
movabs $0x20408000000,%rax
and    -0x10(%rbp),%rax
movabs $0xfdfbf0000000,%rcx
or     %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
add    $0x8000000,%rax
and    -0x18(%rbp),%rax
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
je     1235 <flip_D6+0x125>
mov    -0x28(%rbp),%rax
sub    $0x1,%rax
movabs $0x20408000000,%rcx
and    %rcx,%rax
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
movabs $0x1010101000000000,%rax
10 10 10
and    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
movabs $0x10101010000000,%rax
and    -0x10(%rbp),%rax
movabs $0xfefefefe0000000,%rcx
ef ef 0f
or     %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
add    $0x10000000,%rax
and    -0x18(%rbp),%rax
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
je     12a0 <flip_D6+0x190>
mov    -0x28(%rbp),%rax
sub    $0x1,%rax
movabs $0x10101010000000,%rcx
and    %rcx,%rax
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
movabs $0x804000000000,%rax
and    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
movabs $0x4020000000,%rax
and    -0x10(%rbp),%rax
movabs $0x7fbfc0000000,%rcx
or     %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
add    $0x20000000,%rax
and    -0x18(%rbp),%rax
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
je     130b <flip_D6+0x1fb>
mov    -0x28(%rbp),%rax
sub    $0x1,%rax
movabs $0x4020000000,%rcx
and    %rcx,%rax
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%rax
and    $0xc00000,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
add    $0x200000,%rax
and    -0x18(%rbp),%rax
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
je     134c <flip_D6+0x23c>
mov    -0x28(%rbp),%rax
sub    $0x1,%rax
and    $0xe00000,%rax
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<flip_D6>:
push   %r15
push   %r14
push   %rbx
mov    %rsi,%rbx
mov    %rdi,%r14
mov    %r14d,%eax
shl    $0x9,%eax
and    %ebx,%eax
and    $0x800,%eax
mov    %r14d,%ecx
shl    $0x8,%ecx
and    %ebx,%ecx
and    $0x1000,%ecx
or     %rax,%rcx
mov    %r14d,%r15d
shl    $0x7,%r15d
and    %ebx,%r15d
and    $0x2000,%r15d
or     %rcx,%r15
and    $0x70000,%edi
lea    (%rsi,%rdi,2),%eax
test   $0x100000,%eax
je     1178 <flip_D6+0x68>
call   1030 <last_bit@plt>
mov    $0xfffffffffffffffe,%rdx
mov    %eax,%ecx
shl    %cl,%rdx
add    $0x100000,%rdx
or     %rdx,%r15
movabs $0x20408000000,%rax
mov    %rbx,%rcx
and    %rax,%rcx
movabs $0xfdfbf8000000,%rdx
add    %rcx,%rdx
and    %r14,%rdx
movabs $0x1020400000000,%rsi
and    %rdx,%rsi
lea    -0x1(%rsi),%rcx
and    %rax,%rcx
test   %rsi,%rsi
cmove  %rsi,%rcx
movabs $0x10101010000000,%rax
mov    %rbx,%rdx
and    %rax,%rdx
movabs $0xfefefeff0000000,%rsi
ef ef 0f
add    %rdx,%rsi
and    %r14,%rsi
movabs $0x1010101000000000,%rdi
10 10 10
and    %rsi,%rdi
lea    -0x1(%rdi),%rdx
and    %rax,%rdx
test   %rdi,%rdi
cmove  %rdi,%rdx
movabs $0x4020000000,%r8
mov    %rbx,%rsi
and    %r8,%rsi
movabs $0x7fbfe0000000,%rdi
add    %rsi,%rdi
and    %r14,%rdi
movabs $0x804000000000,%rax
and    %rdi,%rax
lea    -0x1(%rax),%rsi
and    %r8,%rsi
test   %rax,%rax
cmove  %rax,%rsi
add    $0x200000,%ebx
and    %r14d,%ebx
and    $0xc00000,%ebx
lea    -0x1(%rbx),%eax
and    $0xe00000,%eax
test   %rbx,%rbx
cmove  %rbx,%rax
or     %rcx,%rax
or     %rdx,%rax
or     %rsi,%rax
or     %r15,%rax
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define i64 @flip_D6(i64 %0, i64 %1) {
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
%6 = alloca i64
%7 = alloca i64
%8 = alloca i64
store i64 %0, i64* %3
store i64 %1, i64* %4
%9 = load i64, i64* %4
%10 = and i64 %9, 2048
%11 = load i64, i64* %3
%12 = shl i64 %11, 9
%13 = and i64 %10, %12
store i64 %13, i64* %8
%14 = load i64, i64* %4
%15 = and i64 %14, 4096
%16 = load i64, i64* %3
%17 = shl i64 %16, 8
%18 = and i64 %15, %17
%19 = load i64, i64* %8
%20 = or i64 %19, %18
store i64 %20, i64* %8
%21 = load i64, i64* %4
%22 = and i64 %21, 8192
%23 = load i64, i64* %3
%24 = shl i64 %23, 7
%25 = and i64 %22, %24
%26 = load i64, i64* %8
%27 = or i64 %26, %25
store i64 %27, i64* %8
%28 = load i64, i64* %3
%29 = and i64 %28, 458752
store i64 %29, i64* %5
%30 = load i64, i64* %5
%31 = shl i64 %30, 1
%32 = load i64, i64* %4
%33 = add i64 %31, %32
%34 = and i64 %33, 1048576
store i64 %34, i64* %7
%35 = load i64, i64* %7
%36 = icmp ne i64 %35, 0
br i1 %36, label %37, label %45
37: ; preds = %2
%38 = load i64, i64* %5
%39 = call i32 @last_bit(i64 %38)
%40 = zext i32 %39 to i64
%41 = shl i64 2, %40
%42 = sub i64 1048576, %41
%43 = load i64, i64* %8
%44 = or i64 %43, %42
store i64 %44, i64* %8
br label %45
45: ; preds = %37, %2
%46 = load i64, i64* %3
%47 = and i64 %46, 283691179835392
store i64 %47, i64* %5
%48 = load i64, i64* %4
%49 = and i64 %48, 2216337342464
%50 = or i64 %49, 279258505150464
store i64 %50, i64* %6
%51 = load i64, i64* %6
%52 = add i64 %51, 134217728
%53 = load i64, i64* %5
%54 = and i64 %52, %53
store i64 %54, i64* %7
%55 = load i64, i64* %7
%56 = icmp ne i64 %55, 0
br i1 %56, label %57, label %63
57: ; preds = %45
%58 = load i64, i64* %7
%59 = sub i64 %58, 1
%60 = and i64 %59, 2216337342464
%61 = load i64, i64* %8
%62 = or i64 %61, %60
store i64 %62, i64* %8
br label %63
63: ; preds = %57, %45
%64 = load i64, i64* %3
%65 = and i64 %64, 1157442765139738624
store i64 %65, i64* %5
%66 = load i64, i64* %4
%67 = and i64 %66, 4521260801327104
%68 = or i64 %67, 1148400243537084416
store i64 %68, i64* %6
%69 = load i64, i64* %6
%70 = add i64 %69, 268435456
%71 = load i64, i64* %5
%72 = and i64 %70, %71
store i64 %72, i64* %7
%73 = load i64, i64* %7
%74 = icmp ne i64 %73, 0
br i1 %74, label %75, label %81
75: ; preds = %63
%76 = load i64, i64* %7
%77 = sub i64 %76, 1
%78 = and i64 %77, 4521260801327104
%79 = load i64, i64* %8
%80 = or i64 %79, %78
store i64 %80, i64* %8
br label %81
81: ; preds = %75, %63
%82 = load i64, i64* %3
%83 = and i64 %82, 141012366262272
store i64 %83, i64* %5
%84 = load i64, i64* %4
%85 = and i64 %84, 275414777856
%86 = or i64 %85, 140461536706560
store i64 %86, i64* %6
%87 = load i64, i64* %6
%88 = add i64 %87, 536870912
%89 = load i64, i64* %5
%90 = and i64 %88, %89
store i64 %90, i64* %7
%91 = load i64, i64* %7
%92 = icmp ne i64 %91, 0
br i1 %92, label %93, label %99
93: ; preds = %81
%94 = load i64, i64* %7
%95 = sub i64 %94, 1
%96 = and i64 %95, 275414777856
%97 = load i64, i64* %8
%98 = or i64 %97, %96
store i64 %98, i64* %8
br label %99
99: ; preds = %93, %81
%100 = load i64, i64* %3
%101 = and i64 %100, 12582912
store i64 %101, i64* %5
%102 = load i64, i64* %4
%103 = add i64 %102, 2097152
%104 = load i64, i64* %5
%105 = and i64 %103, %104
store i64 %105, i64* %7
%106 = load i64, i64* %7
%107 = icmp ne i64 %106, 0
br i1 %107, label %108, label %114
108: ; preds = %99
%109 = load i64, i64* %7
%110 = sub i64 %109, 1
%111 = and i64 %110, 14680064
%112 = load i64, i64* %8
%113 = or i64 %112, %111
store i64 %113, i64* %8
br label %114
114: ; preds = %108, %99
%115 = load i64, i64* %8
ret i64 %115
}

LLVM IR (-O2):
define i64 @flip_D6(i64 %0, i64 %1) {
%3 = and i64 %1, 2048
%4 = shl i64 %0, 9
%5 = and i64 %3, %4
%6 = and i64 %1, 4096
%7 = shl i64 %0, 8
%8 = and i64 %6, %7
%9 = or i64 %5, %8
%10 = and i64 %1, 8192
%11 = shl i64 %0, 7
%12 = and i64 %10, %11
%13 = or i64 %9, %12
%14 = and i64 %0, 458752
%15 = shl nuw nsw i64 %14, 1
%16 = add i64 %15, %1
%17 = and i64 %16, 1048576
%18 = icmp eq i64 %17, 0
br i1 %18, label %25, label %19
19: ; preds = %2
%20 = tail call i32 @last_bit(i64 %14)
%21 = zext i32 %20 to i64
%22 = shl i64 -2, %21
%23 = add i64 %22, 1048576
%24 = or i64 %23, %13
br label %25
25: ; preds = %19, %2
%26 = phi i64 [ %24, %19 ], [ %13, %2 ]
%27 = and i64 %0, 283691179835392
%28 = and i64 %1, 2216337342464
%29 = add nuw nsw i64 %28, 279258639368192
%30 = and i64 %27, %29
%31 = icmp eq i64 %30, 0
%32 = add nuw nsw i64 %30, 4398046511103
%33 = and i64 %32, 2216337342464
%34 = select i1 %31, i64 0, i64 %33
%35 = and i64 %0, 1157442765139738624
%36 = and i64 %1, 4521260801327104
%37 = add nuw nsw i64 %36, 1148400243805519872
%38 = and i64 %35, %37
%39 = icmp eq i64 %38, 0
%40 = add nuw nsw i64 %38, 9007199254740991
%41 = and i64 %40, 4521260801327104
%42 = select i1 %39, i64 0, i64 %41
%43 = and i64 %0, 141012366262272
%44 = and i64 %1, 275414777856
%45 = add nuw nsw i64 %44, 140462073577472
%46 = and i64 %43, %45
%47 = icmp eq i64 %46, 0
%48 = add nuw nsw i64 %46, 549755813887
%49 = and i64 %48, 275414777856
%50 = select i1 %47, i64 0, i64 %49
%51 = and i64 %0, 12582912
%52 = add i64 %1, 2097152
%53 = and i64 %51, %52
%54 = icmp eq i64 %53, 0
%55 = add nuw nsw i64 %53, 16777215
%56 = and i64 %55, 14680064
%57 = select i1 %54, i64 0, i64 %56
%58 = or i64 %34, %57
%59 = or i64 %58, %42
%60 = or i64 %59, %50
%61 = or i64 %60, %26
ret i64 %61
}