#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 */
typedef int uint8_t;
typedef int uint32_t;

/* Variables and functions */
uint8_t clz(uint32_t x) {
  static const uint8_t bval[] = {0, 1, 2, 2, 3, 3, 3, 3,
                                 4, 4, 4, 4, 4, 4, 4, 4};
  unsigned int r = 32;
  if (x >= 0x10000) {
    r -= 16;
    x >>= 16;
  }
  if (x & 0xFF00) {
    r -= 8;
    x >>= 8;
  }
  if (x & 0xF0) {
    r -= 4;
    x >>= 4;
  }
  return r - bval[x];
}


x86 assembly (clang, -O0):
<clz>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
movl   $0x20,-0x8(%rbp)
cmpl   $0x10000,-0x4(%rbp)
jl     112d <clz+0x2d>
mov    -0x8(%rbp),%eax
sub    $0x10,%eax
mov    %eax,-0x8(%rbp)
mov    -0x4(%rbp),%eax
sar    $0x10,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
and    $0xff00,%eax
cmp    $0x0,%eax
je     1150 <clz+0x50>
mov    -0x8(%rbp),%eax
sub    $0x8,%eax
mov    %eax,-0x8(%rbp)
mov    -0x4(%rbp),%eax
sar    $0x8,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
and    $0xf0,%eax
cmp    $0x0,%eax
je     1173 <clz+0x73>
mov    -0x8(%rbp),%eax
sub    $0x4,%eax
mov    %eax,-0x8(%rbp)
mov    -0x4(%rbp),%eax
sar    $0x4,%eax
mov    %eax,-0x4(%rbp)
mov    -0x8(%rbp),%eax
movslq -0x4(%rbp),%rdx
lea    0xe7f(%rip),%rcx
sub    (%rcx,%rdx,4),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<clz>:
mov    %edi,%eax
sar    $0x10,%eax
xor    %ecx,%ecx
cmp    $0x10000,%edi
setl   %cl
cmovl  %edi,%eax
shl    $0x4,%ecx
lea    0x10(%rcx),%edx
or     $0x8,%ecx
mov    %eax,%esi
sar    $0x8,%esi
test   $0xff00,%eax
cmove  %eax,%esi
cmove  %edx,%ecx
lea    -0x4(%rcx),%eax
mov    %esi,%edx
sar    $0x4,%edx
test   $0xf0,%sil
cmove  %esi,%edx
cmove  %ecx,%eax
movslq %edx,%rcx
lea    0xeb8(%rip),%rdx
sub    (%rdx,%rcx,4),%eax
ret

LLVM IR (-O0):
@clz.bval = internal constant [16 x i32] [i32 0, i32 1, i32 2, i32 2, i32 3, i32 3, i32 3, i32 3, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4]
define i32 @clz(i32 %0) {
%2 = alloca i32
%3 = alloca i32
store i32 %0, i32* %2
store i32 32, i32* %3
%4 = load i32, i32* %2
%5 = icmp sge i32 %4, 65536
br i1 %5, label %6, label %11
6: ; preds = %1
%7 = load i32, i32* %3
%8 = sub i32 %7, 16
store i32 %8, i32* %3
%9 = load i32, i32* %2
%10 = ashr i32 %9, 16
store i32 %10, i32* %2
br label %11
11: ; preds = %6, %1
%12 = load i32, i32* %2
%13 = and i32 %12, 65280
%14 = icmp ne i32 %13, 0
br i1 %14, label %15, label %20
15: ; preds = %11
%16 = load i32, i32* %3
%17 = sub i32 %16, 8
store i32 %17, i32* %3
%18 = load i32, i32* %2
%19 = ashr i32 %18, 8
store i32 %19, i32* %2
br label %20
20: ; preds = %15, %11
%21 = load i32, i32* %2
%22 = and i32 %21, 240
%23 = icmp ne i32 %22, 0
br i1 %23, label %24, label %29
24: ; preds = %20
%25 = load i32, i32* %3
%26 = sub i32 %25, 4
store i32 %26, i32* %3
%27 = load i32, i32* %2
%28 = ashr i32 %27, 4
store i32 %28, i32* %2
br label %29
29: ; preds = %24, %20
%30 = load i32, i32* %3
%31 = load i32, i32* %2
%32 = sext i32 %31 to i64
%33 = getelementptr inbounds [16 x i32], [16 x i32]* @clz.bval, i64 0, i64 %32
%34 = load i32, i32* %33
%35 = sub i32 %30, %34
ret i32 %35
}

LLVM IR (-O2):
@clz.bval = internal unnamed_addr constant [16 x i32] [i32 0, i32 1, i32 2, i32 2, i32 3, i32 3, i32 3, i32 3, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4, i32 4]
define i32 @clz(i32 %0) {
%2 = icmp sgt i32 %0, 65535
%3 = ashr i32 %0, 16
%4 = select i1 %2, i32 %3, i32 %0
%5 = select i1 %2, i32 16, i32 32
%6 = and i32 %4, 65280
%7 = icmp eq i32 %6, 0
%8 = add nsw i32 %5, -8
%9 = ashr i32 %4, 8
%10 = select i1 %7, i32 %4, i32 %9
%11 = select i1 %7, i32 %5, i32 %8
%12 = and i32 %10, 240
%13 = icmp eq i32 %12, 0
%14 = add nsw i32 %11, -4
%15 = ashr i32 %10, 4
%16 = select i1 %13, i32 %10, i32 %15
%17 = select i1 %13, i32 %11, i32 %14
%18 = sext i32 %16 to i64
%19 = getelementptr inbounds [16 x i32], [16 x i32]* @clz.bval, i64 0, i64 %18
%20 = load i32, i32* %19
%21 = sub i32 %17, %20
ret i32 %21
}