unsigned fp_regs_check(unsigned val) {
  unsigned i, result = val;
  unsigned e[8];
  for (i = 0; i < 8; i++)
    __asm__ __volatile__("fistpl %0" : "=m"(e[7 - i]));
  for (i = 0; i < 8; i++)
    if (e[i] != val) {
      printf("r%d: %u != %u\n", i, e[i], val);
      result = e[i];
    }
  return result;
}


x86 assembly (clang, -O0):
<fp_regs_check>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %edi,-0x4(%rbp)
mov    -0x4(%rbp),%eax
mov    %eax,-0xc(%rbp)
movl   $0x0,-0x8(%rbp)
cmpl   $0x8,-0x8(%rbp)
jae    1159 <fp_regs_check+0x49>
mov    $0x7,%eax
sub    -0x8(%rbp),%eax
mov    %eax,%eax
mov    %eax,%ecx
lea    -0x30(%rbp),%rax
shl    $0x2,%rcx
add    %rcx,%rax
fistpl (%rax)
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1128 <fp_regs_check+0x18>
movl   $0x0,-0x8(%rbp)
cmpl   $0x8,-0x8(%rbp)
jae    11b2 <fp_regs_check+0xa2>
mov    -0x8(%rbp),%eax
mov    -0x30(%rbp,%rax,4),%eax
cmp    -0x4(%rbp),%eax
je     119f <fp_regs_check+0x8f>
mov    -0x8(%rbp),%esi
mov    -0x8(%rbp),%eax
mov    -0x30(%rbp,%rax,4),%edx
mov    -0x4(%rbp),%ecx
lea    0xe72(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x8(%rbp),%eax
mov    -0x30(%rbp,%rax,4),%eax
mov    %eax,-0xc(%rbp)
jmp    11a4 <fp_regs_check+0x94>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1160 <fp_regs_check+0x50>
mov    -0xc(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fp_regs_check>:
push   %rbx
sub    $0x20,%rsp
mov    %edi,%ebx
fistpl 0x1c(%rsp)
fistpl 0x18(%rsp)
fistpl 0x14(%rsp)
fistpl 0x10(%rsp)
fistpl 0xc(%rsp)
fistpl 0x8(%rsp)
fistpl 0x4(%rsp)
fistpl (%rsp)
mov    (%rsp),%edx
mov    %edi,%eax
cmp    %edi,%edx
je     1154 <fp_regs_check+0x44>
lea    0xeba(%rip),%rdi
xor    %esi,%esi
mov    %ebx,%ecx
xor    %eax,%eax
call   1030 <printf@plt>
mov    (%rsp),%eax
mov    0x4(%rsp),%edx
cmp    %ebx,%edx
je     1175 <fp_regs_check+0x65>
lea    0xe9d(%rip),%rdi
mov    $0x1,%esi
mov    %ebx,%ecx
xor    %eax,%eax
call   1030 <printf@plt>
mov    0x4(%rsp),%eax
mov    0x8(%rsp),%edx
cmp    %ebx,%edx
je     1196 <fp_regs_check+0x86>
lea    0xe7c(%rip),%rdi
mov    $0x2,%esi
mov    %ebx,%ecx
xor    %eax,%eax
call   1030 <printf@plt>
mov    0x8(%rsp),%eax
mov    0xc(%rsp),%edx
cmp    %ebx,%edx
je     11b7 <fp_regs_check+0xa7>
lea    0xe5b(%rip),%rdi
mov    $0x3,%esi
mov    %ebx,%ecx
xor    %eax,%eax
call   1030 <printf@plt>
mov    0xc(%rsp),%eax
mov    0x10(%rsp),%edx
cmp    %ebx,%edx
je     11d8 <fp_regs_check+0xc8>
lea    0xe3a(%rip),%rdi
mov    $0x4,%esi
mov    %ebx,%ecx
xor    %eax,%eax
call   1030 <printf@plt>
mov    0x10(%rsp),%eax
mov    0x14(%rsp),%edx
cmp    %ebx,%edx
je     11f9 <fp_regs_check+0xe9>
lea    0xe19(%rip),%rdi
mov    $0x5,%esi
mov    %ebx,%ecx
xor    %eax,%eax
call   1030 <printf@plt>
mov    0x14(%rsp),%eax
mov    0x18(%rsp),%edx
cmp    %ebx,%edx
je     121a <fp_regs_check+0x10a>
lea    0xdf8(%rip),%rdi
mov    $0x6,%esi
mov    %ebx,%ecx
xor    %eax,%eax
call   1030 <printf@plt>
mov    0x18(%rsp),%eax
mov    0x1c(%rsp),%edx
cmp    %ebx,%edx
je     123b <fp_regs_check+0x12b>
lea    0xdd7(%rip),%rdi
mov    $0x7,%esi
mov    %ebx,%ecx
xor    %eax,%eax
call   1030 <printf@plt>
mov    0x1c(%rsp),%eax
add    $0x20,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@.str = [15 x i8] c"r%d: %u != %u\0A\00"
define i32 @fp_regs_check(i32 %0) {
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32
%5 = alloca [8 x i32]
store i32 %0, i32* %2
%6 = load i32, i32* %2
store i32 %6, i32* %4
store i32 0, i32* %3
br label %7
7: ; preds = %15, %1
%8 = load i32, i32* %3
%9 = icmp ult i32 %8, 8
br i1 %9, label %10, label %18
10: ; preds = %7
%11 = load i32, i32* %3
%12 = sub i32 7, %11
%13 = zext i32 %12 to i64
%14 = getelementptr inbounds [8 x i32], [8 x i32]* %5, i64 0, i64 %13
br label %15
15: ; preds = %10
%16 = load i32, i32* %3
%17 = add i32 %16, 1
store i32 %17, i32* %3
br label %7
18: ; preds = %7
store i32 0, i32* %3
br label %19
19: ; preds = %42, %18
%20 = load i32, i32* %3
%21 = icmp ult i32 %20, 8
br i1 %21, label %22, label %45
22: ; preds = %19
%23 = load i32, i32* %3
%24 = zext i32 %23 to i64
%25 = getelementptr inbounds [8 x i32], [8 x i32]* %5, i64 0, i64 %24
%26 = load i32, i32* %25
%27 = load i32, i32* %2
%28 = icmp ne i32 %26, %27
br i1 %28, label %29, label %41
29: ; preds = %22
%30 = load i32, i32* %3
%31 = load i32, i32* %3
%32 = zext i32 %31 to i64
%33 = getelementptr inbounds [8 x i32], [8 x i32]* %5, i64 0, i64 %32
%34 = load i32, i32* %33
%35 = load i32, i32* %2
%36 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0), i32 %30, i32 %34, i32 %35)
%37 = load i32, i32* %3
%38 = zext i32 %37 to i64
%39 = getelementptr inbounds [8 x i32], [8 x i32]* %5, i64 0, i64 %38
%40 = load i32, i32* %39
store i32 %40, i32* %4
br label %41
41: ; preds = %29, %22
br label %42
42: ; preds = %41
%43 = load i32, i32* %3
%44 = add i32 %43, 1
store i32 %44, i32* %3
br label %19
45: ; preds = %19
%46 = load i32, i32* %4
ret i32 %46
}

