void check_features(unsigned int ecx, unsigned int edx, int max_cpuid_level) {
  unsigned int eax, ebx;
  unsigned int ext_level;
  if (edx & (1 << 15))
    assert(__builtin_cpu_supports("cmov"));
  if (edx & (1 << 23))
    assert(__builtin_cpu_supports("mmx"));
  if (edx & (1 << 25))
    assert(__builtin_cpu_supports("sse"));
  if (edx & (1 << 26))
    assert(__builtin_cpu_supports("sse2"));
  if (ecx & (1 << 23))
    assert(__builtin_cpu_supports("popcnt"));
  if (ecx & (1 << 25))
    assert(__builtin_cpu_supports("aes"));
  if (ecx & (1 << 1))
    assert(__builtin_cpu_supports("pclmul"));
  if (ecx & (1 << 0))
    assert(__builtin_cpu_supports("sse3"));
  if (ecx & (1 << 9))
    assert(__builtin_cpu_supports("ssse3"));
  if (ecx & (1 << 19))
    assert(__builtin_cpu_supports("sse4.1"));
  if (ecx & (1 << 20))
    assert(__builtin_cpu_supports("sse4.2"));
  if (ecx & (1 << 28))
    assert(__builtin_cpu_supports("avx"));
  if (ecx & (1 << 12))
    assert(__builtin_cpu_supports("fma"));
  if (max_cpuid_level >= 7) {
    __asm__("cpuid\n\t"
            : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
            : "0"(7), "2"(0));
    if (ebx & (1 << 3))
      assert(__builtin_cpu_supports("bmi"));
    if (ebx & (1 << 5))
      assert(__builtin_cpu_supports("avx2"));
    if (ebx & (1 << 8))
      assert(__builtin_cpu_supports("bmi2"));
    if (ebx & (1 << 16))
      assert(__builtin_cpu_supports("avx512f"));
    if (ebx & (1u << 31))
      assert(__builtin_cpu_supports("avx512vl"));
    if (ebx & (1 << 30))
      assert(__builtin_cpu_supports("avx512bw"));
    if (ebx & (1 << 17))
      assert(__builtin_cpu_supports("avx512dq"));
    if (ebx & (1 << 28))
      assert(__builtin_cpu_supports("avx512cd"));
    if (ebx & (1 << 26))
      assert(__builtin_cpu_supports("avx512pf"));
    if (ebx & (1 << 27))
      assert(__builtin_cpu_supports("avx512er"));
    if (ebx & (1 << 21))
      assert(__builtin_cpu_supports("avx512ifma"));
    if (ecx & (1 << 1))
      assert(__builtin_cpu_supports("avx512vbmi"));
    if (ecx & (1 << 14))
      assert(__builtin_cpu_supports("avx512vpopcntdq"));
    if (edx & (1 << 2))
      assert(__builtin_cpu_supports("avx5124vnniw"));
    if (edx & (1 << 3))
      assert(__builtin_cpu_supports("avx5124fmaps"));
  }
  __asm__("cpuid\n\t"
          : "=a"(ext_level), "=b"(ebx), "=c"(ecx), "=d"(edx)
          : "0"(0x80000000));
  if (ext_level >= 0x80000001) {
    __asm__("cpuid\n\t"
            : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
            : "0"(0x80000001));
    if (ecx & (1 << 6))
      assert(__builtin_cpu_supports("sse4a"));
    if (ecx & (1 << 16))
      assert(__builtin_cpu_supports("fma4"));
    if (ecx & (1 << 11))
      assert(__builtin_cpu_supports("xop"));
  }
}


