int fn(float p) {
  int e = 0;
  p = p + 0.5;
  if (p >= 0) {
    e = 0;
    while (e < p)
      e++;
    return e;
  } else {
    e = 0;
    while (e > p)
      e--;
    return e;
  }
}


x86 assembly (clang, -O0):
<fn>:
push   %rbp
mov    %rsp,%rbp
movss  %xmm0,-0x8(%rbp)
movl   $0x0,-0xc(%rbp)
movss  -0x8(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xedf(%rip),%xmm1
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x8(%rbp)
movss  -0x8(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jb     1172 <fn+0x72>
movl   $0x0,-0xc(%rbp)
cvtsi2ssl -0xc(%rbp),%xmm1
movss  -0x8(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    1167 <fn+0x67>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1146 <fn+0x46>
mov    -0xc(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    119c <fn+0x9c>
movl   $0x0,-0xc(%rbp)
cvtsi2ssl -0xc(%rbp),%xmm0
ucomiss -0x8(%rbp),%xmm0
jbe    1196 <fn+0x96>
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
jmp    1179 <fn+0x79>
mov    -0xc(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<fn>:
addss  0xef8(%rip),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jae    1131 <fn+0x31>
mov    $0x1,%eax
cs nopw 0x0(%rax,%rax,1)
nop
add    $0xffffffff,%eax
xorps  %xmm1,%xmm1
cvtsi2ss %eax,%xmm1
ucomiss %xmm0,%xmm1
ja     1120 <fn+0x20>
jmp    114f <fn+0x4f>
mov    $0xffffffff,%eax
cs nopw 0x0(%rax,%rax,1)
add    $0x1,%eax
xorps  %xmm1,%xmm1
cvtsi2ss %eax,%xmm1
ucomiss %xmm1,%xmm0
ja     1140 <fn+0x40>
ret

LLVM IR (-O0):
define i32 @fn(float %0) {
%2 = alloca i32
%3 = alloca float
%4 = alloca i32
store float %0, float* %3
store i32 0, i32* %4
%5 = load float, float* %3
%6 = fpext float %5 to double
%7 = fadd double %6, 5.000000e-01
%8 = fptrunc double %7 to float
store float %8, float* %3
%9 = load float, float* %3
%10 = fcmp oge float %9, 0.000000e+00
br i1 %10, label %11, label %22
11: ; preds = %1
store i32 0, i32* %4
br label %12
12: ; preds = %17, %11
%13 = load i32, i32* %4
%14 = sitofp i32 %13 to float
%15 = load float, float* %3
%16 = fcmp olt float %14, %15
br i1 %16, label %17, label %20
17: ; preds = %12
%18 = load i32, i32* %4
%19 = add nsw i32 %18, 1
store i32 %19, i32* %4
br label %12
20: ; preds = %12
%21 = load i32, i32* %4
store i32 %21, i32* %2
br label %33
22: ; preds = %1
store i32 0, i32* %4
br label %23
23: ; preds = %28, %22
%24 = load i32, i32* %4
%25 = sitofp i32 %24 to float
%26 = load float, float* %3
%27 = fcmp ogt float %25, %26
br i1 %27, label %28, label %31
28: ; preds = %23
%29 = load i32, i32* %4
%30 = add nsw i32 %29, -1
store i32 %30, i32* %4
br label %23
31: ; preds = %23
%32 = load i32, i32* %4
store i32 %32, i32* %2
br label %33
33: ; preds = %31, %20
%34 = load i32, i32* %2
ret i32 %34
}

LLVM IR (-O2):
define i32 @fn(float %0) {
%2 = fadd float %0, 5.000000e-01
%3 = fcmp ult float %2, 0.000000e+00
br i1 %3, label %9, label %4
4: ; preds = %1, %4
%5 = phi i32 [ %8, %4 ], [ 0, %1 ]
%6 = sitofp i32 %5 to float
%7 = fcmp ogt float %2, %6
%8 = add nuw nsw i32 %5, 1
br i1 %7, label %4, label %14
9: ; preds = %1, %9
%10 = phi i32 [ %13, %9 ], [ 0, %1 ]
%11 = sitofp i32 %10 to float
%12 = fcmp olt float %2, %11
%13 = add nsw i32 %10, -1
br i1 %12, label %9, label %14
14: ; preds = %4, %9
%15 = phi i32 [ %10, %9 ], [ %5, %4 ]
ret i32 %15
}