int test2(int i32) {
  struct foo {
    unsigned int u8 : 8;
    unsigned long long u31 : 31;
    unsigned long long u32 : 32;
    unsigned long long u63 : 63;
    unsigned long long u64 : 64;
  } * x;
  if (x->u8 == i32) {
    return 0;
  } else if (x->u31 == i32) {
    return 1;
  } else if (x->u32 == i32) {
    return 2;
  } else if (x->u63 == i32) {
    return 3;
  } else if (x->u64 == i32) {
    return 4;
  } else {
    return 5;
  }
}


x86 assembly (clang, -O0):
<test2>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x8(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
and    $0xff,%rax
cmp    -0x8(%rbp),%eax
jne    1129 <test2+0x29>
movl   $0x0,-0x4(%rbp)
jmp    11be <test2+0xbe>
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
shr    $0x8,%rax
and    $0x7fffffff,%rax
cmp    -0x8(%rbp),%eax
jne    114f <test2+0x4f>
movl   $0x1,-0x4(%rbp)
jmp    11be <test2+0xbe>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%eax
cmp    -0x8(%rbp),%eax
jne    116b <test2+0x6b>
movl   $0x2,-0x4(%rbp)
jmp    11be <test2+0xbe>
mov    -0x10(%rbp),%rcx
movabs $0x7fffffffffffffff,%rax
ff ff 7f
and    0x10(%rcx),%rax
movslq -0x8(%rbp),%rcx
cmp    %rcx,%rax
jne    1196 <test2+0x96>
movl   $0x3,-0x4(%rbp)
jmp    11be <test2+0xbe>
mov    -0x10(%rbp),%rax
mov    0x18(%rax),%rax
movslq -0x8(%rbp),%rcx
cmp    %rcx,%rax
jne    11b7 <test2+0xb7>
movl   $0x4,-0x4(%rbp)
jmp    11be <test2+0xbe>
movl   $0x5,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<test2>:
xor    %eax,%eax
test   %edi,%edi
setne  %al
lea    (%rax,%rax,4),%eax
ret

LLVM IR (-O0):
%struct.foo = type { i40, i32, i64, i64 }
define i32 @test2(i32 %0) {
%2 = alloca i32
%3 = alloca i32
%4 = alloca %struct.foo*
store i32 %0, i32* %3
%5 = load %struct.foo*, %struct.foo** %4
%6 = bitcast %struct.foo* %5 to i64*
%7 = load i64, i64* %6
%8 = and i64 %7, 255
%9 = trunc i64 %8 to i32
%10 = load i32, i32* %3
%11 = icmp eq i32 %9, %10
br i1 %11, label %12, label %13
12: ; preds = %1
store i32 0, i32* %2
br label %50
13: ; preds = %1
%14 = load %struct.foo*, %struct.foo** %4
%15 = bitcast %struct.foo* %14 to i64*
%16 = load i64, i64* %15
%17 = lshr i64 %16, 8
%18 = and i64 %17, 2147483647
%19 = trunc i64 %18 to i32
%20 = load i32, i32* %3
%21 = icmp eq i32 %19, %20
br i1 %21, label %22, label %23
22: ; preds = %13
store i32 1, i32* %2
br label %50
23: ; preds = %13
%24 = load %struct.foo*, %struct.foo** %4
%25 = getelementptr inbounds %struct.foo, %struct.foo* %24, i32 0, i32 1
%26 = load i32, i32* %25
%27 = zext i32 %26 to i64
%28 = trunc i64 %27 to i32
%29 = load i32, i32* %3
%30 = icmp eq i32 %28, %29
br i1 %30, label %31, label %32
31: ; preds = %23
store i32 2, i32* %2
br label %50
32: ; preds = %23
%33 = load %struct.foo*, %struct.foo** %4
%34 = getelementptr inbounds %struct.foo, %struct.foo* %33, i32 0, i32 2
%35 = load i64, i64* %34
%36 = and i64 %35, 9223372036854775807
%37 = load i32, i32* %3
%38 = sext i32 %37 to i64
%39 = icmp eq i64 %36, %38
br i1 %39, label %40, label %41
40: ; preds = %32
store i32 3, i32* %2
br label %50
41: ; preds = %32
%42 = load %struct.foo*, %struct.foo** %4
%43 = getelementptr inbounds %struct.foo, %struct.foo* %42, i32 0, i32 3
%44 = load i64, i64* %43
%45 = load i32, i32* %3
%46 = sext i32 %45 to i64
%47 = icmp eq i64 %44, %46
br i1 %47, label %48, label %49
48: ; preds = %41
store i32 4, i32* %2
br label %50
49: ; preds = %41
store i32 5, i32* %2
br label %50
50: ; preds = %49, %48, %40, %31, %22, %12
%51 = load i32, i32* %2
ret i32 %51
}

LLVM IR (-O2):
define i32 @test2(i32 %0) {
%2 = icmp eq i32 %0, 0
%3 = select i1 %2, i32 0, i32 5
ret i32 %3
}