x86 assembly (clang, -O0):
<check_features>:
push   %rbp
mov    %rsp,%rbp
push   %rbx
sub    $0x18,%rsp
mov    %edi,-0xc(%rbp)
mov    %esi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x10(%rbp),%eax
and    $0x8000,%eax
cmp    $0x0,%eax
je     21c0 <check_features+0x40>
mov    0x2eb3(%rip),%eax
and    $0x1,%eax
cmp    $0x1,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x10(%rbp),%eax
and    $0x800000,%eax
cmp    $0x0,%eax
je     21ee <check_features+0x6e>
mov    0x2e85(%rip),%eax
and    $0x2,%eax
cmp    $0x2,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x10(%rbp),%eax
and    $0x2000000,%eax
cmp    $0x0,%eax
je     221c <check_features+0x9c>
mov    0x2e57(%rip),%eax
and    $0x8,%eax
cmp    $0x8,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x10(%rbp),%eax
and    $0x4000000,%eax
cmp    $0x0,%eax
je     224a <check_features+0xca>
mov    0x2e29(%rip),%eax
and    $0x10,%eax
cmp    $0x10,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x800000,%eax
cmp    $0x0,%eax
je     2278 <check_features+0xf8>
mov    0x2dfb(%rip),%eax
and    $0x4,%eax
cmp    $0x4,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x2000000,%eax
cmp    $0x0,%eax
je     22aa <check_features+0x12a>
mov    0x2dcd(%rip),%eax
and    $0x40000,%eax
cmp    $0x40000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x2,%eax
cmp    $0x0,%eax
je     22da <check_features+0x15a>
mov    0x2d9d(%rip),%eax
and    $0x80000,%eax
cmp    $0x80000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     2306 <check_features+0x186>
mov    0x2d6d(%rip),%eax
and    $0x20,%eax
cmp    $0x20,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x200,%eax
cmp    $0x0,%eax
je     2334 <check_features+0x1b4>
mov    0x2d3f(%rip),%eax
and    $0x40,%eax
cmp    $0x40,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x80000,%eax
cmp    $0x0,%eax
je     2366 <check_features+0x1e6>
mov    0x2d11(%rip),%eax
and    $0x80,%eax
cmp    $0x80,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x100000,%eax
cmp    $0x0,%eax
je     2398 <check_features+0x218>
mov    0x2cdf(%rip),%eax
and    $0x100,%eax
cmp    $0x100,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x10000000,%eax
cmp    $0x0,%eax
je     23ca <check_features+0x24a>
mov    0x2cad(%rip),%eax
and    $0x200,%eax
cmp    $0x200,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x1000,%eax
cmp    $0x0,%eax
je     23fc <check_features+0x27c>
mov    0x2c7b(%rip),%eax
and    $0x4000,%eax
cmp    $0x4000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
cmpl   $0x7,-0x14(%rbp)
jl     2704 <check_features+0x584>
mov    $0x7,%eax
xor    %ecx,%ecx
cpuid
mov    %eax,-0x18(%rbp)
mov    %ebx,-0x1c(%rbp)
mov    %ecx,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    -0x1c(%rbp),%eax
and    $0x8,%eax
cmp    $0x0,%eax
je     244b <check_features+0x2cb>
mov    0x2c2c(%rip),%eax
and    $0x10000,%eax
cmp    $0x10000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x1c(%rbp),%eax
and    $0x20,%eax
cmp    $0x0,%eax
je     247b <check_features+0x2fb>
mov    0x2bfc(%rip),%eax
and    $0x400,%eax
cmp    $0x400,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x1c(%rbp),%eax
and    $0x100,%eax
cmp    $0x0,%eax
je     24ad <check_features+0x32d>
mov    0x2bca(%rip),%eax
and    $0x20000,%eax
cmp    $0x20000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x1c(%rbp),%eax
and    $0x10000,%eax
cmp    $0x0,%eax
je     24df <check_features+0x35f>
mov    0x2b98(%rip),%eax
and    $0x8000,%eax
cmp    $0x8000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x1c(%rbp),%eax
and    $0x80000000,%eax
cmp    $0x0,%eax
je     2511 <check_features+0x391>
mov    0x2b66(%rip),%eax
and    $0x100000,%eax
cmp    $0x100000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x1c(%rbp),%eax
and    $0x40000000,%eax
cmp    $0x0,%eax
je     2543 <check_features+0x3c3>
mov    0x2b34(%rip),%eax
and    $0x200000,%eax
cmp    $0x200000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x1c(%rbp),%eax
and    $0x20000,%eax
cmp    $0x0,%eax
je     2575 <check_features+0x3f5>
mov    0x2b02(%rip),%eax
and    $0x400000,%eax
cmp    $0x400000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x1c(%rbp),%eax
and    $0x10000000,%eax
cmp    $0x0,%eax
je     25a7 <check_features+0x427>
mov    0x2ad0(%rip),%eax
and    $0x800000,%eax
cmp    $0x800000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x1c(%rbp),%eax
and    $0x4000000,%eax
cmp    $0x0,%eax
je     25d9 <check_features+0x459>
mov    0x2a9e(%rip),%eax
and    $0x2000000,%eax
cmp    $0x2000000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x1c(%rbp),%eax
and    $0x8000000,%eax
cmp    $0x0,%eax
je     260b <check_features+0x48b>
mov    0x2a6c(%rip),%eax
and    $0x1000000,%eax
cmp    $0x1000000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x1c(%rbp),%eax
and    $0x200000,%eax
cmp    $0x0,%eax
je     263d <check_features+0x4bd>
mov    0x2a3a(%rip),%eax
and    $0x8000000,%eax
cmp    $0x8000000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x2,%eax
cmp    $0x0,%eax
je     266d <check_features+0x4ed>
mov    0x2a0a(%rip),%eax
and    $0x4000000,%eax
cmp    $0x4000000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x4000,%eax
cmp    $0x0,%eax
je     269f <check_features+0x51f>
mov    0x29d8(%rip),%eax
and    $0x40000000,%eax
cmp    $0x40000000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x10(%rbp),%eax
and    $0x4,%eax
cmp    $0x0,%eax
je     26cf <check_features+0x54f>
mov    0x29a8(%rip),%eax
and    $0x10000000,%eax
cmp    $0x10000000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x10(%rbp),%eax
and    $0x8,%eax
cmp    $0x0,%eax
je     26ff <check_features+0x57f>
mov    0x2978(%rip),%eax
and    $0x20000000,%eax
cmp    $0x20000000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
jmp    2704 <check_features+0x584>
mov    $0x80000000,%eax
cpuid
mov    %eax,-0x20(%rbp)
mov    %ebx,-0x1c(%rbp)
mov    %ecx,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
cmpl   $0x80000001,-0x20(%rbp)
jb     27d0 <check_features+0x650>
mov    $0x80000001,%eax
cpuid
mov    %eax,-0x18(%rbp)
mov    %ebx,-0x1c(%rbp)
mov    %ecx,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    -0xc(%rbp),%eax
and    $0x40,%eax
cmp    $0x0,%eax
je     2767 <check_features+0x5e7>
mov    0x2910(%rip),%eax
and    $0x800,%eax
cmp    $0x800,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x10000,%eax
cmp    $0x0,%eax
je     2799 <check_features+0x619>
mov    0x28de(%rip),%eax
and    $0x1000,%eax
cmp    $0x1000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0xc(%rbp),%eax
and    $0x800,%eax
cmp    $0x0,%eax
je     27cb <check_features+0x64b>
mov    0x28ac(%rip),%eax
and    $0x2000,%eax
cmp    $0x2000,%eax
sete   %al
and    $0x1,%al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
jmp    27d0 <check_features+0x650>
add    $0x18,%rsp
pop    %rbx
pop    %rbp
ret