LLVM IR (-O2):
@.str = [15 x i8] c"r%d: %u != %u\0A\00"
define i32 @fp_regs_check(i32 %0) {
%2 = alloca [8 x i32]
%3 = bitcast [8 x i32]* %2 to i8*
%4 = getelementptr inbounds [8 x i32], [8 x i32]* %2, i64 0, i64 7
%5 = getelementptr inbounds [8 x i32], [8 x i32]* %2, i64 0, i64 6
%6 = getelementptr inbounds [8 x i32], [8 x i32]* %2, i64 0, i64 5
%7 = getelementptr inbounds [8 x i32], [8 x i32]* %2, i64 0, i64 4
%8 = getelementptr inbounds [8 x i32], [8 x i32]* %2, i64 0, i64 3
%9 = getelementptr inbounds [8 x i32], [8 x i32]* %2, i64 0, i64 2
%10 = getelementptr inbounds [8 x i32], [8 x i32]* %2, i64 0, i64 1
%11 = getelementptr inbounds [8 x i32], [8 x i32]* %2, i64 0, i64 0
%12 = load i32, i32* %11
%13 = icmp eq i32 %12, %0
br i1 %13, label %17, label %14
14: ; preds = %1
%15 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0), i32 0, i32 %12, i32 %0)
%16 = load i32, i32* %11
br label %17
17: ; preds = %1, %14
%18 = phi i32 [ %16, %14 ], [ %0, %1 ]
%19 = load i32, i32* %10
%20 = icmp eq i32 %19, %0
br i1 %20, label %24, label %21
21: ; preds = %17
%22 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0), i32 1, i32 %19, i32 %0)
%23 = load i32, i32* %10
br label %24
24: ; preds = %21, %17
%25 = phi i32 [ %23, %21 ], [ %18, %17 ]
%26 = load i32, i32* %9
%27 = icmp eq i32 %26, %0
br i1 %27, label %31, label %28
28: ; preds = %24
%29 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0), i32 2, i32 %26, i32 %0)
%30 = load i32, i32* %9
br label %31
31: ; preds = %28, %24
%32 = phi i32 [ %30, %28 ], [ %25, %24 ]
%33 = load i32, i32* %8
%34 = icmp eq i32 %33, %0
br i1 %34, label %38, label %35
35: ; preds = %31
%36 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0), i32 3, i32 %33, i32 %0)
%37 = load i32, i32* %8
br label %38
38: ; preds = %35, %31
%39 = phi i32 [ %37, %35 ], [ %32, %31 ]
%40 = load i32, i32* %7
%41 = icmp eq i32 %40, %0
br i1 %41, label %45, label %42
42: ; preds = %38
%43 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0), i32 4, i32 %40, i32 %0)
%44 = load i32, i32* %7
br label %45
45: ; preds = %42, %38
%46 = phi i32 [ %44, %42 ], [ %39, %38 ]
%47 = load i32, i32* %6
%48 = icmp eq i32 %47, %0
br i1 %48, label %52, label %49
49: ; preds = %45
%50 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0), i32 5, i32 %47, i32 %0)
%51 = load i32, i32* %6
br label %52
52: ; preds = %49, %45
%53 = phi i32 [ %51, %49 ], [ %46, %45 ]
%54 = load i32, i32* %5
%55 = icmp eq i32 %54, %0
br i1 %55, label %59, label %56
56: ; preds = %52
%57 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0), i32 6, i32 %54, i32 %0)
%58 = load i32, i32* %5
br label %59
59: ; preds = %56, %52
%60 = phi i32 [ %58, %56 ], [ %53, %52 ]
%61 = load i32, i32* %4
%62 = icmp eq i32 %61, %0
br i1 %62, label %66, label %63
63: ; preds = %59
%64 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0), i32 7, i32 %61, i32 %0)
%65 = load i32, i32* %4
br label %66
66: ; preds = %63, %59
%67 = phi i32 [ %65, %63 ], [ %60, %59 ]
ret i32 %67
}