unsigned int hashnum(unsigned int num) {
  unsigned int mask1 = 0x10 << 27, mask2 = 0x02 << 27;
  for (; mask1 >= 0x10; mask1 >>= 1, mask2 >>= 1)
    if (num & mask1)
      num ^= mask2;
  return num & (16 - 1);
}


x86 assembly (clang, -O0):
<hashnum>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
movl   $0x80000000,-0x8(%rbp)
movl   $0x10000000,-0xc(%rbp)
cmpl   $0x10,-0x8(%rbp)
jb     1153 <hashnum+0x53>
mov    -0x4(%rbp),%eax
and    -0x8(%rbp),%eax
cmp    $0x0,%eax
je     1137 <hashnum+0x37>
mov    -0xc(%rbp),%eax
xor    -0x4(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    113c <hashnum+0x3c>
mov    -0x8(%rbp),%eax
shr    $0x1,%eax
mov    %eax,-0x8(%rbp)
mov    -0xc(%rbp),%eax
shr    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1115 <hashnum+0x15>
mov    -0x4(%rbp),%eax
and    $0xf,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<hashnum>:
mov    %edi,%eax
mov    $0x80000000,%edx
mov    $0x10000000,%ecx
jmp    1124 <hashnum+0x24>
xchg   %ax,%ax
xor    %esi,%eax
mov    %edx,%esi
shr    $0x4,%esi
shr    $0x4,%ecx
cmp    $0xff,%edx
mov    %esi,%edx
jbe    115c <hashnum+0x5c>
mov    %edx,%esi
and    %eax,%esi
je     112c <hashnum+0x2c>
mov    %ecx,%esi
xor    %eax,%esi
mov    %edx,%eax
shr    %eax
and    %esi,%eax
je     113a <hashnum+0x3a>
mov    %ecx,%eax
shr    %eax
xor    %esi,%eax
mov    %edx,%esi
shr    $0x2,%esi
and    %eax,%esi
je     114a <hashnum+0x4a>
mov    %ecx,%esi
shr    $0x2,%esi
xor    %eax,%esi
mov    %edx,%eax
shr    $0x3,%eax
and    %esi,%eax
je     1110 <hashnum+0x10>
mov    %ecx,%eax
shr    $0x3,%eax
jmp    1110 <hashnum+0x10>
and    $0xf,%eax
ret

LLVM IR (-O0):
define i32 @hashnum(i32 %0) {
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32
store i32 %0, i32* %2
store i32 -2147483648, i32* %3
store i32 268435456, i32* %4
br label %5
5: ; preds = %18, %1
%6 = load i32, i32* %3
%7 = icmp uge i32 %6, 16
br i1 %7, label %8, label %23
8: ; preds = %5
%9 = load i32, i32* %2
%10 = load i32, i32* %3
%11 = and i32 %9, %10
%12 = icmp ne i32 %11, 0
br i1 %12, label %13, label %17
13: ; preds = %8
%14 = load i32, i32* %4
%15 = load i32, i32* %2
%16 = xor i32 %15, %14
store i32 %16, i32* %2
br label %17
17: ; preds = %13, %8
br label %18
18: ; preds = %17
%19 = load i32, i32* %3
%20 = lshr i32 %19, 1
store i32 %20, i32* %3
%21 = load i32, i32* %4
%22 = lshr i32 %21, 1
store i32 %22, i32* %4
br label %5
23: ; preds = %5
%24 = load i32, i32* %2
%25 = and i32 %24, 15
ret i32 %25
}

LLVM IR (-O2):
define i32 @hashnum(i32 %0) {
br label %2
2: ; preds = %2, %1
%3 = phi i32 [ 268435456, %1 ], [ %29, %2 ]
%4 = phi i32 [ -2147483648, %1 ], [ %28, %2 ]
%5 = phi i32 [ %0, %1 ], [ %27, %2 ]
%6 = and i32 %4, %5
%7 = icmp eq i32 %6, 0
%8 = select i1 %7, i32 0, i32 %3
%9 = xor i32 %8, %5
%10 = lshr i32 %4, 1
%11 = lshr i32 %3, 1
%12 = and i32 %10, %9
%13 = icmp eq i32 %12, 0
%14 = select i1 %13, i32 0, i32 %11
%15 = xor i32 %14, %9
%16 = lshr i32 %4, 2
%17 = lshr i32 %3, 2
%18 = and i32 %16, %15
%19 = icmp eq i32 %18, 0
%20 = select i1 %19, i32 0, i32 %17
%21 = xor i32 %20, %15
%22 = lshr i32 %4, 3
%23 = lshr i32 %3, 3
%24 = and i32 %22, %21
%25 = icmp eq i32 %24, 0
%26 = select i1 %25, i32 0, i32 %23
%27 = xor i32 %26, %21
%28 = lshr i32 %4, 4
%29 = lshr i32 %3, 4
%30 = icmp ugt i32 %4, 255
br i1 %30, label %2, label %31
31: ; preds = %2
%32 = and i32 %27, 15
ret i32 %32
}