x86 assembly (clang, -O2):
<check_features>:
push   %rbp
push   %r14
push   %rbx
mov    %edx,%r14d
mov    %esi,%ebx
mov    %edi,%ebp
test   $0x8000,%esi
jne    2232 <check_features+0xb2>
test   $0x800000,%ebx
jne    224e <check_features+0xce>
test   $0x2000000,%ebx
jne    226c <check_features+0xec>
test   $0x4000000,%ebx
jne    228b <check_features+0x10b>
test   $0x800000,%ebp
jne    22aa <check_features+0x12a>
test   $0x2000000,%ebp
jne    22c9 <check_features+0x149>
test   $0x2,%bpl
jne    22e6 <check_features+0x166>
test   $0x1,%bpl
jne    2303 <check_features+0x183>
test   $0x200,%ebp
jne    2322 <check_features+0x1a2>
test   $0x80000,%ebp
jne    2341 <check_features+0x1c1>
test   $0x100000,%ebp
jne    2360 <check_features+0x1e0>
test   $0x10000000,%ebp
jne    237f <check_features+0x1ff>
test   $0x1000,%ebp
jne    239e <check_features+0x21e>
cmp    $0x7,%r14d
jge    23bb <check_features+0x23b>
jmp    247c <check_features+0x2fc>
mov    0x2e24(%rip),%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x800000,%ebx
je     21a3 <check_features+0x23>
mov    0x2e08(%rip),%edi
shr    %edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x2000000,%ebx
je     21af <check_features+0x2f>
mov    0x2dea(%rip),%edi
shr    $0x3,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x4000000,%ebx
je     21bb <check_features+0x3b>
mov    0x2dcb(%rip),%edi
shr    $0x4,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x800000,%ebp
je     21c7 <check_features+0x47>
mov    0x2dac(%rip),%edi
shr    $0x2,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x2000000,%ebp
je     21d3 <check_features+0x53>
mov    0x2d8d(%rip),%edi
shr    $0x12,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x2,%bpl
je     21dd <check_features+0x5d>
mov    0x2d70(%rip),%edi
shr    $0x13,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x1,%bpl
je     21e7 <check_features+0x67>
mov    0x2d53(%rip),%edi
shr    $0x5,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x200,%ebp
je     21f3 <check_features+0x73>
mov    0x2d34(%rip),%edi
shr    $0x6,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x80000,%ebp
je     21ff <check_features+0x7f>
mov    0x2d15(%rip),%edi
shr    $0x7,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x100000,%ebp
je     220b <check_features+0x8b>
mov    0x2cf6(%rip),%edi
shr    $0x8,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x10000000,%ebp
je     2217 <check_features+0x97>
mov    0x2cd7(%rip),%edi
shr    $0x9,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x1000,%ebp
je     2223 <check_features+0xa3>
mov    0x2cb8(%rip),%edi
shr    $0xe,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
cmp    $0x7,%r14d
jl     247c <check_features+0x2fc>
xor    %ecx,%ecx
mov    $0x7,%eax
cpuid
mov    %ecx,%ebp
mov    %edx,%r14d
test   $0x8,%bl
jne    24b9 <check_features+0x339>
test   $0x20,%bl
jne    24d5 <check_features+0x355>
test   $0x100,%ebx
jne    24f4 <check_features+0x374>
test   $0x10000,%ebx
jne    2513 <check_features+0x393>
test   %ebx,%ebx
js     252e <check_features+0x3ae>
test   $0x40000000,%ebx
jne    254d <check_features+0x3cd>
test   $0x20000,%ebx
jne    256c <check_features+0x3ec>
test   $0x10000000,%ebx
jne    258b <check_features+0x40b>
test   $0x4000000,%ebx
jne    25aa <check_features+0x42a>
test   $0x8000000,%ebx
jne    25c9 <check_features+0x449>
test   $0x200000,%ebx
jne    25e8 <check_features+0x468>
test   $0x2,%bpl
jne    2605 <check_features+0x485>
test   $0x4000,%ebp
jne    2624 <check_features+0x4a4>
test   $0x4,%r14b
jne    2641 <check_features+0x4c1>
test   $0x8,%r14b
je     247c <check_features+0x2fc>
mov    0x2bed(%rip),%edi
shr    $0x1d,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
mov    $0x80000000,%eax
cpuid
cmp    $0x80000001,%eax
jb     24b4 <check_features+0x334>
mov    $0x80000001,%eax
cpuid
mov    %ecx,%ebx
test   $0x40,%bl
jne    2663 <check_features+0x4e3>
test   $0x10000,%ebx
jne    2682 <check_features+0x502>
test   $0x800,%ebx
jne    26a1 <check_features+0x521>
pop    %rbx
pop    %r14
pop    %rbp
ret
mov    0x2b9d(%rip),%edi
shr    $0x10,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x20,%bl
je     23db <check_features+0x25b>
mov    0x2b81(%rip),%edi
shr    $0xa,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x100,%ebx
je     23e7 <check_features+0x267>
mov    0x2b62(%rip),%edi
shr    $0x11,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x10000,%ebx
je     23f3 <check_features+0x273>
mov    0x2b43(%rip),%edi
shr    $0xf,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   %ebx,%ebx
jns    23fb <check_features+0x27b>
mov    0x2b28(%rip),%edi
shr    $0x14,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x40000000,%ebx
je     2407 <check_features+0x287>
mov    0x2b09(%rip),%edi
shr    $0x15,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x20000,%ebx
je     2413 <check_features+0x293>
mov    0x2aea(%rip),%edi
shr    $0x16,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x10000000,%ebx
je     241f <check_features+0x29f>
mov    0x2acb(%rip),%edi
shr    $0x17,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x4000000,%ebx
je     242b <check_features+0x2ab>
mov    0x2aac(%rip),%edi
shr    $0x19,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x8000000,%ebx
je     2437 <check_features+0x2b7>
mov    0x2a8d(%rip),%edi
shr    $0x18,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x200000,%ebx
je     2443 <check_features+0x2c3>
mov    0x2a6e(%rip),%edi
shr    $0x1b,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x2,%bpl
je     244d <check_features+0x2cd>
mov    0x2a51(%rip),%edi
shr    $0x1a,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x4000,%ebp
je     2459 <check_features+0x2d9>
mov    0x2a32(%rip),%edi
shr    $0x1e,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x4,%r14b
je     2463 <check_features+0x2e3>
mov    0x2a15(%rip),%edi
shr    $0x1c,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x8,%r14b
jne    2469 <check_features+0x2e9>
jmp    247c <check_features+0x2fc>
mov    0x29f3(%rip),%edi
shr    $0xb,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x10000,%ebx
je     24a8 <check_features+0x328>
mov    0x29d4(%rip),%edi
shr    $0xc,%edi
and    $0x1,%edi
xor    %eax,%eax
call   1030 <assert@plt>
test   $0x800,%ebx
je     24b4 <check_features+0x334>
mov    0x29b5(%rip),%edi
shr    $0xd,%edi
and    $0x1,%edi
xor    %eax,%eax
pop    %rbx
pop    %r14
pop    %rbp
jmp    1030 <assert@plt>

LLVM IR (-O0):
@__cpu_model = external global { i32, i32, i32, [1 x i32] }
define void @check_features(i32 %0, i32 %1, i32 %2) {
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
store i32 %0, i32* %4
store i32 %1, i32* %5
store i32 %2, i32* %6
%10 = load i32, i32* %5
%11 = and i32 %10, 32768
%12 = icmp ne i32 %11, 0
br i1 %12, label %13, label %20
13: ; preds = %3
%14 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%15 = and i32 %14, 1
%16 = icmp eq i32 %15, 1
%17 = and i1 true, %16
%18 = zext i1 %17 to i32
%19 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %18)
br label %20
20: ; preds = %13, %3
%21 = load i32, i32* %5
%22 = and i32 %21, 8388608
%23 = icmp ne i32 %22, 0
br i1 %23, label %24, label %31
24: ; preds = %20
%25 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%26 = and i32 %25, 2
%27 = icmp eq i32 %26, 2
%28 = and i1 true, %27
%29 = zext i1 %28 to i32
%30 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %29)
br label %31
31: ; preds = %24, %20
%32 = load i32, i32* %5
%33 = and i32 %32, 33554432
%34 = icmp ne i32 %33, 0
br i1 %34, label %35, label %42
35: ; preds = %31
%36 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%37 = and i32 %36, 8
%38 = icmp eq i32 %37, 8
%39 = and i1 true, %38
%40 = zext i1 %39 to i32
%41 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %40)
br label %42
42: ; preds = %35, %31
%43 = load i32, i32* %5
%44 = and i32 %43, 67108864
%45 = icmp ne i32 %44, 0
br i1 %45, label %46, label %53
46: ; preds = %42
%47 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%48 = and i32 %47, 16
%49 = icmp eq i32 %48, 16
%50 = and i1 true, %49
%51 = zext i1 %50 to i32
%52 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %51)
br label %53
53: ; preds = %46, %42
%54 = load i32, i32* %4
%55 = and i32 %54, 8388608
%56 = icmp ne i32 %55, 0
br i1 %56, label %57, label %64
57: ; preds = %53
%58 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%59 = and i32 %58, 4
%60 = icmp eq i32 %59, 4
%61 = and i1 true, %60
%62 = zext i1 %61 to i32
%63 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %62)
br label %64
64: ; preds = %57, %53
%65 = load i32, i32* %4
%66 = and i32 %65, 33554432
%67 = icmp ne i32 %66, 0
br i1 %67, label %68, label %75
68: ; preds = %64
%69 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%70 = and i32 %69, 262144
%71 = icmp eq i32 %70, 262144
%72 = and i1 true, %71
%73 = zext i1 %72 to i32
%74 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %73)
br label %75
75: ; preds = %68, %64
%76 = load i32, i32* %4
%77 = and i32 %76, 2
%78 = icmp ne i32 %77, 0
br i1 %78, label %79, label %86
79: ; preds = %75
%80 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%81 = and i32 %80, 524288
%82 = icmp eq i32 %81, 524288
%83 = and i1 true, %82
%84 = zext i1 %83 to i32
%85 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %84)
br label %86
86: ; preds = %79, %75
%87 = load i32, i32* %4
%88 = and i32 %87, 1
%89 = icmp ne i32 %88, 0
br i1 %89, label %90, label %97
90: ; preds = %86
%91 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%92 = and i32 %91, 32
%93 = icmp eq i32 %92, 32
%94 = and i1 true, %93
%95 = zext i1 %94 to i32
%96 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %95)
br label %97
97: ; preds = %90, %86
%98 = load i32, i32* %4
%99 = and i32 %98, 512
%100 = icmp ne i32 %99, 0
br i1 %100, label %101, label %108
101: ; preds = %97
%102 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%103 = and i32 %102, 64
%104 = icmp eq i32 %103, 64
%105 = and i1 true, %104
%106 = zext i1 %105 to i32
%107 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %106)
br label %108
108: ; preds = %101, %97
%109 = load i32, i32* %4
%110 = and i32 %109, 524288
%111 = icmp ne i32 %110, 0
br i1 %111, label %112, label %119
112: ; preds = %108
%113 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%114 = and i32 %113, 128
%115 = icmp eq i32 %114, 128
%116 = and i1 true, %115
%117 = zext i1 %116 to i32
%118 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %117)
br label %119
119: ; preds = %112, %108
%120 = load i32, i32* %4
%121 = and i32 %120, 1048576
%122 = icmp ne i32 %121, 0
br i1 %122, label %123, label %130
123: ; preds = %119
%124 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%125 = and i32 %124, 256
%126 = icmp eq i32 %125, 256
%127 = and i1 true, %126
%128 = zext i1 %127 to i32
%129 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %128)
br label %130
130: ; preds = %123, %119
%131 = load i32, i32* %4
%132 = and i32 %131, 268435456
%133 = icmp ne i32 %132, 0
br i1 %133, label %134, label %141
134: ; preds = %130
%135 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%136 = and i32 %135, 512
%137 = icmp eq i32 %136, 512
%138 = and i1 true, %137
%139 = zext i1 %138 to i32
%140 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %139)
br label %141
141: ; preds = %134, %130
%142 = load i32, i32* %4
%143 = and i32 %142, 4096
%144 = icmp ne i32 %143, 0
br i1 %144, label %145, label %152
145: ; preds = %141
%146 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%147 = and i32 %146, 16384
%148 = icmp eq i32 %147, 16384
%149 = and i1 true, %148
%150 = zext i1 %149 to i32
%151 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %150)
br label %152
152: ; preds = %145, %141
%153 = load i32, i32* %6
%154 = icmp sge i32 %153, 7
br i1 %154, label %155, label %326
155: ; preds = %152
%156 = call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 7, i32 0)
%157 = extractvalue { i32, i32, i32, i32 } %156, 0
%158 = extractvalue { i32, i32, i32, i32 } %156, 1
%159 = extractvalue { i32, i32, i32, i32 } %156, 2
%160 = extractvalue { i32, i32, i32, i32 } %156, 3
store i32 %157, i32* %7
store i32 %158, i32* %8
store i32 %159, i32* %4
store i32 %160, i32* %5
%161 = load i32, i32* %8
%162 = and i32 %161, 8
%163 = icmp ne i32 %162, 0
br i1 %163, label %164, label %171
164: ; preds = %155
%165 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%166 = and i32 %165, 65536
%167 = icmp eq i32 %166, 65536
%168 = and i1 true, %167
%169 = zext i1 %168 to i32
%170 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %169)
br label %171
171: ; preds = %164, %155
%172 = load i32, i32* %8
%173 = and i32 %172, 32
%174 = icmp ne i32 %173, 0
br i1 %174, label %175, label %182
175: ; preds = %171
%176 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%177 = and i32 %176, 1024
%178 = icmp eq i32 %177, 1024
%179 = and i1 true, %178
%180 = zext i1 %179 to i32
%181 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %180)
br label %182
182: ; preds = %175, %171
%183 = load i32, i32* %8
%184 = and i32 %183, 256
%185 = icmp ne i32 %184, 0
br i1 %185, label %186, label %193
186: ; preds = %182
%187 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%188 = and i32 %187, 131072
%189 = icmp eq i32 %188, 131072
%190 = and i1 true, %189
%191 = zext i1 %190 to i32
%192 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %191)
br label %193
193: ; preds = %186, %182
%194 = load i32, i32* %8
%195 = and i32 %194, 65536
%196 = icmp ne i32 %195, 0
br i1 %196, label %197, label %204
197: ; preds = %193
%198 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%199 = and i32 %198, 32768
%200 = icmp eq i32 %199, 32768
%201 = and i1 true, %200
%202 = zext i1 %201 to i32
%203 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %202)
br label %204
204: ; preds = %197, %193
%205 = load i32, i32* %8
%206 = and i32 %205, -2147483648
%207 = icmp ne i32 %206, 0
br i1 %207, label %208, label %215
208: ; preds = %204
%209 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%210 = and i32 %209, 1048576
%211 = icmp eq i32 %210, 1048576
%212 = and i1 true, %211
%213 = zext i1 %212 to i32
%214 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %213)
br label %215
215: ; preds = %208, %204
%216 = load i32, i32* %8
%217 = and i32 %216, 1073741824
%218 = icmp ne i32 %217, 0
br i1 %218, label %219, label %226
219: ; preds = %215
%220 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%221 = and i32 %220, 2097152
%222 = icmp eq i32 %221, 2097152
%223 = and i1 true, %222
%224 = zext i1 %223 to i32
%225 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %224)
br label %226
226: ; preds = %219, %215
%227 = load i32, i32* %8
%228 = and i32 %227, 131072
%229 = icmp ne i32 %228, 0
br i1 %229, label %230, label %237
230: ; preds = %226
%231 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%232 = and i32 %231, 4194304
%233 = icmp eq i32 %232, 4194304
%234 = and i1 true, %233
%235 = zext i1 %234 to i32
%236 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %235)
br label %237
237: ; preds = %230, %226
%238 = load i32, i32* %8
%239 = and i32 %238, 268435456
%240 = icmp ne i32 %239, 0
br i1 %240, label %241, label %248
241: ; preds = %237
%242 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%243 = and i32 %242, 8388608
%244 = icmp eq i32 %243, 8388608
%245 = and i1 true, %244
%246 = zext i1 %245 to i32
%247 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %246)
br label %248
248: ; preds = %241, %237
%249 = load i32, i32* %8
%250 = and i32 %249, 67108864
%251 = icmp ne i32 %250, 0
br i1 %251, label %252, label %259
252: ; preds = %248
%253 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%254 = and i32 %253, 33554432
%255 = icmp eq i32 %254, 33554432
%256 = and i1 true, %255
%257 = zext i1 %256 to i32
%258 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %257)
br label %259
259: ; preds = %252, %248
%260 = load i32, i32* %8
%261 = and i32 %260, 134217728
%262 = icmp ne i32 %261, 0
br i1 %262, label %263, label %270
263: ; preds = %259
%264 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%265 = and i32 %264, 16777216
%266 = icmp eq i32 %265, 16777216
%267 = and i1 true, %266
%268 = zext i1 %267 to i32
%269 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %268)
br label %270
270: ; preds = %263, %259
%271 = load i32, i32* %8
%272 = and i32 %271, 2097152
%273 = icmp ne i32 %272, 0
br i1 %273, label %274, label %281
274: ; preds = %270
%275 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%276 = and i32 %275, 134217728
%277 = icmp eq i32 %276, 134217728
%278 = and i1 true, %277
%279 = zext i1 %278 to i32
%280 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %279)
br label %281
281: ; preds = %274, %270
%282 = load i32, i32* %4
%283 = and i32 %282, 2
%284 = icmp ne i32 %283, 0
br i1 %284, label %285, label %292
285: ; preds = %281
%286 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%287 = and i32 %286, 67108864
%288 = icmp eq i32 %287, 67108864
%289 = and i1 true, %288
%290 = zext i1 %289 to i32
%291 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %290)
br label %292
292: ; preds = %285, %281
%293 = load i32, i32* %4
%294 = and i32 %293, 16384
%295 = icmp ne i32 %294, 0
br i1 %295, label %296, label %303
296: ; preds = %292
%297 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%298 = and i32 %297, 1073741824
%299 = icmp eq i32 %298, 1073741824
%300 = and i1 true, %299
%301 = zext i1 %300 to i32
%302 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %301)
br label %303
303: ; preds = %296, %292
%304 = load i32, i32* %5
%305 = and i32 %304, 4
%306 = icmp ne i32 %305, 0
br i1 %306, label %307, label %314
307: ; preds = %303
%308 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%309 = and i32 %308, 268435456
%310 = icmp eq i32 %309, 268435456
%311 = and i1 true, %310
%312 = zext i1 %311 to i32
%313 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %312)
br label %314
314: ; preds = %307, %303
%315 = load i32, i32* %5
%316 = and i32 %315, 8
%317 = icmp ne i32 %316, 0
br i1 %317, label %318, label %325
318: ; preds = %314
%319 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%320 = and i32 %319, 536870912
%321 = icmp eq i32 %320, 536870912
%322 = and i1 true, %321
%323 = zext i1 %322 to i32
%324 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %323)
br label %325
325: ; preds = %318, %314
br label %326
326: ; preds = %325, %152
%327 = call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 -2147483648)
%328 = extractvalue { i32, i32, i32, i32 } %327, 0
%329 = extractvalue { i32, i32, i32, i32 } %327, 1
%330 = extractvalue { i32, i32, i32, i32 } %327, 2
%331 = extractvalue { i32, i32, i32, i32 } %327, 3
store i32 %328, i32* %9
store i32 %329, i32* %8
store i32 %330, i32* %4
store i32 %331, i32* %5
%332 = load i32, i32* %9
%333 = icmp uge i32 %332, -2147483647
br i1 %333, label %334, label %373
334: ; preds = %326
%335 = call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 -2147483647)
%336 = extractvalue { i32, i32, i32, i32 } %335, 0
%337 = extractvalue { i32, i32, i32, i32 } %335, 1
%338 = extractvalue { i32, i32, i32, i32 } %335, 2
%339 = extractvalue { i32, i32, i32, i32 } %335, 3
store i32 %336, i32* %7
store i32 %337, i32* %8
store i32 %338, i32* %4
store i32 %339, i32* %5
%340 = load i32, i32* %4
%341 = and i32 %340, 64
%342 = icmp ne i32 %341, 0
br i1 %342, label %343, label %350
343: ; preds = %334
%344 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%345 = and i32 %344, 2048
%346 = icmp eq i32 %345, 2048
%347 = and i1 true, %346
%348 = zext i1 %347 to i32
%349 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %348)
br label %350
350: ; preds = %343, %334
%351 = load i32, i32* %4
%352 = and i32 %351, 65536
%353 = icmp ne i32 %352, 0
br i1 %353, label %354, label %361
354: ; preds = %350
%355 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%356 = and i32 %355, 4096
%357 = icmp eq i32 %356, 4096
%358 = and i1 true, %357
%359 = zext i1 %358 to i32
%360 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %359)
br label %361
361: ; preds = %354, %350
%362 = load i32, i32* %4
%363 = and i32 %362, 2048
%364 = icmp ne i32 %363, 0
br i1 %364, label %365, label %372
365: ; preds = %361
%366 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i32 0, i32 3, i32 0)
%367 = and i32 %366, 8192
%368 = icmp eq i32 %367, 8192
%369 = and i1 true, %368
%370 = zext i1 %369 to i32
%371 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %370)
br label %372
372: ; preds = %365, %361
br label %373
373: ; preds = %372, %326
ret void
}

LLVM IR (-O2):
@__cpu_model = external global { i32, i32, i32, [1 x i32] }
define void @check_features(i32 %0, i32 %1, i32 %2) {
%4 = and i32 %1, 32768
%5 = icmp eq i32 %4, 0
br i1 %5, label %10, label %6
6: ; preds = %3
%7 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%8 = and i32 %7, 1
%9 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %8)
br label %10
10: ; preds = %6, %3
%11 = and i32 %1, 8388608
%12 = icmp eq i32 %11, 0
br i1 %12, label %18, label %13
13: ; preds = %10
%14 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%15 = lshr i32 %14, 1
%16 = and i32 %15, 1
%17 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %16)
br label %18
18: ; preds = %13, %10
%19 = and i32 %1, 33554432
%20 = icmp eq i32 %19, 0
br i1 %20, label %26, label %21
21: ; preds = %18
%22 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%23 = lshr i32 %22, 3
%24 = and i32 %23, 1
%25 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %24)
br label %26
26: ; preds = %21, %18
%27 = and i32 %1, 67108864
%28 = icmp eq i32 %27, 0
br i1 %28, label %34, label %29
29: ; preds = %26
%30 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%31 = lshr i32 %30, 4
%32 = and i32 %31, 1
%33 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %32)
br label %34
34: ; preds = %29, %26
%35 = and i32 %0, 8388608
%36 = icmp eq i32 %35, 0
br i1 %36, label %42, label %37
37: ; preds = %34
%38 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%39 = lshr i32 %38, 2
%40 = and i32 %39, 1
%41 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %40)
br label %42
42: ; preds = %37, %34
%43 = and i32 %0, 33554432
%44 = icmp eq i32 %43, 0
br i1 %44, label %50, label %45
45: ; preds = %42
%46 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%47 = lshr i32 %46, 18
%48 = and i32 %47, 1
%49 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %48)
br label %50
50: ; preds = %45, %42
%51 = and i32 %0, 2
%52 = icmp eq i32 %51, 0
br i1 %52, label %58, label %53
53: ; preds = %50
%54 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%55 = lshr i32 %54, 19
%56 = and i32 %55, 1
%57 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %56)
br label %58
58: ; preds = %53, %50
%59 = and i32 %0, 1
%60 = icmp eq i32 %59, 0
br i1 %60, label %66, label %61
61: ; preds = %58
%62 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%63 = lshr i32 %62, 5
%64 = and i32 %63, 1
%65 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %64)
br label %66
66: ; preds = %61, %58
%67 = and i32 %0, 512
%68 = icmp eq i32 %67, 0
br i1 %68, label %74, label %69
69: ; preds = %66
%70 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%71 = lshr i32 %70, 6
%72 = and i32 %71, 1
%73 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %72)
br label %74
74: ; preds = %69, %66
%75 = and i32 %0, 524288
%76 = icmp eq i32 %75, 0
br i1 %76, label %82, label %77
77: ; preds = %74
%78 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%79 = lshr i32 %78, 7
%80 = and i32 %79, 1
%81 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %80)
br label %82
82: ; preds = %77, %74
%83 = and i32 %0, 1048576
%84 = icmp eq i32 %83, 0
br i1 %84, label %90, label %85
85: ; preds = %82
%86 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%87 = lshr i32 %86, 8
%88 = and i32 %87, 1
%89 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %88)
br label %90
90: ; preds = %85, %82
%91 = and i32 %0, 268435456
%92 = icmp eq i32 %91, 0
br i1 %92, label %98, label %93
93: ; preds = %90
%94 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%95 = lshr i32 %94, 9
%96 = and i32 %95, 1
%97 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %96)
br label %98
98: ; preds = %93, %90
%99 = and i32 %0, 4096
%100 = icmp eq i32 %99, 0
br i1 %100, label %106, label %101
101: ; preds = %98
%102 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%103 = lshr i32 %102, 14
%104 = and i32 %103, 1
%105 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %104)
br label %106
106: ; preds = %101, %98
%107 = icmp sgt i32 %2, 6
br i1 %107, label %108, label %231
108: ; preds = %106
%109 = tail call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 7, i32 0)
%110 = extractvalue { i32, i32, i32, i32 } %109, 1
%111 = extractvalue { i32, i32, i32, i32 } %109, 2
%112 = extractvalue { i32, i32, i32, i32 } %109, 3
%113 = and i32 %110, 8
%114 = icmp eq i32 %113, 0
br i1 %114, label %120, label %115
115: ; preds = %108
%116 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%117 = lshr i32 %116, 16
%118 = and i32 %117, 1
%119 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %118)
br label %120
120: ; preds = %115, %108
%121 = and i32 %110, 32
%122 = icmp eq i32 %121, 0
br i1 %122, label %128, label %123
123: ; preds = %120
%124 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%125 = lshr i32 %124, 10
%126 = and i32 %125, 1
%127 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %126)
br label %128
128: ; preds = %123, %120
%129 = and i32 %110, 256
%130 = icmp eq i32 %129, 0
br i1 %130, label %136, label %131
131: ; preds = %128
%132 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%133 = lshr i32 %132, 17
%134 = and i32 %133, 1
%135 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %134)
br label %136
136: ; preds = %131, %128
%137 = and i32 %110, 65536
%138 = icmp eq i32 %137, 0
br i1 %138, label %144, label %139
139: ; preds = %136
%140 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%141 = lshr i32 %140, 15
%142 = and i32 %141, 1
%143 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %142)
br label %144
144: ; preds = %139, %136
%145 = icmp sgt i32 %110, -1
br i1 %145, label %151, label %146
146: ; preds = %144
%147 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%148 = lshr i32 %147, 20
%149 = and i32 %148, 1
%150 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %149)
br label %151
151: ; preds = %146, %144
%152 = and i32 %110, 1073741824
%153 = icmp eq i32 %152, 0
br i1 %153, label %159, label %154
154: ; preds = %151
%155 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%156 = lshr i32 %155, 21
%157 = and i32 %156, 1
%158 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %157)
br label %159
159: ; preds = %154, %151
%160 = and i32 %110, 131072
%161 = icmp eq i32 %160, 0
br i1 %161, label %167, label %162
162: ; preds = %159
%163 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%164 = lshr i32 %163, 22
%165 = and i32 %164, 1
%166 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %165)
br label %167
167: ; preds = %162, %159
%168 = and i32 %110, 268435456
%169 = icmp eq i32 %168, 0
br i1 %169, label %175, label %170
170: ; preds = %167
%171 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%172 = lshr i32 %171, 23
%173 = and i32 %172, 1
%174 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %173)
br label %175
175: ; preds = %170, %167
%176 = and i32 %110, 67108864
%177 = icmp eq i32 %176, 0
br i1 %177, label %183, label %178
178: ; preds = %175
%179 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%180 = lshr i32 %179, 25
%181 = and i32 %180, 1
%182 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %181)
br label %183
183: ; preds = %178, %175
%184 = and i32 %110, 134217728
%185 = icmp eq i32 %184, 0
br i1 %185, label %191, label %186
186: ; preds = %183
%187 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%188 = lshr i32 %187, 24
%189 = and i32 %188, 1
%190 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %189)
br label %191
191: ; preds = %186, %183
%192 = and i32 %110, 2097152
%193 = icmp eq i32 %192, 0
br i1 %193, label %199, label %194
194: ; preds = %191
%195 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%196 = lshr i32 %195, 27
%197 = and i32 %196, 1
%198 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %197)
br label %199
199: ; preds = %194, %191
%200 = and i32 %111, 2
%201 = icmp eq i32 %200, 0
br i1 %201, label %207, label %202
202: ; preds = %199
%203 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%204 = lshr i32 %203, 26
%205 = and i32 %204, 1
%206 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %205)
br label %207
207: ; preds = %202, %199
%208 = and i32 %111, 16384
%209 = icmp eq i32 %208, 0
br i1 %209, label %215, label %210
210: ; preds = %207
%211 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%212 = lshr i32 %211, 30
%213 = and i32 %212, 1
%214 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %213)
br label %215
215: ; preds = %210, %207
%216 = and i32 %112, 4
%217 = icmp eq i32 %216, 0
br i1 %217, label %223, label %218
218: ; preds = %215
%219 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%220 = lshr i32 %219, 28
%221 = and i32 %220, 1
%222 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %221)
br label %223
223: ; preds = %218, %215
%224 = and i32 %112, 8
%225 = icmp eq i32 %224, 0
br i1 %225, label %231, label %226
226: ; preds = %223
%227 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%228 = lshr i32 %227, 29
%229 = and i32 %228, 1
%230 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %229)
br label %231
231: ; preds = %223, %226, %106
%232 = tail call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 -2147483648)
%233 = extractvalue { i32, i32, i32, i32 } %232, 0
%234 = icmp ugt i32 %233, -2147483648
br i1 %234, label %235, label %261
235: ; preds = %231
%236 = tail call { i32, i32, i32, i32 } asm "cpuid\0A\09", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 -2147483647)
%237 = extractvalue { i32, i32, i32, i32 } %236, 2
%238 = and i32 %237, 64
%239 = icmp eq i32 %238, 0
br i1 %239, label %245, label %240
240: ; preds = %235
%241 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%242 = lshr i32 %241, 11
%243 = and i32 %242, 1
%244 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %243)
br label %245
245: ; preds = %240, %235
%246 = and i32 %237, 65536
%247 = icmp eq i32 %246, 0
br i1 %247, label %253, label %248
248: ; preds = %245
%249 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%250 = lshr i32 %249, 12
%251 = and i32 %250, 1
%252 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %251)
br label %253
253: ; preds = %248, %245
%254 = and i32 %237, 2048
%255 = icmp eq i32 %254, 0
br i1 %255, label %261, label %256
256: ; preds = %253
%257 = load i32, i32* getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, { i32, i32, i32, [1 x i32] }* @__cpu_model, i64 0, i32 3, i64 0)
%258 = lshr i32 %257, 13
%259 = and i32 %258, 1
%260 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %259)
br label %261
261: ; preds = %253, %256, %231
ret void
}